Прерывание таймера PSoC

Мне кажется, что у меня прерывание по таймеру работает некорректно. Проблема в том, что счетчик внутри функции прерывания увеличивается только один раз. Вот мой код из основных настроек и настроек таймера.

#include <m8c.h>
#include "PSoCAPI.h"
#include <stdio.h>
#include <stdlib.h>

char theStr[] = "PSoC LCD";
static char tmp[3];
static int counter = 0;

void main(void){

    LCD_Start();
    LCD_Position(0,5);
    LCD_PrString(theStr);
    M8C_EnableGInt;
    Timer8_EnableInt();
    Timer8_Start();
    while (1);
}

#pragma interrupt_handler myTimerInt
void myTimerInt(void){
    counter ++;
    LCD_Position(1,0);
    itoa(tmp, counter, 10);
    LCD_PrString(tmp);
}

person mikedanylov    schedule 30.03.2014    source источник
comment
Дело в том, что обработчики прерываний должны быть небольшими, быстрыми и особенно не вызывать вложенных прерываний.   -  person Some programmer dude    schedule 30.03.2014
comment
@JoachimPileborg - да, «LCD_Position» не звучит как то, что я бы вызывал из обработчика прерываний.   -  person Martin James    schedule 30.03.2014
comment
Действительно, печать на ЖК-дисплее может занять немного времени. Как часто таймер прерывает огонь? Начнет ли код работать, если частота прерываний таймера резко уменьшится?   -  person Chris Stratton    schedule 02.04.2014
comment
Проблема решена! Спасибо за комментарии.   -  person mikedanylov    schedule 04.04.2014


Ответы (2)


Большинству подпрограмм обслуживания прерываний необходимо повторно активировать прерывание (иногда называемое «подтверждением прерывания»), которое его вызвало. В противном случае ISR вызывается только один раз. Обычно это делается после завершения критической части ISR.

В случае с 503418, я думаю, повторное включение выполняется чтением регистра счетчика. См. код внизу этого.

person wallyk    schedule 02.04.2014
comment
Правильно, прерывание вызывалось только один раз. Упрощено использование только флага, и теперь это работает. Спасибо. - person mikedanylov; 25.04.2014

Возможная проблема, с которой вы можете столкнуться, — неправильно сконфигурированная процедура обслуживания прерывания в Timer8INT.asm. При использовании директивы #pragma interrupt_handler вам нужно убедиться, что вы используете правильную инструкцию для вызова подпрограммы обслуживания прерывания C в ISR Timer8INT.asm.

Если эта директива определена, в конец этой функции будет добавлена ​​инструкция reti, что неверно, если вы используете lcall для вызова этой функции C из вашего Timer8INT.asm. В этом случае вам действительно нужна простая инструкция ljmp для этой функции C.

При использовании директивы #pragma interrupt_handler Timer8INT.asm должен иметь

_Timer8_ISR:

    ljmp _myTimerInt

    reti

Без директивы #pragma interrupt_handler Timer8INT.asm должен иметь

_Timer8_ISR:

    PRESERVE_CPU_CONTEXT
    lcall _myTimerInt
    RESTORE_CPU_CONTEXT

    reti
person Community    schedule 02.04.2014