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

 
 
6 страниц V  « < 4 5 6  
Reply to this topicStart new topic
> Стиль программирования на Си, описание функции
sKWO
сообщение Apr 7 2008, 10:40
Сообщение #76


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(zltigo @ Apr 2 2008, 22:30) *
Компиляторы умнеют, но тем не менее пока не умнее Вас и на подсказку вполне вероятно, ответят лучшим кодом.

К примеру с чем связано столько заморочек в ВИН АВР?
Макрос доступа к битам порта средствами ВИН АВР, например
sbi(PORTB, 5);
Подняв несколька файлов и сделав соответствующие подстановки получаем
следующее ( адрес порта Б к примеру 0x08)
Код
((*(volatile uint8_t *)(((uint16_t) &((*(volatile uint8_t *)((0x08) + 0x20)))) ))   |=(1 << (5)))

средствами ИАР это дело обстоит намного проще и находится в одном файле avr_macros.h
Код
/* Set BIT in ADDRESS */
#define SETBIT(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT)))


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Apr 7 2008, 10:58
Сообщение #77


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
средствами ИАР это дело обстоит намного проще

А как насчёт то же применить в WinAVR? Неужели этот макрос там не будет работать? Вы хоть попробовать-то пытались?


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
sKWO
сообщение Apr 7 2008, 11:07
Сообщение #78


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(sensor_ua @ Apr 7 2008, 13:58) *
А как насчёт то же применить в WinAVR? Неужели этот макрос там не будет работать? Вы хоть попробовать-то пытались?

Да, я немного не про то. Конечно он будет работать. Это и такому дураку как я понятно smile.gif

Попробуйте в ИАР вот так и объясните почему, а то мне дураку не ясно
Допустим нужно установить в единицу четвёртый бит порта ну пускай Б
Настроим его как выход, назовём его HELS
Код
#define HELSp B
#define HELSb 4
CLRDDR(HELS);// направление
SETPORT(HELS);// бит 4 порта Б единичка


Сообщение отредактировал sKWO - Apr 7 2008, 11:41


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Apr 7 2008, 12:51
Сообщение #79


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Не очень понял, что Вы хотите, но на телесистемах на днях обсуждался вариант доступа только по имени.
Код
typedef volatile uint8_t * port_t;

typedef struct Port_Bit{
  port_t Port;
  unsigned char Bit;
}Port_Bit;

void CLRDDR(const Port_Bit * pb){
  *(pb->Port-1) &= ~(1 << pb->Bit);
}
void SETPORT(const Port_Bit * pb){
  *(pb->Port) |= 1 << pb->Bit;
}

Port_Bit dHELS={&PORTB, 4};
const Port_Bit * HELS = &dHELS;


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
sKWO
сообщение Apr 7 2008, 17:49
Сообщение #80


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



спасибо за инфу!!


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
ReAl
сообщение Apr 7 2008, 19:43
Сообщение #81


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(sKWO @ Apr 7 2008, 13:40) *
К примеру с чем связано столько заморочек в ВИН АВР?
Макрос доступа к битам порта средствами ВИН АВР, например
sbi(PORTB, 5);
Подняв несколька файлов и сделав соответствующие подстановки получаем
следующее ( адрес порта Б к примеру 0x08)
Код
((*(volatile uint8_t *)(((uint16_t) &((*(volatile uint8_t *)((0x08) + 0x20)))) ))   |=(1 << (5)))
средствами ИАР это дело обстоит намного проще и находится в одном файле avr_macros.h
Код
/* Set BIT in ADDRESS */
#define SETBIT(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT)))
Средствами WinAVR это "всё" тоже было одной практически такой же строкой
Код
#define sbi(port, bit) (port) |= (1 << (bit))
Зачем её было раскручивать? Какая разница что там, если оно всё равно компилируется в одну такую же команду ассемблера, что и у IAR ?

Ведь для SETBIT(PORTB,5) вы же у IAR не раскручивали, что такое PORTB и не сравнивали с WinAVR?
А он выглядит так

WinAVR:
Код
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + 0x20)
...
#define PORTB    _SFR_IO8(0x18)
Кстати, что-то Ваш вариант раскрутки sbi(port,bit) длинноват, выходит короче
Код
( *(volatile uint8_t *)((0x08) + 0x20) )    |=(1 << (5))


IAR:
Код
#define __BYTEBITS(_NAME,_A,_B,_C,_D,_E,_F,_G,_H) \
unsigned char _NAME ## _ ## _A:1, \
              _NAME ## _ ## _B:1, \
              _NAME ## _ ## _C:1, \
              _NAME ## _ ## _D:1, \
              _NAME ## _ ## _E:1, \
              _NAME ## _ ## _F:1, \
              _NAME ## _ ## _G:1, \
              _NAME ## _ ## _H:1;

#define SFR_B_BITS(_NAME, _ADDR, _A,_B,_C,_D,_E,_F,_G,_H) \
    __io union { \
      unsigned char   _NAME;           /* The sfrb as 1 byte */ \
      struct {                        /* The sfrb as 8 bits */ \
        __BYTEBITS(_NAME, _A,_B,_C,_D,_E,_F,_G,_H) \
      };  \
    } @ _ADDR;

#define SFR_B(_NAME, _ADDR) SFR_B_BITS(_NAME, _ADDR, \
                                    Bit0,Bit1,Bit2,Bit3,Bit4,Bit5,Bit6,Bit7)
...

SFR_B(PORTB,  0x18)
Так что у IAR просто наворочено в другом месте, до которого просто Вы не добрались :-)
Как лучше - тяжело сказать. Вариант IAR позволяет написать
Код
SPMCR.SPMIE = 1;
вместо
Код
SPMCR |= (1 << SPMIE);
или
SPMCR |= _BV(SPMIE);

зато не позволяет сделать то, что позволяет avr-gcc
(к чему это приводит - см, например, http://electronix.ru/forum/index.php?s=&am...st&p=377042 )
Код
#if defined(SPMCSR)
#  define SPM_CONTROL_REG SPMCSR
#elif defined(SPMCR)
#  define SPM_CONTROL_REG SPMCR
#else
#  error "SPM control register not defined"
#endif

...

SPM_CONTROL_REG |= (1 << SPMIE);
Таким образом для всех кристаллов, у которых есть либо SPMCR либо SPMCSR - можно обойтись несколькими строками кода и получить исходник, компилирующийся для всего. У IAR для этого придётся персонально проверять типы процесоров через
Код
#if defined(__AT90Mega88__) || defined(__AT90Mega168__) || ...

А всё потому, что PORTB да SPMCR у avr-gcc это макросы препроцессора, а у IAR - переменные-вложенные агрегаты, прибитые гвозядми к адресам, поэтому их наличие или отсутствие препроцессор не видит и нельзя сделать условную компиляцию просто проверив наличие имени регистра.


Цитата(sKWO @ Apr 7 2008, 14:07) *
Допустим нужно установить в единицу четвёртый бит порта ну пускай Б
Настроим его как выход, назовём его HELS
Код
#define HELSp B
#define HELSb 4
CLRDDR(HELS);// направление
SETPORT(HELS);// бит 4 порта Б единичка
Это вообще уже лет 10 не так делается.

Код
#define LED1 B,0,L   /* светодиод анодом на питание, зажигаем низким уровнем - L */
#define LED2 D,1,H   /* светодиод катодом на землю, зажигаем высоким  уровнем */
#define KEY1 C,2,L  /* кнопка на землю, при нажатии низкий уровень */
#define KEY2 A,3,H /*  кнопка на питание, при нажатии высокий уровень */
...
  // теперь не глядя на полярности сигналов пишем ON, чтобы включить, а включается
  // нулём или единичкой - макрос разбирается
  DRIVER(LED1,OUT);
  DRIVER(LED2,OUT);
  DRIVER(KEY1,IN);
  DRIVER(KEY1,PULLUP); // к примеру тут обходимся внутренней подтяжкой
  DRIVER(KEY2,IN);
  DRIVER(KEY2,HIZ);   // а тут внешняя подтяжка на землю
...
  if( ACTIVE(KEY1) ) {
    ON(LED1);
    OFF(LED2);
  }

  if( ACTIVE(KEY2) ) OFF(LED1);

  if( flag) ) CPL(LED2); // проинвертировали ногу


Называется "макросы Аскольда Волкова", модифицировалось уже под разные процессоры и компиляторы всеми кому не лень. Вот мой вариант:
Прикрепленные файлы
Прикрепленный файл  pin_macros.zip ( 1.32 килобайт ) Кол-во скачиваний: 112
 


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
sKWO
сообщение Apr 8 2008, 11:00
Сообщение #82


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(ReAl @ Apr 7 2008, 22:43) *
Называется "макросы Аскольда Волкова", модифицировалось уже под разные процессоры и компиляторы всеми кому не лень.

C макросами ядерного физика Аскольда Волкова давно знаком, удобная вещь, когда-то на Телесисах
он его представлял, собственно как и его модификацию которую выложил Сергей Борщ.
Конечно же их использую.

Цитата(ReAl @ Apr 7 2008, 22:43) *
А всё потому, что PORTB да SPMCR у avr-gcc это макросы препроцессора, а у IAR - переменные-вложенные агрегаты, прибитые гвозядми к адресам, поэтому их наличие или отсутствие препроцессор не видит и нельзя сделать условную компиляцию просто проверив наличие имени регистра.

За это большое спасибо!


Цитата(ReAl @ Apr 7 2008, 22:43) *
длинноват, выходит короче
Код
( *(volatile uint8_t *)((0x08) + 0x20) )    |=(1 << (5))

Код
в файле sfr_def.h находим
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
дальше
#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))
дальше
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_ADDR(sfr) _SFR_MEM_ADDR(sfr)  
#define _SFR_MEM_ADDR(sfr) ((uint16_t) &(sfr))
получаем
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
подставляем
#define sbi(sfr, bit) (   (*(volatile uint8_t *)(   ((uint16_t) &(sfr))   ))   |= _BV(bit))
смотрим в  pgmspace.h  _BV
#define _BV(bit) (1 << (bit))
видим
#define sbi(sfr, bit)  ((*(volatile uint8_ t *)(((uint16_t) &(sfr)) ))   |=  (1 << (bit)))
всё хорошо получается или чёта провтыкал?
имеем следующее
((*(volatile uint8_t *)(((uint16_t) &(PORTB )) ))   |=  (1 << (5)))
ну и остаётся за малым подставить знач порта
допустим
#define PORTB  _SFR_IO8(0x08)
находим _SFR_IO8 в файле sfrdefs.h
#define _SFR_IO8(io_addr) _MMIO_BYTE ((io_addr) + 0x20)
соответственно _SFR_IO8(0x08) есть_MMIO_BYTE((0x08) + 0x20)
а  _MMIO_BYTE((0x08) + 0x20) есть (*(volatile uint8_t *)((0x08) + 0x20))
отсюда и получается
((*(volatile uint8_t *)(((uint16_t) &((*(volatile uint8_t *)((0x08) + 0x20)))) ))   |=(1 << (5)))

Выходит разные версии компилят , наверное smile.gif


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post

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

 


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


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