PIC - таймер0 и прерывание для подсчета и мигания светодиода - PullRequest
0 голосов
/ 09 января 2019

Я использую PIC10F322 и timer0 с прерыванием, пытаюсь мигать светодиодом, включается в течение 1 с, а затем выключается в течение еще 1 с. Я пытался закодировать таймер, вызываемый для прерывания, и он работал хорошо. Но рассчитывать время не правильно. Подсчет был включен в течение примерно 2 с, а затем выключен в течение еще 2 с, что не является правильным. Интересно, что-то не так с расчетом? Чип составляет 16 МГц, таймер 0 равен 8 битам, а предварительный масштабатор установлен на 256. Моя попытка - запускать прерывание каждые 1 мс, а затем выполнить цикл 999, чтобы достичь 1 секунды.

Мой расчет:

256 - [(Delay * Fosc) / (prescaler*4)] = 256 - [(1ms * 16000000)/(256*4)] = 240


#define _XTAL_FREQ 16000000
#include <xc.h>

#pragma config FOSC = INTOSC    // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#pragma config LPBOR = ON      // Brown-out Reset Selection bits (BOR disabled)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)

int z = 0,count=0;
void main(void) {

    ANSELA = 0x00;

    TRISA = 0b0100;
    TRISAbits.TRISA2 = 1;
    LATAbits.LATA0 = 0;

    INTCONbits.GIE=1;       /* Enable Global Interrupt*/
    INTCONbits.PEIE = 1;  /* Enable peripheral Interrupt */

    OPTION_REGbits.T0CS = 0;

    OPTION_REGbits.PSA = 0; 
    OPTION_REGbits.PS0 = 1; /* set prescaler to 256 */
    OPTION_REGbits.PS1 = 1;
    OPTION_REGbits.PS2 = 1;
    OPTION_REGbits.INTEDG = 0;
    TMR0 = 240;
    INTCONbits.TMR0IF = 0;
    INTCONbits.TMR0IE = 1;

    while(1){
    }

   return; 
}


void __interrupt(high_priority) tcInt(void)
{

    if (TMR0IE && TMR0IF)
    {
        TMR0 = 240;
        TMR0IF = 0;

        if (count == 999)
        { 
            z = 0;
            LATAbits.LATA0 = ~LATAbits.LATA0;
            count =0;
        }
        count++;
    }

 return;
}

1 Ответ

0 голосов
/ 09 января 2019

Вы рассчитываете таймер в порядке, но я думаю, ваш микроконтроллер работает на частоте 8 МГц, которая является значением по умолчанию после сброса, если вы работаете с внутренним генератором (#pragma config FOSC = INTOSC). Если вам нравится 16 МГц, вам нужно было сделать выбор в регистре OSCCON.

OSCCON = 0b01110000;
...