Таймер 1 на PIC24F16KA102 не работает

Я хочу настроить timer1 для PIC24F16KA102 для его подсчета. Источником синхронизации должен быть внутренний тактовый генератор 8 МГц. Я настроил регистр T1CON и установил на высокий уровень бит TON для запуска таймера. Timer1 настроен на переполнение каждые 100 мкс, а затем с циклом while я увеличу счетчик переменных. Я не понимаю, потому что timer1 не работает, я заметил, что он не увеличивается. Зачем?

   #include <xc.h>
   #include "config.h"

   int count = 0;

   void main(void) {

        TRISB = 0;    

        T1CON = 0;      //TRM1 stopped, internal clock source, prescaler 1:1

        _TON = 1;
        TMR1 = 65135;   //overflow of TM1 every 100 us (400 counts)

        while (1) {

             if (TMR1 == 65535) {

             count++;       // increase every 100 us
             TMR1 = 65135;

             }

        }
   }

1 ответ

Попробуйте установить регистр периода Таймера 1 (PR1) и использовать прерывание, а не пытаться перехватить и перезагрузить TMR1 по его окончательному счету. Вы пытаетесь поймать TMR1 на ТОЧНО 65535, и это почти никогда не сработает, потому что, как только TMR1 достигнет 65535, он просто переполнится и снова начнет считать с 0.РЕДАКТИРОВАТЬ: Конечно, это предполагает, что это имеет значение вообще. Я не знаю, каково поведение таймера, когда вы покидаете регистр периодов в 0. Он может просто сосчитать до максимума 65535, затем сброситься до 0, или он может вообще никогда не сосчитаться и постоянно загружать PRx в TMRx, так как они соответствует 0

PRx предназначен для определения периода, который вы хотите для данного таймера, в данном случае 100 мкс. PR1 = 400. Как только TMR1 = PR1, таймер автоматически перезагрузится и вызовет прерывание, чтобы предупредить вас, что таймер истек.

volatile unsigned int count = 0;   //Vars that change in an ISR should be volatile
PR1 = 400;          //Set Period for Timer1 (100us)
T1CON = 0x8000;     //Enable Timer1

IEC0bits.T1IE = 1;      //Enable Timer1 Interrupt
IPC0bits.T1IP = 0b011;  

Соедините это с функцией ISR, чтобы увеличить счетчик всякий раз, когда таймер истекает:

void __attribute__ ((interrupt,no_auto_psv)) _T1Interrupt (void)
{
 count++;
 IFS0bits.T1IF = 0;  //Make sure to clear the interrupt flag
}

Вы также можете попробовать что-то вроде этого без каких-либо прерываний:

void main(void){
unsigned int count = 0;
TMR1 = 0;
T1CON = 0x8000;   //TON = 1

    while(1){
         if (TMR1 >= 400){
          count++;
          TMR1=0;
         }
    }
}

Однако я бы порекомендовал использовать регистр PR и ISR. Это то, что он должен делать.

РЕДАКТИРОВАТЬ: Я также рекомендовал бы прочитать Справочное руководство PIC24F на таймеры: здесь

Другие вопросы по тегам