|
|
  |
возможно ли на Си, объединить биты регистров портов микроконтроллера |
|
|
|
Jun 14 2009, 11:34
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Я бы сделал так:
#define UP(port, bit) port |= (1<<bit) #define DOWN(port, bit) port &= ~(1<<bit)
Далее:
#define LIGHT P1OUT,1 #define MOTOR P2OUT,3 #define BEEPER P3OUT,2
Итого имеем:
UP(LIGHT); DOWN(MOTOR); UP(BEEPER);
Названия регистров взял от МСП, как наиболее актуального для меня
Если хочется именно структуры, то надо немного подумать. Например, определить структуру Pin{}, в которой указать порт, номер пина и т.д. Например, забить туда все регистры порта (OUT,DIR,IE,SEL). А потом уже эту структуру включать внутрь других структур. Но всё равно без макросов не обойтись. Либо класс рисовать.
Хотя, если взять тот же МСП, то там в io.h порты расписаны в том числе и как структуры, и можно написать port1.out.pin3 = 1; port2.out.pin1 = 0; Тогда всё еще проще: #define MOTOR port1.out.pin3; ... MOTOR = 1; C инициализацией других регистров порта опять же, нужно отдельно думать.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jun 14 2009, 17:09
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(aaarrr @ Jun 14 2009, 14:35)  очень полезный в некоторых случаях прием. ОК, я подумаю. Хотелось бы уточнить случаи. Вопрос то в чем - если придерживаться какой-то структуры проекта, логичного разбиения проекта на модули (файлы), то достаточно сложные инлайновые функции должны быть определены в соответствующих модулях. И им нечего быть включенными в другие модули. Как раз недавно пришлось воспользоваться инлайном и оптимизацией для быстрых операций в прерывании. Если же функция вырождается в дерганье выводом или считывание его состояния, то объясните мне плз, в чем преимущество инлайновой функции по сравнению с простейшим макросом: #define ON_BACKLIGHT (P1OUT|=P1_BACKLIGHT), где #define P1_BACKLIGHT 0x02 //output
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 14 2009, 17:16
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Dog Pawlowa @ Jun 14 2009, 21:09)  ОК, я подумаю. Хотелось бы уточнить случаи. Например, есть у меня в модуле display такая функция: Код __forceinline void disp_set_dot_alpha(u_int x, u_int y, DISP_COLOR color, u_char alpha) { u_int c0, c1, mask; if(alpha > 0) { c0 = color; if(alpha < DISP_MAX_ALPHA) { c1 = *((u_short*)&disp_frame + (y * DISP_WIDTH) + x); mask = 0x07e0f81f; c0 = (c0 | (c0 << 16)) & mask; c1 = (c1 | (c1 << 16)) & mask; c0 = ((c0 * alpha) >> 5) & mask; c1 = ((c1 * (DISP_MAX_ALPHA - alpha)) >> 5) & mask; c0 = c0 + c1; c0 |= c0 >> 16; } *((u_short*)&disp_frame + (y * DISP_WIDTH) + x) = c0; } } Тащить всю работу с графикой в один модуль неразумно, до макроса не вырождается, зато как инлайн функция существенно повышает производительность.
|
|
|
|
|
Jun 14 2009, 17:29
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(Dog Pawlowa @ Jun 14 2009, 20:09)  #define ON_BACKLIGHT (P1OUT|=P1_BACKLIGHT), где #define P1_BACKLIGHT 0x02 //output Это значит, что где-то кто-то может встретить в вашей программе: Код ... ON_BACKLIGHT; ... Вы сами-то как оцениваете читабельность такого выражения?
|
|
|
|
|
Jun 14 2009, 17:36
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(aaarrr @ Jun 14 2009, 20:16)  зато как инлайн функция существенно повышает производительность. ОК, спасибо. Видимо, не сталкивался. Но в таком виде функция не инклюдится, или я не знаю эту среду/компилятор? Цитата(sergeeff @ Jun 14 2009, 20:29)  Вы сами-то как оцениваете читабельность такого выражения? Супер! Превосходная ! Ни у кого такого нет! "Включить подсвет", насколько мне известно... Большие буквы, отсутствие скобок -> значит это макрос для работы с портами -> см файл project_ports.h Лет пят-шесть так работаю, маразм наступает, но вот с этим пока проблем не было.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 14 2009, 17:55
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(aaarrr @ Jun 14 2009, 20:41)  Вы имеете в виду __forceinline? Это от RVCT. Нет, я не только это я имею ввиду. Как тут отмечалось, чтобы функция инлайнилась, нужно, чтобы ее текст попадал в область видимости, то есть ее текст должен быть перенесен в модуль, где она используется, как то так: #define DISPL_SET_DOT_ALPHA __forceinline void disp_set_dot_alpha(u_int x, u_int y, DISP_COLOR color, u_char alpha) \ { \ u_int c0, c1, mask; \ if(alpha > 0) \ { \ ... Цитата(aaarrr @ Jun 14 2009, 20:41)  Понятно, что при помощи макросов можно заставить 'C' выглядеть как что-то совсем другое, но, ИМХО, лучше так не делать. Так сложилось в жизни, что был период turbo pascal 6.0/ Pascal Borland 7.0 for embedded applications, so I don't follow strong rules in C
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 14 2009, 18:04
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(sergeeff @ Jun 14 2009, 20:48)  Ну это, условный рефлекс, наверное. Форум "электроникс" - 1) достаточно модерируемый и 2) самоорганизующийся форум. Я удивлен тем фактом, что мне приходится отметать Ваш переход на какие-то посторонние от техники аспекты. Или Вы так зашорены, что больше нечего сказать? Цитата(aaarrr @ Jun 14 2009, 20:59)  Только не так, Боже упаси! Функция в header'е display.h, который и подключается. А, ну да, конечно...
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jun 14 2009, 18:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(Dog Pawlowa @ Jun 14 2009, 21:04)  Или Вы так зашорены, что больше нечего сказать? 1. При чем тут зашоренность. Абсолютное большинство программистов, увидев Код ABC() сразу поймет, что вызывается некая функция, т.е. некая локальная обработка данных, а Код ABC; может означать все что угодно. Может это чтение из глобальной переменной ABC в стиле уважаемого гуру zltigo, a может вызов макро. 2. Есть понятие "стиль программирования". Мне кажется, что "стильно" написанная программа это такая, которая легко читается и сопровождается, и не только автором.
|
|
|
|
|
Jun 14 2009, 18:41
|

Местный
  
Группа: Участник
Сообщений: 252
Регистрация: 2-03-08
Пользователь №: 35 557

|
Цитата(MrYuran @ Jun 14 2009, 15:34)  Я бы сделал так: Всем большое спасибо за помощь
Причина редактирования: Нарушение п.3.4 Правил форума.
--------------------
One Chip is All You Need
|
|
|
|
|
Jun 14 2009, 18:59
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(another_one @ Jun 14 2009, 21:41)  Всем большое спасибо за помощь Небольшой пример для иллюстрации "прелестей" макро. Код #define UP(port, bit) port |= (1<<bit) где-то в программе напишем: Код UP(port,2) + 3; Понятно, что такое можно написать после долгих праздников, но это может быть и результатом типичной ляпы типа "copy/paste". Очевидно, что это ляпа, но препроцессор это преобразует в Код port |= (1<<2) + 3; и компилятор не моргнув никакими error/warning откомпилирует. Очевидно, что это ляпа, но сколько времени вы будете ее искать? Ежели UP оформить в виде inline функции Код inline void UP(char port, char bit) {port &= ~(1<<bit);} компилятор тут же выдаст что-нибудь типа '+' : illegal operand of type 'void' с указанием номера строки (VS 2008). Если не хочется себе жизнь облегчать, то это, конечно, дело каждого уважаемого участника форума.
|
|
|
|
|
Jun 14 2009, 19:05
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergeeff @ Jun 14 2009, 22:59)  Ежели UP оформить в виде inline функции Код inline void UP(char port, char bit) {port &= ~(1<<bit);} Ну, с тем же успехом можно сделать и в виде дефайна: Код #define UP(port, bit) {port &= ~(1<<bit);}
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|