#include
sbit D1=P1^0; //将D1位定义为P1.0引脚 sbit D2=P1^1; //将D2位定义为P1.1引脚 sbit D3=P1^2; //将D3位定义为P1.2引脚
unsigned char Countor1; //设置全局变量,储存定时器T1中断次数 unsigned int Countor2; //设置全局变量,储存定时器T1中断次数
unsigned long int Countor3; //设置全局变量,储存定时器T1中断次数 void main(void) {
EA=1; //开总中断
ET1=1; //定时器T1中断允许
TMOD=0x10; //使用定时器T1的模式1 TH1=0xd8; //定时器T1的高8位赋初值 TL1=0xf0; //定时器T1的低8位赋初值 TR1=1; //启动定时器T1
Countor1=0; //从0开始累计中断次数 Countor2=0; //从0开始累计中断次数 Countor3=0; //从0开始累计中断次数 while(1) ; //无限循环等待中断 }
/************************************************************** 函数功能:定时器T1的中断服务程序
**************************************************************/ void Time1(void) interrupt 3 using 0//“interrupt”声明函数为中断服务函数 //其后的3为定时器T1的中断编号; {
Countor1++; //Countor1自加1 Countor2++; //Countor2自加1 Countor3++; //Countor3自加1
if(Countor1==100) //计时满1s {
D1=~D1; //按位取反操作,将P1.0引脚输出电平取反 Countor1=0; //将Countor1清0,重新从0开始计数 }
if(Countor2==6000) //计时满1分钟 {
D2=~D2; Countor2=0; }
if(Countor3==360000) //计时满1小时 {
D3=~D3;
Countor3=0; }
TH1=0xd8; //定时器T1的高8位重新赋初值 TL1=0xf0; //定时器T1的低8位重新赋初值 }
写了c程序之后在proteus仿真运行发现灯取反的时间有误差,特别是每小时取反一次的那个灯误差更大,查了单片机定时误差的分析,得知用汇编语言写的程序误差很小,因而继续写了汇编语言的程序如下: ORG 0000H AJMP MAIN ORG 000BH LJMP TOINT ORG 0030H
MAIN: MOV TMOD,#01H MOV TH0,#0D8H MOV TL0,#0F0H
MOV IE,#82H SETB TR0 MOV 40H ,#64H MOV 41H,#3CH MOV 42H,#3CH CLR 4DH CLR 4EH CLR 4FH TT0: JNB 4DH,TT0 CLR 4DH CPL P1.0 JNB 4EH,TT0 CLR 4EH CPL P1.1 JNB 4FH,TT0 CLR 4FH CPL P1.2 AJMP TT0 TOINT: MOV TH0,#0D8H MOV TL0,#0F0H DJNZ 40H,NEXT MOV 40H,#64H SETB 4DH DJNZ 41H,NEXT MOV 41H,#3CH SETB 4EH DJNZ 42H,NEXT
;设定T0为方式1
;装入定时器常数高8位 ;装入定时器常数低8位 T0中断 T0
;设置软件计数器 ;设置软件计数器 ;设置软件计数器 ;标志位清零 ;标志位清零 ;标志位清零
;1秒钟未到(4DH=0)等 ;1秒钟到,清标志位4DH ;每1秒钟取反一次
;1分钟未到(4EH=0)等 ;1分钟到,清标志位4EH ;每1分钟取反一次 ;1小时未到(4FH=0)等 ;1小时到,清标志位4FH ;每1小时取反一次 ;循环
;定时器重赋值 ;1s到否,没到转 ;1s到,再赋64H ;置1s标志位 ;1min到否,没到转 ;1min到,再赋3CH ;置1min标志位 ;1h到否,没到转
;开放 ;启动
MOV 42H,#3CH ;1h到,再赋3CH SETB 4FH ;置1h标志位
NEXT: RETI END
相关推荐: