PIC - 定时器 0 和中断计数和闪烁 LED
PIC - timer0 and interrupt to count and blink LED
我正在使用带中断的 PIC10F322 和定时器 0,试图使 LED 闪烁,亮 1 秒,然后再灭 1 秒。我曾尝试对调用中断的计时器进行编码,并且效果很好。但是时间的计算是不正确的。计数开启约 2 秒,然后关闭另外 2 秒,这是不正确的。请问是不是计算有问题?芯片是16MHZ,timer0是8位,预分频器设置为256。我的尝试是每1ms触发一次中断,然后进行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;
}
你的定时器计算没问题,但我猜你的微控制器在 8 MHz 时是 运行,如果你使用内部振荡器 (#pragma config FOSC = INTOSC
),这是重置后的默认值。如果您喜欢 16 MHz,则必须在 OSCCON
寄存器中进行选择。
OSCCON = 0b01110000;
我正在使用带中断的 PIC10F322 和定时器 0,试图使 LED 闪烁,亮 1 秒,然后再灭 1 秒。我曾尝试对调用中断的计时器进行编码,并且效果很好。但是时间的计算是不正确的。计数开启约 2 秒,然后关闭另外 2 秒,这是不正确的。请问是不是计算有问题?芯片是16MHZ,timer0是8位,预分频器设置为256。我的尝试是每1ms触发一次中断,然后进行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;
}
你的定时器计算没问题,但我猜你的微控制器在 8 MHz 时是 运行,如果你使用内部振荡器 (#pragma config FOSC = INTOSC
),这是重置后的默认值。如果您喜欢 16 MHz,则必须在 OSCCON
寄存器中进行选择。
OSCCON = 0b01110000;