定时器C语言
1、一般使用直接读入初值的定时器方式,采用查询方式的定时器中断,代码如下:
#include <reg51.h>
sbit P1_0=P1^0;//定义一个特殊功能寄存器的类变量
void main()
{
char i;
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
for(;;)
{
if (TF0)
{
TF0=0;
P1_0=!P1_0;
} //查询计数溢出
}
}
保存编译,没有错误,然后启动调试
打开端口Timer0,实时观察:
F10表示单步运行,程序运行时,端口也会发生变化,运行至TL0=0xFF时,再次运行,会发生如下变化:
TF0为高电平,进入死循环,此时打开p1端口,全速执行程序,p1.0会以500ms的速度不停的闪烁。
2、采用中断处理的程序:
#include <reg51.h>
sbit P1_0=P1^0;
void main()
{
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
EA=1;
ET0=1;
while(1);
}
void time0_int(void) interrupt 1 //中断服务程序
{
P1_0=!P1_0;
}
编译,调出Timer0,P0接口, 单步运行发现TL0运行至0xFF时,再运行,自动进入中断程序,全速执行程序,p1.0会以500ms的速度不停的闪烁
3、用某变量i对计数器溢出中断次数进行软件计数
#include <reg51.h>
sbit P1_1=P1^1;
char i;
void main()
{
TMOD=0x01;
TH0=0xD8;
TL0=0xf0;
TR0=1;
EA=1;
ET0=1;
i=0;
while(1);
}
void time0_int(void) interrupt 1 //中断服务程序
{
TH0=0xD8;
TL0=0xf0;
i++;
if(i==50){P1_1=!P1_1;i=0;}
}
定时器汇编
方式1,T0:
ORG 0000H //程序入口
RESET:AJMP MAIN //转主程序
ORG 000BH //T0中断入口
AJMP IT0P //转T0中断处理程序
ORG 0100H //主程序入口
MAIN:MOV SP,#60H //设置堆栈指针
MOV TMOD,#01H //设置T0为方式1定时
ACALL PT0M0 //调用初始化子程序PT0M0
HERE:AJMP HERE //原地等待
PT0M0:MOV TL0,#0F0H //T0初始化子程序,装入低八位
MOV TH0,#0FFH //装入计数初值高八位
SETB ET0 //允许T0中断
SETB EA //总中断允许
SETB TR0 //启动初值计数
RET
IT0P:MOV TL0,#0F0H //T0中断服务子程序,重新装入初值
MOV TH0,#0FFH
CPL P1.0 //P1.0的状态取反
RETI
运行时需要查看寄存去器和引脚:
方式2:
ORG 0000H
RESET:LJMP MAIN
ORG 000BH //T0的中断入口
LJMP IT0P
ORG 001BH //T1的中断入口
LJMP IT1P
ORG 0100H
MAIN:MOV SP,#60H //设置堆栈指针
ACALL PT0M2 //调用初始化子程序
LOOP:MOV C,F0 //P0脚的负跳是否发生变化,若发生变化,则F0置1
JNC LOOP //P0脚的负跳无变化,C=0,跳到LOOP等待
SETB ET1 //C=1,允许T1产生中断
SETB TR1 //启动T1计数
HERE:AJMP HERE
PT0M2:MOV TMOD,#25H //对T0,T1初始化,T0方式1计数,T1方式2定时
MOV TL0,#0FFH //T0设初值
MOV TH0,#0FFH
SETB ET0 //允许T0中断
MOV TL1,#06H //T1置500微秒中断初值
MOV TH1,#06H
CLR F0 //F0标志清零
SETB EA //打开总中断
SETB TR0 //启动T0计数
RET
IT0P:CLR TR0 //T0引脚发生跳变,停止T0
SETB F0 //把T0引脚已接受负脉冲标志F0置1,表示接受过负跳变,
RETI
IT1P:CPL P1.0 //T1中断服务程序,对P1.0取反
RETI