IAR AVR, запись в EEPROM. Подскажите, в чем причина, толи лыжи не
едут, толи я? Леплю некий блочок, который должен померить время спада напряжения и записать результат в ЕЕПРОМ. Который я после из епрома считаю программатором. Читаю почему-то нули. Есть программный таймер в регистровой паре R5:R4, который считает обратно, до нуля. т.е. загрузив в пару значение 1000, каждое прерыание таймера Т0 (~1мс) из этой тыщи вычитается единица. Компилятор последний, IAR AVR 8.10, с предыдущим IAR AVR 7.30 точно такая же картина. Оптимизация максимальная. Всё обволятилено. Исходный текст:
__no_init __eeprom volatile unsigned int eeTestTime @17;
#pragma required=eeTestTime
void main(void)
{
WriteTimer (1000); // зарядить обратный таймер на 1000 мс
// Бла-бла-бла ....
eeTestTime = uiReadTimer();
Листинг:
315 WriteTimer (1000); // зарядить обратный таймер на 1000 мс
\ 00000000 94F8 CLI
\ 00000002 EE08 LDI R16, 232
\ 00000004 2E40 MOV R4, R16
\ 00000006 E003 LDI R16, 3
\ 00000008 2E50 MOV R5, R16
\ 0000000A 9478 SEI
316
317 // Бла-бла-бла ....
318
319 eeTestTime = uiReadTimer();
\ 0000000C 94F8 CLI
\ 0000000E 0182 MOVW R17:R16, R5:R4
\ 00000010 9478 SEI
\ 00000012 E141 LDI R20, 17
\ 00000014 .... RCALL __eeput16_8
Все нормально, засады нет. Жирным выделил чтение содержимого счётчика, и запись в ячейку №17 еепрома. Чтение епрома дает оставшееся время в таймере. Но мне интересно не оставшееся время в таймере, а прошедшее с момента старта. Поэтому я добавляю вычитание значение таймера из 1000:
// Бла-бла-бла ....
eeTestTime = (unsigned int) 1000 - uiReadTimer();
И тут начинается какая-то неведомая мне хрень:
317 // Бла-бла-бла ....
318
319 eeTestTime = (unsigned int) 1000 - uiReadTimer();
\ 0000000C 94F8 CLI
\ 0000000E 0192 MOVW R19:R18, R5:R4
\ 00000010 9478 SEI
\ 00000012 E000 LDI R16, 0
\ 00000014 2711 CLR R17
\ 00000016 E141 LDI R20, 17
\ 00000018 .... RCALL __eeput16_8
Компилятор просто обнуляет результат, и пишет нули, которые я и читаю. Причем, что новый, 8.10, что старый, 7.30. Вопрос: Что я делаю не так?
Если уровень оптимизации понизить до среднего, то всё ОК, читает таймер, грузит тысячу, отнимает, пишет в результат в епром:
317 // Бла-бла-бла ....
318
319 eeTestTime = (unsigned int) 1000 - uiReadTimer();
\ 0000000C 94F8 CLI
\ 0000000E 0192 MOVW R19:R18, R5:R4
\ 00000010 9478 SEI
\ 00000012 EE08 LDI R16, 232
\ 00000014 E013 LDI R17, 3
\ 00000016 1B02 SUB R16, R18
\ 00000018 0B13 SBC R17, R19
\ 0000001A E141 LDI R20, 17
\ 0000001C .... RCALL __eeput16_8
Может. я упускаю какой-то принципиальный момент? Где я ошибаюсь, понять не могу. Почему компилятор обнуляет результат при включеной оптимизации?
P.S. Про вариант "Отключай оптимизацию" я знаю, спасибо. Зачем тогда вобще IAR нужен :)))