Помогите разобраться с ошибкой.
При чтении данных с EEPROMa в переменную, данные оказываются в RAM по другому адресу.
Описание проблемы:
В main.c, по флагу вызывается функция, которая читает
данные из EEPROMa в глобальную переменную.
Код
if(DevFlag.ReadDataEE) {
ReReadDataEE();
}
Флаг вызова ф-ии устанавливается в прерывании.
Структура(флаги) объявлена main.c:
Код
typedef struct
{
volatile u_char
Regim12 :1, //
...
ReadDataEE :1, //считать с EEPROMa
...
}dev_fl;
dev_fl DevFlag;
u_int ContrValueData, ContrValueTest;
В функции очищается флаг вызова функции и читаются данные.
Если флаг очищается сразу после входа в функцию, то данные пишутся по другому адресу.
Если если перед выходом из ф-ии, то по адресу переменной(правильно).
В чем ошибка?
Функция чтения данных:
Код
void ReReadDataEE(void)
{
//если сброс флага здесь, то ошибка в адресе записи в RAM
__disable_interrupt();
DevFlag.ReadDataEE = 0;
__enable_interrupt();
if(!DevFlag.Regim12) {
ContrValueData = ReadIntDataEE(ADR_DATA1_EE);
ContrValueTest = ReadIntDataEE(ADR_DATA2_EE);
}
else {
ContrValueData = ReadIntDataEE(ADR_DATA12_EE);
}
//если сброс флага здесь, то ошибки нет
/* __disable_interrupt();
DevFlag.ReadDataEE = 0;
__enable_interrupt(); */
}
Расположение переменных из map файла:
Код
ContrValueTest DATA 0000007E
ContrValueData DATA 0000007C
TimerData DATA 0000007A
//------------------------------------------------------------------------------
Листинг 1, с ошибкой:
Код
312 void ReReadDataEE(void)
\ ReReadDataEE:
313 {
\ 00000000 93AA ST -Y, R26
314 //если сброс флага здесь, то ошибка в адресе записи в RAM
315 __disable_interrupt();
\ 00000002 94F8 CLI
316 DevFlag.ReadDataEE = 0;
\ 00000004 .... LDI R26, (TimerData + 8) & 0xFF
\ 00000006 910C LD R16, X
\ 00000008 .... LDI R26, (TimerData) & 0xFF
\ 0000000A 7F07 ANDI R16, 0xF7
\ 0000000C 930C ST X, R16
317 __enable_interrupt();
\ 0000000E 9478 SEI
318
319 if(!DevFlag.Regim12) {
\ 00000010 910C LD R16, X
\ 00000012 FD00 SBRC R16, 0
\ 00000014 C009 RJMP ??ReReadDataEE_0
320 ContrValueData = ReadIntDataEE(ADR_DATA1_EE);
\ 00000016 E007 LDI R16, 7
\ 00000018 .... RCALL ReadIntDataEE
\ 0000001A .... LDI R26, (TimerData - 6) & 0xFF //вот здесь задается ошибочный адрес
\ 0000001C 930D ST X+, R16
\ 0000001E 931C ST X, R17
321 ContrValueTest = ReadIntDataEE(ADR_DATA2_EE);
\ 00000020 E003 LDI R16, 3
\ 00000022 .... RCALL ReadIntDataEE
\ 00000024 .... LDI R26, (TimerData - 4) & 0xFF
\ 00000026 C003 RJMP ??ReReadDataEE_1
322 }
323 else {
324 ContrValueData = ReadIntDataEE(ADR_DATA12_EE); //
\ ??ReReadDataEE_0:
\ 00000028 E00B LDI R16, 11
\ 0000002A .... RCALL ReadIntDataEE
\ 0000002C .... LDI R26, (TimerData - 6) & 0xFF
\ ??ReReadDataEE_1:
\ 0000002E 930D ST X+, R16
\ 00000030 931C ST X, R17
325 }
326 }
\ 00000032 91A9 LD R26, Y+
\ 00000034 9508 RET
Листинг 2, без ошибки:
Код
312 void ReReadDataEE(void)
\ ReReadDataEE:
313 {
\ 00000000 93AA ST -Y, R26
314 if(!DevFlag.Regim12) {
\ 00000002 .... LDI R26, (TimerData + 8) & 0xFF
\ 00000004 910C LD R16, X
\ 00000006 FD00 SBRC R16, 0
\ 00000008 C009 RJMP ??ReReadDataEE_0
315 ContrValueData = ReadIntDataEE(ADR_DATA1_EE);
\ 0000000A E007 LDI R16, 7
\ 0000000C .... RCALL ReadIntDataEE
\ 0000000E .... LDI R26, (TimerData + 2) & 0xFF
\ 00000010 930D ST X+, R16
\ 00000012 931C ST X, R17
316 ContrValueTest = ReadIntDataEE(ADR_DATA2_EE);
\ 00000014 E003 LDI R16, 3
\ 00000016 .... RCALL ReadIntDataEE
\ 00000018 .... LDI R26, (TimerData + 4) & 0xFF
\ 0000001A C003 RJMP ??ReReadDataEE_1
317 }
318 else {
319 ContrValueData = ReadIntDataEE(ADR_DATA12_EE); //
\ ??ReReadDataEE_0:
\ 0000001C E00B LDI R16, 11
\ 0000001E .... RCALL ReadIntDataEE
\ 00000020 .... LDI R26, (TimerData + 2) & 0xFF
\ ??ReReadDataEE_1:
\ 00000022 930D ST X+, R16
\ 00000024 931C ST X, R17
320 }
321 //если сброс флага здесь, то ошибки адреса нет
322 __disable_interrupt();
\ 00000026 94F8 CLI
323 DevFlag.ReadDataEE = 0;
\ 00000028 .... LDI R26, (TimerData + 8) & 0xFF
\ 0000002A 910C LD R16, X
\ 0000002C .... LDI R26, (TimerData) & 0xFF
\ 0000002E 7F07 ANDI R16, 0xF7
\ 00000030 930C ST X, R16
324 __enable_interrupt();
\ 00000032 9478 SEI
325 }
\ 00000034 91A9 LD R26, Y+
\ 00000036 9508 RET
Компилятор IAR 5.30, контроллер tiny26. Оптимизация максимальная, по скорости.