У меня своеобразная проблема с таймером на DSPIC33F. Мне нужно создать функцию задержки, и я решил использовать Таймер 2 для подсчета количества циклов команд. Функция включает таймер, а затем ждет в цикле while, ожидая установки флага прерывания. См. код ниже:
T2CONbits.TON = 0; // disable Timer 2
IFS0bits.T2IF = 0; // reset Timer 2 interrupt flag
TMR2 = 0; // reset timer accumulator
T2CONbits.TON = 1; // enable Timer 2
while(!IFS0bits.T2IF); // Wait until until the timer 2 timeout
IFS0bits.T2IF = 0; // reset Timer 2 interrupt flag
T2CONbits.TON = 0; // disable Timer 2
Функция отлично работает, если прерывания TMR2 отключены. Однако, если прерывания TMR2 разрешены, микропрограмма перезапускается при установке флага прерывания. Этот перезапуск происходит только тогда, когда я запускаю код, но не во время пошагового выполнения (я использую ICD3 с MPLab 8.something). Я не настраивал ISR для TMR2. Все остальные прерывания отключены.
Несмотря на то, что я достиг своей цели по созданию функции задержки, я все еще задаюсь вопросом о возможных причинах перезапуска прошивки. Это потому, что по какой-то причине я могу адресовать флаг прерывания только внутри ISR? Или есть какие-то другие причины?
На странице 2 справочника по семейству прерываний PIC33f показано, как работает процесс прерывания для dsPIC33f:
http://ww1.microchip.com/downloads/en/DeviceDoc/70300C.pdf
Когда вы разрешаете прерывание (например, T2IE) и прерывание срабатывает, оно переходит к ячейке адреса, найденной в периферийном векторе прерывания. если вы не определили юридический адрес для периферийного устройства, вектор прерывания периферийного устройства будет иметь неизвестный адрес (возможно, 0), и когда прерывание сработает, оно отправится по этому адресу, и могут произойти непредсказуемые вещи.
в вашем случае, предполагая, что бит ALTIVT (INTCON2<15>) очищен, когда срабатывает прерывание TMR2, оно переходит к адресу, найденному в 0x000022.
когда вы пишете:
void __attribute__((__interrupt__, auto_psv)) _T2Interrupt (void)
{
}
вы фактически сообщаете своему компилятору, что хотели бы разместить адрес начала этого кода по адресу 0x000022 (адрес TMR2 IVT)
и когда вы пишете:
void __attribute__((__interrupt__, auto_psv)) _AltT2Interrupt (void)
{
}
вы говорите своему компилятору разместить адрес начала этого кода по адресу 0x000122 (адрес TMR2 AIVT)
Адам Лоуренс
удушу
Адам Лоуренс