[an error occurred while processing this directive] [an error occurred while processing this directive]
А вот самый правильный ;-) способ
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)
[an error occurred while processing this directive] [an error occurred while processing this directive]

Отправлено Самый правильный способ 25 апреля 2002 г. 11:57
В ответ на: Как в IAR AVR писать бинарные числа???? 0b01010101 и 01010101b непроходят............. отправлено Колян 24 апреля 2002 г. 20:06


(c) Boris F.Frolkin,2002

C/C++ Bits & Fields Define FAQ

Q1. Зачем это нужно?
Q2. Как это можно использовать?
Q3. Как это сделано?


A1. Зачем это нужно?

Любой программист микроконтроллеров рано или поздно сталкивается с тем, что
для инициализации какого-нибудь регистра нужно определить константу, состоящую
из нескольких битовых полей. К сожалению, в языке С/С++ нет встроенных средств
для определения битовых констант. Обычно в таком случае используют 16-ричные
константы, вручную сделав перевод из двоичной системы в 16-ричную.
Но это неудобно, ненаглядно, муторно при большом числе регистров в процессоре
и может привести к ошибкам, особенно если необходимо заполнять поля из
нескольких групп байт, пересекающих 4-битовые границы.
Кроме того, при таком способе невозможно определить часть полей в одном месте
программы, а часть в другом. Есть и другие неудобства.
Существует способ определения битовой константы через 8-ричную, но он тоже
неудобен, особенно для 16(32)-разрядных данных - все 16(32) нулей или единиц
приходится писать подряд и разобраться в получившейся каше довольно
затруднительно.
Однако, с использованием вложенных #define, процесс определения битовых полей
в константах можно существенно облегчить и сделать наглядным и удобным для
понимания и самодокументирования программы.

A2. Как это можно использовать?

Просто. Вызывается DefByte() или DefWord(), где через запятую перечисляются
значения битов 1 или 0, начиная со старшего разряда. Можно также использовать
их эквиваленты on/off, en/dis, yes/no. Неиспользуемые биты обозначаются
значком X. Если нужно определить поле из нескольких бит, для всех старших
битов этого поля используют знак подчеркивания, а в младшем бите записывают
значение всего поля. Если это число не превышает 100 (можно сделать и больше,
если хочется), его пишут без скобок, если превышает - в круглых скобках. Если
зачение любого (битового или многобитового) поля определено в другом месте
через #define или присутствует как вычисляемое константное выражение, то
значение такого поля также нужно писать в круглых скобках.
Группы бит удобно выделять пробелами.

EXAMPLES (Infineon C16x family):
-------------------
//Run,LoopBack,div2/div3,even/odd,
//divFrac,OverrunErrFlag,FramingErrFlag,ParityErrFlag,
//OverrunCheck,FramingCheck,ParityCheck,ReceiverEnable,
//stop1/stop2,_,_,Mode

RS232_REG = DefWord(off,dis,0,0, 1,x,x,x, dis,dis,dis,en, 0,_,_,1);
-------------------
//IntReqFlag,IntEnable,
//IntPriorityLevel=4bit,
//IntGroupLevel=2bit

RS232_TransmitIC = DefByte(0,en, _,_,_,9, _,0)
RS232_ReceiveIC = DefByte(0,en, _,_,_,9, _,1)
RS232_ErrorIC = DefByte(0,en, _,_,_,4, _,0)
RS232_TransBufIC = DefByte(0,en, _,_,_,9, _,2)
-------------------
typedef enum {BusDemux8=0, BusMux8=1, BusDemux16=2, BusMux16=3} BusMode;

//WrCsDepend,RdCsDepend,x,ReadyEn,
//x,CsEn,AleLengthened,EarlyWrite,
//_,BusType,NoMemTristateWaitstate,NoRWdelay,
//_,_,_,WaitStates=15-x

BUSCON1 = DefWord(no,no,x,dis, x,en,yes,en, _,(BusMux8),yes,yes, _,_,_,(15-3))
BUSCON2 = DefWord(no,no,x,dis, x,en,no,dis, _,(BusMux16),no,yes, _,_,_,(15-0))
BUSCON3 = DefWord(no,no,x,dis, x,en,no,dis, _,(BusMux16),no,yes, _,_,_,(15-0))
BUSCON4 = DefWord(no,no,x,dis, x,en,no,dis, _,(BusMux16),no,yes, _,_,_,(15-0))
-------------------
typedef enum {Size4K=0, Size8K=1, Size16K=2,.. Size4M=10} BusSize;

//RangeStartAddress=12bit, RangeSizeSelection=4bit

ADDRSEL1 = DefWord(_,_,_,_,_,_,_,_,_,_,_,(0x000),_,_,_,(Size2M))
ADDRSEL2 = DefWord(_,_,_,_,_,_,_,_,_,_,_,(0x300),_,_,_,(Size64K))
ADDRSEL3 = DefWord(_,_,_,_,_,_,_,_,_,_,_,(0x340),_,_,_,(Size64K))
ADDRSEL4 = DefWord(_,_,_,_,_,_,_,_,_,_,_,(0x380),_,_,_,(Size64K))
-------------------
-------------------


A3. Как это сделано?


#define DefBitByte(b7,b6,b5,b4,b3,b2,b1,b0) \
(DefBitField_##b7<<7 | DefBitField_##b6<<6 | DefBitField_##b5<<5 | DefBitField_##b4<<4 | \
DefBitField_##b3<<3 | DefBitField_##b2<<2 | DefBitField_##b1<<1 | DefBitField_##b0<<0)
#define DefBitWord(b15,b14,b13,b12,b11,b10,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0) \
(DefBitField_##b15<<15 | DefBitField_##b11<<11 | DefBitField_##b7<<7 | DefBitField_##b3<<3 | \
DefBitField_##b14<<14 | DefBitField_##b10<<10 | DefBitField_##b6<<6 | DefBitField_##b2<<2 | \
DefBitField_##b13<<13 | DefBitField_##b9 <<9 | DefBitField_##b5<<5 | DefBitField_##b1<<1 | \
DefBitField_##b12<<12 | DefBitField_##b8 <<8 | DefBitField_##b4<<4 | DefBitField_##b0<<0)

#define DefBitField_0 0
#define DefBitField_1 1
#define DefBitField_2 2
#define DefBitField_3 3
.........................
#define DefBitField_98 98
#define DefBitField_99 99
#define DefBitField__ 0
#define DefBitField_o 0
#define DefBitField_O 0
#define DefBitField_x 0
#define DefBitField_X 0
#define DefBitField_on 1
#define DefBitField_off 0
#define DefBitField_en 1
#define DefBitField_dis 0
#define DefBitField_yes 1
#define DefBitField_no 0
#define DefBitField_(Value) (Value)




Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru