注意:本人刚学C18,不能保证程序没有错误!
#include <p18cxxx.h>
#pragma config WDT = OFF
void timer0(void);
#pragma code timer_interrupt = 0x08 //把GOTO指令放在高优先级中断向量处
void timer_interrupt(void)
{
_asm //通过汇编的GOTO指令跳转到中断服务程序
//C语言里的goto只在函数内部有效
goto timer0
_endasm
}
#pragma code //切换回普通代码段
volatile unsigned char counter = 0; //有可能中断函数和普通程序都要用的变量要
//用volatile声明,以使编译器不对其进行优化
#pragma interrupt timer0
void timer0(void)
{
INTCONbits.T0IF = 0; //清除T0中断标志,必须操作
TMR0H = 0x3c; //重置定时器初值,这里也是要先TMR0H再L
TMR0L = 0xb0;
counter++;
}
void main(void)
{
//INTCONbits.PEIE = 0;
//RCONbits.IPEN = 1;
INTCONbits.T0IF = 0; //与INTCONbits.TMR0IF = 0;等价,清除T0中断标志
T0CONbits.T08BIT = 0; //设定T0为16位模式
T0CONbits.T0CS = 0; //选择内部指令时钟为时钟源,也是定时器计数器选
//择位,0即为定时器
T0CONbits.PSA = 1; //选择不使用分频器
TMR0H = 0x3c; //设定T0的定时初值,这里因为外部时钟设定为
//4MHz,PIC单片机的机器周期为4个时钟周期,即
//1μs,定时器定时时间为(0xFFFF-0x3CB0+1)*1μs=
//50ms
TMR0L = 0xb0; //注意,必须先定义TMR0H,再定义TMR0L。
INTCONbits.T0IE = 1; //与INTCONbits.TMR0IE = 1;等价,打开定时器中断
INTCONbits.GIE = 1; //打开全局中断使能
T0CONbits.TMR0ON = 1; //打开T0
while(1);
}
结果:
定时器溢出产生中断3次后,运行时间为150.180000ms
关于需要先定义TMR0H再定义TMR0L:
TMR0H只是Timer0高字节的缓存,在写入TMR0L时才会写入。这样是能一次读取Timer0的所有位,防止在读取低字节时高字节有变化。
参考资料:MPLAB C18 C编译器用户指南,PIC18Fxx2数据手册
文章评论(0条评论)
登录后参与讨论