|
|
  |
Компилятор С for PIC |
|
|
|
Dec 20 2007, 14:50
|

Местный
  
Группа: Свой
Сообщений: 206
Регистрация: 17-03-07
Из: Москва
Пользователь №: 26 266

|
Цитата(Сергей Борщ @ Dec 20 2007, 16:28)  ...объявить ногу в одном месте, и потом при необходимости в одном месте ее изменить - это гораздо удобнее и ошибкоустойчивее, чем во всем исходнике явно указывать порт и ногу. тогда в *.h файле просто запишите (MCC30): Код #define MyPin PORTB4 // (например) и потом везде где вам нужно обращаться к PORTB4, будете писать MyPin. Если нужно изменить, будете менять только в хедере.
--------------------
УЭР
|
|
|
|
|
Dec 20 2007, 15:31
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(evc @ Dec 20 2007, 16:50)  Код #define MyPin PORTB4 // (например) Заманчиво, не знал.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 20 2007, 19:11
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Alex B._ @ Dec 20 2007, 20:20)  это шутка? Нет, просто не обратил внимания, что он умеет работать с битовыми переменными и что ноги портов объявлены как битовые переменные. Поскольку я пользуюсь компиляторами, в которых нет такого расширения, и часто приходится таскать код между разными платформами - привык пользоваться стандартными конструкциями типа port |= (1 << bit); В случае с битовыми переменными-выводами портов переносимости можно добиться, обернув их в макросы #define on(pin) pin = 1. Возьму на заметку. Но МСС18 использовать все равно не буду - этот проект уже закончен в SDCC, а новых на пиках, надеюсь, не будет. А если и будут - SDCC уже освоен и к эклипсе прикручен.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 20 2007, 20:06
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Сергей Борщ @ Dec 20 2007, 17:31)  Заманчиво, не знал. Встроенные макросы для прямого побитного объявления портов и других SFR-ов есть и в компиляторах HTPICC, HTPIC18 для ПИКов. Пример: Код #define pin_PFail RB5 #define pin_1w_in RE2 #define pin_1w_out RA5 И в ИАРовских компиляторах, в частности IAR AVR 4.21. Пример: Код #define poGreenLED PORTB_Bit6 #define poRedLED PORTB_Bit7 Вот цитата из файла iom128.h: Код /* Examples of how to use the expanded result: * TCCR2 |= (1<<5); * or if ENABLE_BIT_DEFINITIONS is defined * TCCR2 |= (1<<COM21); * or like this: * TCCR2_Bit5 = 1; * or like this: * TCCR2_COM21 = 1; */
|
|
|
|
|
Dec 20 2007, 20:20
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Baser @ Dec 20 2007, 22:06)  И в ИАРовских компиляторах, в частности IAR AVR 4.21. Да, вспомнил, что мне не понравилось в таком подходе - объявив таким образом конкретный пин, я могу с ним делать только два действия - on и off. А через свои чудо-макросы - on, off, читать, менять направление, читать направление и прочее. При использовании битовых полей универсальности не получается - невозможно будет сделать if(signal(SCLK)) { dir_out(SCLK); off(SCLK); } if(dir(SCLK) { on(SCLK); dir_in(SCLK); } - придется отдельно объявлять SCLK_PIN, SCLK_DIR, SCLK_OUT. В общем: если макросы дают больше удобств - зачем от них отказываться?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 21 2007, 15:50
|

Местный
  
Группа: Свой
Сообщений: 206
Регистрация: 17-03-07
Из: Москва
Пользователь №: 26 266

|
Цитата(Сергей Борщ @ Dec 20 2007, 22:11)  Нет, просто не обратил внимания, что он умеет работать с битовыми переменными и что ноги портов объявлены как битовые переменные... Знаете, это не совсем так... Это особенность адресации в майкрочиповских контроллерах - у них каждый пин (вообще бит SFR) имеет свой адрес, как регистр (напр. адрес PORTB4 = @PORTB + 4). Вот поэтому, объявляя "#define MyPin PORTB4", указываете препроцессору, что значение этикетки MyPin будет равно адресу пина PORTB4. Это все равно записать Код unsigned char* MyPin; MyPin = @PORTB4;// = @PORTB + 4 (только это уже будет переменная в памяти процессора) Пользуясь подобными выражениями (#define ...), можете не только выставлять или обнулять данного пина, но и читать его состояние. Направление пина не можете менять, поскольку в ПИК-е этим обязан совсем другой регистр (TRIS).
--------------------
УЭР
|
|
|
|
|
Dec 21 2007, 17:25
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(evc @ Dec 21 2007, 17:50)  Это особенность адресации в майкрочиповских контроллерах - у них каждый пин (вообще бит SFR) имеет свой адрес, Это что-то новенькое. С х51 не путаете? А существо вопроса в том, что в макросе я указываю не конкретный регистр (PORTx, TRISx, LATx), а имя порта (A, B, C) и уже внутри макроса из него получается имя нужного регистра в зависимости от необходимого действия. При использовании битовых полей такое невозможно.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 21 2007, 20:40
|

Местный
  
Группа: Свой
Сообщений: 206
Регистрация: 17-03-07
Из: Москва
Пользователь №: 26 266

|
Цитата(Сергей Борщ @ Dec 21 2007, 20:25)  Это что-то новенькое. С х51 не путаете?... Нет не новенькое (наверно я не очень, так, объяснил). У х51 немножко по-другому. У них регистр направления порта нет. Что бы настроит на вход нужно просто на порт выставить 1. В ПИК-ах есть регистр направления - именно TRIS (конечно, это вам хорошо известно). Дело в том, что вы о макросах говорите, а та конструкция, о которой я - обыкновенная директива препроцессора. Объявление константы "MyPin" со значением "адрес PORTB4". Мне, в принципе, макросы не нравятся, потому что они съедают програмную память. Но это стоит учитывать только на маленьких процессорах. Зато код выполняется (если пользуетесь макросами) быстрее.
--------------------
УЭР
|
|
|
|
|
Dec 21 2007, 21:52
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(evc @ Dec 21 2007, 22:40)  Нет не новенькое (наверно я не очень, так, объяснил). У х51 немножко по-другому. У них регистр направления порта нет. Это-то понятно. С каких пор у ПИКов каждый бит порта имеет свой адрес? Цитата(evc @ Dec 21 2007, 22:40)  Мне, в принципе, макросы не нравятся, потому что они съедают програмную память. Тоже чудеса рассказываете. Используемый мной (приведенный выше) макрос on(LED) преобразуется препроцессором(!) в С-выражение LATx |= ( 1<< bit), что, в свою очередь, компилируется в команду BSF LATx, bit. Где съедание памяти?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 21 2007, 22:47
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(evc @ Dec 21 2007, 17:50)  Это особенность адресации в майкрочиповских контроллерах - у них каждый пин (вообще бит SFR) имеет свой адрес, как регистр (напр. адрес PORTB4 = @PORTB + 4). Вот поэтому, объявляя "#define MyPin PORTB4", указываете препроцессору, что значение этикетки MyPin будет равно адресу пина PORTB4 Ну, если так рассуждать, то любой бит регистрового файла в пределах одной страницы у ПИК-ов имеет уникальный адрес, состоящий из адресов байта+бита. Это поддерживается на уровне системы команд. Побитовая адресация части SFR-ов на уровне системы команд есть и у AVR и у MCS51 семейства. Но на самом деле адрес регистра и адрес бита находятся в разных адресных пространствах и мешать их нельзя. В ANSI С нет операций с отдельными битами, поэтому разработчики компиляторов изголяются кто как может. Приведенный вами пример с PORTB4 это уже фича компилятора. Например, вот выдержка из мануала на HTPICC: Цитата PICC supports bit integral types which can hold the values 0 or 1. The bit variable facility may be combined with absolute variable declarations (see page 153) to access bits at specific addresses. Absolute bit objects are numbered from 0 (the least significant bit of the first byte) up. Therefore, bit number 3 (the fourth bit in the byte since numbering starts with 0) in byte number 5 is actually absolute bit number 43 (that is 8bits/byte * 5 bytes + 3 bits).
For example, to access the power down detection flag bit in the RCON register, declare RCON to be a C object at absolute address 03h, then declare a bit variable at absolute bit address 27:
static unsigned char RCON @ 0xFD0; static near bit PD @ (unsigned)&RCON*8+2;
Note that all standard registers and bits within these registers are defined in the header files provided. Поэтому, когда мы пишем PORTB4, мы используем встроенный макрос и просто даем прямую команду компилятору применить специфическую для данного процессора команду битовой адресации. В общем случае компилятор имеет право это не поддерживать. Цитата(evc @ Dec 21 2007, 22:40)  Мне, в принципе, макросы не нравятся, потому что они съедают програмную память. Но это стоит учитывать только на маленьких процессорах. Зато код выполняется (если пользуетесь макросами) быстрее. Вы говорите о inline macro, которые каждый раз, когда встречаются в тексте, заменяются на одинаковые куски кода. Сергей же приводит пример макросов переопределения синтаксиса. При этом все равно каждая строка транслируется в одну команду работы с портами. Смысл таких макросов в том, что куски кода можно без исправлений переносить с одного компилятора и процессора на другой. Переписать нужно будет только макросы.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|