STC11F04單片機(jī)定時器模擬多任務(wù)程序
由于本人用的是11.0592的晶體,所以時間上不是很精確。如果對定時有精確要求的,請用32.768M的晶振。
本文引用地址:http://m.butianyuan.cn/article/201611/318661.htm串口輸出采用 printf函數(shù)輸出。
#include"reg51.h"
#include "stdio.h"#include"intrins.h" //_nop_()
unsigned int tick;
int hh,mm,ss; //時:分:秒char putchar (unsigned char i)
{
ES = 0; //關(guān)串口中斷
TI = 0; //清零串口發(fā)送完成中斷請求標(biāo)志
SBUF = i;
while(TI ==0); //等待發(fā)送完成
TI = 0; //清零串口發(fā)送完成中斷請求標(biāo)志
ES = 1; //允許串口中斷
return SBUF;
}
void Task_1s()
{
printf("S=[%d:%d:%d]rn",hh,mm,ss);
}
void Task_1m()
{
printf("M=[%d:%d:%d]rn",hh,mm,ss);
}
void Task_1h()
{
printf("H=[%d:%d:%d]rn",hh,mm,ss);
}
//0.1ms = 100us
void Timer0(void) interrupt 1 using 1//定時器0中斷外理
{
TR0=0;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
tick++; //計數(shù)值+1
if(tick>999) //加到10次即1秒
{
tick=0;
ss++;
if(ss>59){
mm++;
ss=0;
if(mm>59){
hh++;
mm=0;
if(hh>11){
hh=0;
}
Task_1h();//1小時定時任務(wù)
}
Task_1m(); //1分鐘定時任務(wù)
}
Task_1s();//1s定時任務(wù)
}
TR0=1;
}
void main()
{
SCON=0x50;//0101,0000 8位可變波特率,無奇偶校驗(yàn)位
TMOD=0X21;
TH1=TL1=-(11059200L/12/32/9600);
TR1=1;
tick=0;
hh=0;
mm=0;
ss=0;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
TR0=1;
ET0=1;
ES=1; //允許串口中斷
EA=1; //開總中斷
printf("SystemStart...rn");
while(1)
{
_nop_();
}
}
程序運(yùn)行后結(jié)果如圖:
代碼詳解:
(1)串口波特率計算
TH1=TL1=-(11059200L/12/32/9600);
由于采用11.0592晶振,所以這里是11059200L
由于采用9600波特率和計算機(jī)通信,所以采用9600
(2)串口輸出為什么可以用“printf"函數(shù)?
例如: printf("S=[%d:%d:%d]rn",hh,mm,ss); 可以很方便的輸出要的數(shù)據(jù)
原因是要自己實(shí)現(xiàn)printf的底層通信代碼,即在你的代碼里加入
這個函數(shù)的原型定義在:#include "stdio.h" 里,感興趣的朋友,還可以把其他函數(shù)也實(shí)現(xiàn)。這樣C51編程就可以和計算機(jī)上的C語言編程類似了。
(3)定時器初值說明:
TH0=(65536-2000)/256; 高8位
TL0=(65536-2000)%256; 低8位
(4) 定時任務(wù)
任務(wù)的調(diào)用在定時器中斷里,詳細(xì)見定時器中斷。
void Timer0(void) interrupt 1 using 1//定時器0中斷外理
希望對大家有用!錯誤在所難免,諸位看官自己調(diào)試把
評論