IAR их использует в своих целях? А то хочется их в качестве флаговых
задействовать (в асме так делаю). А то создал битовое поле, а он его в
SRAM засунул, да ещё и обращается к нему через указатель Z - долго всё
это. Как поступить? Как запретить IAR использовать эти регистры в своих
целях. И как разместить структуру по заданному адресу?
IAR - не использует.
Переменная кладётся по адресу так:
__no_init char a @0x100;
Подозреваю, что даже если положить в GPIOR битовое поле, вряд ли код будет оптимальным. Впрочем, не проверял; с интересом жду результатов Ваших экспериментов

CodeVision - использует GPIOR и размещает там битовые переменные в первую очередь.
prottoss
Mar 2 2006, 17:33
Цитата(SZ0 @ Mar 2 2006, 18:32)

IAR их использует в своих целях? А то хочется их в качестве флаговых
задействовать (в асме так делаю). А то создал битовое поле, а он его в
SRAM засунул, да ещё и обращается к нему через указатель Z - долго всё
это. Как поступить? Как запретить IAR использовать эти регистры в своих
целях. И как разместить структуру по заданному адресу?
Код
/****************************************************************************
Системные флаги
****************************************************************************/
#define g_System_Flags GPIOR0
#define fKEY_VALID (1 << 0)// действительное нажатие кнопки
#define fNEED_FLASH (1 << 1)// гашение мерцающего индикатора
#define fSOUND_ENABLE (1 << 2)// разрешение выхода звукового сигнала
#define fNEED_NEXT_MODE (1 << 3)// разрешение смены режима вывода
#define fVIEW_MENU_NAME (1 << 4)// разрешение вывода названия пункта меню
#define fEDIT_MODE (1 << 5)// вход в меню редактирования режима
#define fEDIT_SUB_ITEM (1 << 6)// редактирование подпункта меню редактирования
#define fNEGATIVE (1 << 7)// флаг отрицательного результата при преобразовании HEX->BCD
#define g_System_Flags2 GPIOR1
#define fPOWER_GOOD (1 << 0)// флаг присутствия основного питания
....
....
....
/****************************************************************************
Прерывание по переполнению ТС0
период вызова - 5мс
Выполняемые функции:
* Вывод очередного символа на индикаторы
* Вычисление скан-бита для следующего выводимого символа из буфера дисплея
* Чтение состояния клавиатуры и определение валидного нажатия кнопки
* Инкремент RTC
* Формирование бита мерцания
****************************************************************************/
#pragma vector=TIMER0_OVF0_vect
__interrupt void TIMER0_OVF0(void)
{ char sn;
// записываем в TC0 значение для переполнения с периодом 5мс (200 гц)
// для частоты внешнего кварца 7.372800 мГц
TCNT0 = (0xFF - TC0_OVR_VAL);
// проверяем присутствие основного питания
if(g_System_Flags2 & fPOWER_GOOD)
{
// обновляем сканбит каждые 4 прерывания
sn = g_Tick & 0x03;
if(!sn)
{ g_Scan = (1 << CATH_1);
}
// формируем байт сканирования и управления устройствами
g_Scan |= (g_Alarm_Exes_Flags | g_Termo_Exes_Flags);
// выводим во внешний регистр символа очередной символ
Led_Data_Transfer(g_Led_Buffer[sn]); // загружаем символ
Led_Data_Transfer(g_Scan);// зажигаем индикатор
// формируем строб записи в выходной регистр 74595
PORTB |= (1 << SSTB);
PORTB &= ~(1 << SSTB);
// читаем клавиатуру
Read_Keys();
// вычисляем новый скан-бит для дисплея и клавиатуры
g_Scan <<= 1;
// Формируем бит мерцания
g_System_Flags &= ~fNEED_FLASH;
if(g_Tick >= FLASH_MAX_VALUE)
{ if(!(g_Menu_Name_Tick & fKEY_VALID)) // если нет нажатой кнопки, мерцаем
{ g_System_Flags |= fNEED_FLASH;
}
}
}
// инкрементируем системное время
Inc_RTC();
}
Что сделал:
__io union
{
struct
{
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char f_tdate:1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
}f1;
}@ 0x1e;//GPIOR0
__io union
{
struct
{
unsigned char f_vardt:1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
}f2;
}@ 0x2a;//GPIOR1
__io union
{
struct
{
unsigned char f_timeind:1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
}f3;
}@ 0x2b;//GPIOR2
108: f1.f_tdate=1;
+0000004B: 9AF3 SBI 0x1E,3
109: f2.f_vardt=1;
+0000004C: B50A IN R16,0x2A
+0000004D: 6001 ORI R16,0x01
+0000004E: BD0A OUT 0x2A,R16
110: f3.f_timeind=1;
+0000004F: B50B IN R16,0x2B
+00000050: 6001 ORI R16,0x01
+00000051: BD0B OUT 0x2B,R16
Что было и сколько кода зинимало:
struct
{
unsigned char :1;
unsigned char f_timeon:1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
}f4;
122: f4.f_timeon=1;
+00000052: E0E0 LDI R30,0x00
+00000053: E0F1 LDI R31,0x01
+00000054: 8100 LDD R16,Z+0
+00000055: 6002 ORI R16,0x02
+00000056: 8300 STD Z+0,R16
123: f4.f_timeon=0;
+00000057: E0E0 LDI R30,0x00
+00000058: E0F1 LDI R31,0x01
+00000059: 8100 LDD R16,Z+0
+0000005A: 7F0D ANDI R16,0xFD
+0000005B: 8300 STD Z+0,R16
IAR не правильно отображает значения битов в полях когда смотрим watch.
У него все биты в поле первые. Хотя всё работает.
prottoss
Mar 2 2006, 19:28
Цитата(SZ0 @ Mar 3 2006, 02:05)

Что сделал:
__io union...
...
IAR не правильно отображает значения битов в полях когда смотрим watch.
У него все биты в поле первые. Хотя всё работает.
Зачем так все усложнять то? Я же привел Вам рабочий кусок программы.
SZ0
Спасибо за информацию.