定时/计数器(定时和计数的功能)、定时器中断
生活随笔
收集整理的這篇文章主要介紹了
定时/计数器(定时和计数的功能)、定时器中断
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
定時/計數器實現功能:
(1)定時功能:
定時/計數器說明(最高單次計時時間是71毫秒=65535*1.085us,1.085us是機器周期):
使用51定時/計數器步驟:
定時/計算器控制寄存器:
設置定時寄存器的工作模式:
將想計時的時間(這個時間意思是想讓定時/計數器經過多長時間溢出,溢出后就說明達到了你設定的時間)轉化為微秒級(50毫秒=50000微妙)再用轉化后的數除以1.085(機器周期時間)得到的數就是要加的次數 ,定時/計數器總共加65535次就會溢出,提前有一個初始值就可減少達到溢出的的次數。
例子:想50毫秒后定時/計數器溢出,50毫秒=50000微妙
(第一種方式)50000除以1.085得到46082(次),然后就可以將高八位TH0=46082/256(意思是有多少個256放入高八位中),低八位TL0=46082%256(意思是將剩余的256放到低八位中)。
(第二種方式)也可以用65535減46082得到初值,再將十進制初值轉化為十六進制,將前兩位給TH0后兩位給TL0
計時器代碼示例
#include<reg52.h> #include<intrins.h>#define uint unsigned int #define uchar unsigned charsbit beep=P2^3; sbit DUAN =P2^6;//數碼管段選 sbit WEI=P2^7; //數碼管位選 uchar temp; //共陰極數碼管段選表0——9,code表示數組中的數據在程序執行過程中不能被修改 //加code存放的是ROM區不加code存放的是RAM區 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void delay(void) //誤差 -0.000000000001us {unsigned char a,b;for(b=15;b>0;b--)for(a=152;a>0;a--); } void display(uint i) { uint bai,shi,ge;bai=i/100;shi=i%100/10;ge=i%10;P0=0xff;//清除斷碼WEI=1;//打開位選鎖存器P0 = 0xfe;//1111 1110 給第一個數碼管接地,讓它工作WEI =0;//關閉位選鎖存器,進行段選(顯示數字)DUAN=1;//打開段選鎖存器P0 =table[bai];DUAN =0;//鎖存段選鎖存器delay();P0=0xff;//清除斷碼WEI=1;P0 = 0xfd;WEI =0;DUAN=1;P0 = table[shi];DUAN =0;delay();P0=0xff;//清除斷碼WEI=1;P0 = 0xfb;WEI =0;DUAN=1;P0 = table[ge];DUAN =0; delay(); } //定時器0初始化 void timeInit() {TR0=1;//啟動定時器0TMOD=0x01;//定時器工作模式一,16位定時計時模式//TH0=0x4b;//TL0=0xfd;//定時50毫秒;TH0=(65535-46082)/256;TL0=(65535-46082)%256;//定時50毫秒; }void main() {uchar msec,sec;//聲明毫秒和秒儲存變量timeInit();while(1){if(TF0==1){TF0=0;//軟件清0溢出標志位TH0=0x4b;TL0=0xfd;//重放初值msec++;//50毫秒到if(msec==20){msec=0;sec++;//一秒時間到if(sec>100)sec=0;//計時到100秒從1開始 } }display(sec); //數碼管顯示時間} }(2)計數功能:
#include<reg52.h> #include<intrins.h>#define uint unsigned int #define uchar unsigned charsbit DUAN =P2^6;//數碼管段選 sbit WEI=P2^7; //數碼管位選 sbit LED1=P1^0; uchar temp; //共陰極數碼管段選表0——9,code表示數組中的數據在程序執行過程中不能被修改 //加code存放的是ROM區不加code存放的是RAM區 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void delay(void) //誤差 -0.000000000001us {unsigned char a,b;for(b=15;b>0;b--)for(a=152;a>0;a--); } void display(uint i) { uint bai,shi,ge;bai=i/100;shi=i%100/10;ge=i%10;P0=0xff;//清除斷碼WEI=1;//打開位選鎖存器P0 = 0xfe;//1111 1110 給第一個數碼管接地,讓它工作WEI =0;//關閉位選鎖存器,進行段選(顯示數字)DUAN=1;//打開段選鎖存器P0 =table[bai];DUAN =0;//鎖存段選鎖存器delay();P0=0xff;//清除斷碼WEI=1;P0 = 0xfd;WEI =0;DUAN=1;P0 = table[shi];DUAN =0;delay();P0=0xff;//清除斷碼WEI=1;P0 = 0xfb;WEI =0;DUAN=1;P0 = table[ge];DUAN =0; delay(); } //計數器0初始化 void jishuInit() {TR0=1;//啟動計數器0TMOD|=0x05;//定時器工作模式一,16位計數模式TH0=0;TL0=0; } //定時器1初始化 void timeInit() {TR1= 1;//啟動定時器1TMOD|=0x10;//定時器工作模式一,16位定時模式TH1=0x4b;TL1=0xfd; }void main() {uchar msec;//聲明毫秒和秒儲存變量jishuInit();//計數器0初始化timeInit();//定時器1初始化while(1){if(TF1==1){TF1=0;//軟件清0溢出標志位TH1=0x4b;TL1=0xfd;//重放初值msec++;//50毫秒到if(msec==10)//定時500毫秒到{msec=0;LED1=~LED1;//產生方波}}display(TL0); //數碼管顯示時間} }定時器中斷
中斷情況下TF由硬件清0,若無中斷則有軟件清0。
代碼示例:
定時器中斷進行數碼管動態掃描:
#include <reg52.h> #include <intrins.h>#define uint unsigned int #define uchar unsigned charsbit DU = P2^6;//數碼管段選 sbit WE = P2^7;//數碼管位選 sbit key_s2 = P3^0;//獨立按鍵S2 sbit key_s3 = P3^1;//獨立按鍵S3 uchar num;//數碼管顯示的值//共陰數碼管段選表 uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,}; //數碼管位選碼 uchar code SMGwei[] = {0xfe, 0xfd, 0xfb}; //毫秒級延時函數定義 void delay(uint z) {uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--); } void display(uchar i) {static uchar wei; P0 = 0XFF;//清除斷碼WE = 1;//打開位選寄存器P0 = SMGwei[wei];WE = 0;//鎖存位選寄存器switch(wei){case 0: DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;case 1: DU = 1; P0 = SMGduan[i % 100 / 10]; DU = 0; break; case 2: DU = 1; P0 = SMGduan[i % 10]; DU = 0; break; }wei++;if(wei == 3)wei = 0; } //定時器0初始化 void timer0Init() {EA = 1; //打開總中斷ET0 = 1;//打開定時器0中斷TR0 = 1; //啟動定時器0TMOD = 0X01; //定時器工作模式,16位定時模式TH0 = 0xED;TL0 = 0xFF; //定時5ms }void main()//main函數自身會循環 { timer0Init();//?¨ê±?÷03?ê??ˉwhile(1){if(key_s2 == 0)//判斷S2是否被按下{delay(20);//按鍵消抖if(key_s2 == 0){if(num != 120)num++;while(!key_s2);//松手檢測} }if(key_s3 == 0)//判斷S3是否被按下{delay(20);//按鍵消抖if(key_s3 == 0){if(num > 0)num--;while(!key_s3);//松手檢測} }} } //定時器中斷函數 void timer0() interrupt 1 {TH0 = 0xED;TL0 = 0xFF; //定時5msdisplay(num); //數碼管顯示函數 }總結
以上是生活随笔為你收集整理的定时/计数器(定时和计数的功能)、定时器中断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中断系统详解、外部中断
- 下一篇: 51单片机—串口通信