evc 0 20 декабря, 2007 Опубликовано 20 декабря, 2007 · Жалоба ...объявить ногу в одном месте, и потом при необходимости в одном месте ее изменить - это гораздо удобнее и ошибкоустойчивее, чем во всем исходнике явно указывать порт и ногу. тогда в *.h файле просто запишите (MCC30): #define MyPin PORTB4 // (например) и потом везде где вам нужно обращаться к PORTB4, будете писать MyPin. Если нужно изменить, будете менять только в хедере. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 декабря, 2007 Опубликовано 20 декабря, 2007 · Жалоба #define MyPin PORTB4 // (например) Заманчиво, не знал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex B._ 0 20 декабря, 2007 Опубликовано 20 декабря, 2007 · Жалоба Заманчиво, не знал. это шутка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 декабря, 2007 Опубликовано 20 декабря, 2007 · Жалоба это шутка?Нет, просто не обратил внимания, что он умеет работать с битовыми переменными и что ноги портов объявлены как битовые переменные. Поскольку я пользуюсь компиляторами, в которых нет такого расширения, и часто приходится таскать код между разными платформами - привык пользоваться стандартными конструкциями типа port |= (1 << bit); В случае с битовыми переменными-выводами портов переносимости можно добиться, обернув их в макросы #define on(pin) pin = 1. Возьму на заметку. Но МСС18 использовать все равно не буду - этот проект уже закончен в SDCC, а новых на пиках, надеюсь, не будет. А если и будут - SDCC уже освоен и к эклипсе прикручен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 20 декабря, 2007 Опубликовано 20 декабря, 2007 · Жалоба Заманчиво, не знал. Встроенные макросы для прямого побитного объявления портов и других 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; */ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 декабря, 2007 Опубликовано 20 декабря, 2007 · Жалоба И в ИАРовских компиляторах, в частности 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. В общем: если макросы дают больше удобств - зачем от них отказываться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба ... Да, к слову, нет ли под рукой ссылочки, где описывается макропроцессор с применением двойных ##. Сложные макросы никогда не применял и до сих пор не понимаю значения ## :) , хотя они широко применяются в хидерах компиляторов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Да, к слову, нет ли под рукой ссылочки, где описывается макропроцессор с применением двойных ##.Гугля дает много ссылок по запросу "c preprocessor". Я обычно пользуюсь вот этой, разделы 3.4, 3.5 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Гугля дает много ссылок по запросу "c preprocessor". Я обычно пользуюсь вот этой, разделы 3.4, 3.5 Спасибо, теперь буду знать умные слова stringification (#) и token pasting or token concatenation (##). Раньше мне везде попадалось только описание Traditional macros, ISO макросы всеми замалчивались :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evc 0 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Нет, просто не обратил внимания, что он умеет работать с битовыми переменными и что ноги портов объявлены как битовые переменные... Знаете, это не совсем так... Это особенность адресации в майкрочиповских контроллерах - у них каждый пин (вообще бит SFR) имеет свой адрес, как регистр (напр. адрес PORTB4 = @PORTB + 4). Вот поэтому, объявляя "#define MyPin PORTB4", указываете препроцессору, что значение этикетки MyPin будет равно адресу пина PORTB4. Это все равно записать unsigned char* MyPin; MyPin = @PORTB4;// = @PORTB + 4 (только это уже будет переменная в памяти процессора) Пользуясь подобными выражениями (#define ...), можете не только выставлять или обнулять данного пина, но и читать его состояние. Направление пина не можете менять, поскольку в ПИК-е этим обязан совсем другой регистр (TRIS). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Это особенность адресации в майкрочиповских контроллерах - у них каждый пин (вообще бит SFR) имеет свой адрес,Это что-то новенькое. С х51 не путаете? А существо вопроса в том, что в макросе я указываю не конкретный регистр (PORTx, TRISx, LATx), а имя порта (A, B, C) и уже внутри макроса из него получается имя нужного регистра в зависимости от необходимого действия. При использовании битовых полей такое невозможно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evc 0 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Это что-то новенькое. С х51 не путаете?... Нет не новенькое (наверно я не очень, так, объяснил). У х51 немножко по-другому. У них регистр направления порта нет. Что бы настроит на вход нужно просто на порт выставить 1. В ПИК-ах есть регистр направления - именно TRIS (конечно, это вам хорошо известно). Дело в том, что вы о макросах говорите, а та конструкция, о которой я - обыкновенная директива препроцессора. Объявление константы "MyPin" со значением "адрес PORTB4". Мне, в принципе, макросы не нравятся, потому что они съедают програмную память. Но это стоит учитывать только на маленьких процессорах. Зато код выполняется (если пользуетесь макросами) быстрее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Нет не новенькое (наверно я не очень, так, объяснил). У х51 немножко по-другому. У них регистр направления порта нет.Это-то понятно. С каких пор у ПИКов каждый бит порта имеет свой адрес? Мне, в принципе, макросы не нравятся, потому что они съедают програмную память.Тоже чудеса рассказываете. Используемый мной (приведенный выше) макрос on(LED) преобразуется препроцессором(!) в С-выражение LATx |= ( 1<< bit), что, в свою очередь, компилируется в команду BSF LATx, bit. Где съедание памяти? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex B._ 0 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Это-то понятно. С каких пор у ПИКов каждый бит порта имеет свой адрес? Тоже чудеса рассказываете. Используемый мной (приведенный выше) макрос on(LED) преобразуется препроцессором(!) в С-выражение LATx |= ( 1<< bit), что, в свою очередь, компилируется в команду BSF LATx, bit. Где съедание памяти? чего-то он путает конечно =) Все там как обычно Но макросы все равно зло в любом виде, хоть микрочип, хоть не микрочип. Тогда уж лучше инлайновые функции - компилер хотя бы тело функции сформирует если она явно по указателю будет вызвана Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 21 декабря, 2007 Опубликовано 21 декабря, 2007 · Жалоба Это особенность адресации в майкрочиповских контроллерах - у них каждый пин (вообще бит 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, мы используем встроенный макрос и просто даем прямую команду компилятору применить специфическую для данного процессора команду битовой адресации. В общем случае компилятор имеет право это не поддерживать. Мне, в принципе, макросы не нравятся, потому что они съедают програмную память. Но это стоит учитывать только на маленьких процессорах. Зато код выполняется (если пользуетесь макросами) быстрее. Вы говорите о inline macro, которые каждый раз, когда встречаются в тексте, заменяются на одинаковые куски кода. Сергей же приводит пример макросов переопределения синтаксиса. При этом все равно каждая строка транслируется в одну команду работы с портами. Смысл таких макросов в том, что куски кода можно без исправлений переносить с одного компилятора и процессора на другой. Переписать нужно будет только макросы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться