реклама на сайте
подробности

 
 
5 страниц V  < 1 2 3 4 > »   
Reply to this topicStart new topic
> Компилятор С for PIC
evc
сообщение Dec 20 2007, 14:50
Сообщение #16


Местный
***

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



Цитата(Сергей Борщ @ Dec 20 2007, 16:28) *
...объявить ногу в одном месте, и потом при необходимости в одном месте ее изменить - это гораздо удобнее и ошибкоустойчивее, чем во всем исходнике явно указывать порт и ногу.


тогда в *.h файле просто запишите (MCC30):

Код
#define MyPin PORTB4 // (например)


и потом везде где вам нужно обращаться к PORTB4, будете писать MyPin. Если нужно изменить, будете менять только в хедере.


--------------------
УЭР
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 20 2007, 15:31
Сообщение #17


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Dec 20 2007, 18:20
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



Цитата(Сергей Борщ @ Dec 20 2007, 18:31) *
Заманчиво, не знал.

это шутка?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 20 2007, 19:11
Сообщение #19


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 20 2007, 20:06
Сообщение #20


Просто 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;
*/
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 20 2007, 20:20
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 21 2007, 11:53
Сообщение #22


Просто Che
*****

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



Цитата(Сергей Борщ @ Dec 20 2007, 22:20) *
...

Да, к слову, нет ли под рукой ссылочки, где описывается макропроцессор с применением двойных ##.
Сложные макросы никогда не применял и до сих пор не понимаю значения ## smile.gif , хотя они широко применяются в хидерах компиляторов.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 21 2007, 12:58
Сообщение #23


Гуру
******

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



Цитата(Baser @ Dec 21 2007, 13:53) *
Да, к слову, нет ли под рукой ссылочки, где описывается макропроцессор с применением двойных ##.
Гугля дает много ссылок по запросу "c preprocessor". Я обычно пользуюсь вот этой, разделы 3.4, 3.5


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 21 2007, 13:59
Сообщение #24


Просто Che
*****

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



Цитата(Сергей Борщ @ Dec 21 2007, 14:58) *
Гугля дает много ссылок по запросу "c preprocessor". Я обычно пользуюсь вот этой, разделы 3.4, 3.5

Спасибо, теперь буду знать умные слова stringification (#) и token pasting or token concatenation (##).
Раньше мне везде попадалось только описание Traditional macros, ISO макросы всеми замалчивались smile.gif
Go to the top of the page
 
+Quote Post
evc
сообщение Dec 21 2007, 15:50
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 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).


--------------------
УЭР
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 21 2007, 17:25
Сообщение #26


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
evc
сообщение Dec 21 2007, 20:40
Сообщение #27


Местный
***

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



Цитата(Сергей Борщ @ Dec 21 2007, 20:25) *
Это что-то новенькое. С х51 не путаете?...


Нет не новенькое (наверно я не очень, так, объяснил). У х51 немножко по-другому. У них регистр направления порта нет. Что бы настроит на вход нужно просто на порт выставить 1. В ПИК-ах есть регистр направления - именно TRIS (конечно, это вам хорошо известно). Дело в том, что вы о макросах говорите, а та конструкция, о которой я - обыкновенная директива препроцессора. Объявление константы "MyPin" со значением "адрес PORTB4".
Мне, в принципе, макросы не нравятся, потому что они съедают програмную память. Но это стоит учитывать только на маленьких процессорах. Зато код выполняется (если пользуетесь макросами) быстрее.


--------------------
УЭР
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 21 2007, 21:52
Сообщение #28


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Dec 21 2007, 22:21
Сообщение #29


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



Цитата(Сергей Борщ @ Dec 22 2007, 00:52) *
Это-то понятно. С каких пор у ПИКов каждый бит порта имеет свой адрес?
Тоже чудеса рассказываете. Используемый мной (приведенный выше) макрос on(LED) преобразуется препроцессором(!) в С-выражение LATx |= ( 1<< bit), что, в свою очередь, компилируется в команду BSF LATx, bit. Где съедание памяти?

чего-то он путает конечно =) Все там как обычно
Но макросы все равно зло в любом виде, хоть микрочип, хоть не микрочип. Тогда уж лучше инлайновые функции - компилер хотя бы тело функции сформирует если она явно по указателю будет вызвана
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 21 2007, 22:47
Сообщение #30


Просто 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, которые каждый раз, когда встречаются в тексте, заменяются на одинаковые куски кода.
Сергей же приводит пример макросов переопределения синтаксиса. При этом все равно каждая строка транслируется в одну команду работы с портами. Смысл таких макросов в том, что куски кода можно без исправлений переносить с одного компилятора и процессора на другой. Переписать нужно будет только макросы.
Go to the top of the page
 
+Quote Post

5 страниц V  < 1 2 3 4 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 4th July 2025 - 23:37
Рейтинг@Mail.ru


Страница сгенерированна за 0.01516 секунд с 7
ELECTRONIX ©2004-2016