Недавно начал писАть под ATMega128 на IAR C v.2.28a. Вот посмотрел на сгенерированный ассемблерный код - объясните (+)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Помогите начинающему 18 марта 2004 г. 15:55

У меня есть обработчик прерывания TIMER1_COMPA_vect - на нем я инкрементирую переменную
unsigned long ti_cnt ;
Этот обработчик разрешается где-то в фоне.
Ну и иногда я в фоне должен взять значение этого счетчика (я беру его в начале процесса, затем в конце процесса, вычитаю и получаю время процесса).
Естественно, когда я его просто буду переписывать, то в это время может произойти прерывание в котором изменяется значение счетчика и я могу получить неправильное значение (пару байтов - новое, пару - старое). Для того, чтобы этого избежать, есть два метода - один это считывать подряд значения, пока они станут одинаковыми. А быстрее и тупее - запретить это прерывание прочитать и разрешить. Именно это я и хочу сделать. Вот функция, которая берет текущее значение счетчика :

unsigned long get_10ms_counter( void) {
unsigned long l ;

if( TIMSK & 0x10) { // разрешены прер-ния по таймеру 1
TIMSK &= ~0x10 ; // запретим
l = t1_cnt ; // прочитаем
TIMSK |= 0x10 ; // разрешим
return l; // выходим
}
// а здесь и так таймер не запущен
return t1_cnt ;
}

А вот ассемблер :
; 282 unsigned long get_10ms_counter( void) {
; 283 unsigned long l ;
; 284
; 285 if( TIMSK & 0x10) {
; __nearfunc unsigned long get_10ms_counter();
get_10ms_counter:
IN R16,0x37
MOV R17,R16
SBRS R17,4
RJMP ??get_10ms_counter_0
; 286 TIMSK &= ~0x10 ; // § ЇаҐвЁ¬
IN R16,0x37
ANDI R16,0xEF
OUT 0x37,R16
; 287 l = t1_cnt ; // Їа®зЁв Ґ¬
; 288 TIMSK |= 0x10 ; // а §аҐиЁ¬
IN R16,0x37
ORI R16,0x10
OUT 0x37,R16
; 289 return l;
LDI R30,LOW(t1_cnt)
LDI R31,(t1_cnt) >> 8
LD R16,Z
LDD R17,Z+1
LDD R18,Z+2
LDD R19,Z+3
RET
; 290 }

По-моему, код не корректен - запрещаются прерывания по таймеру, затем разрешаются, а значение берется уже при работающем таймере!
Не ошибаюсь ли я ? А то я еще не разбирался в Си от ИАР и не знаю как оно возвращает значения, через какие регистры и т. д.
Объясните !

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

Ответы



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

E-mail: info@telesys.ru