ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
21 декабря
1321992
vpv.vpv (20.06.2023 09:07, просмотров: 2630)
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 нужен :)))