|
本帖最后由 lw1997 于 2019-11-2 23:33 編輯
軟件定時(shí)器是用程序模擬出來(lái)的定時(shí)器,可以由一個(gè)硬件定時(shí)器模擬出成千上萬(wàn)個(gè)軟件定時(shí)器,這樣程序在需要使用較多定時(shí)器的時(shí)候就不會(huì)受限于硬件資源的不足,這是軟件定時(shí)器的一個(gè)優(yōu)點(diǎn),即數(shù)量不受限制。但由于軟件定時(shí)器是通過(guò)程序?qū)崿F(xiàn)的,其運(yùn)行和維護(hù)都需要耗費(fèi)一定的CPU資源,同時(shí)精度也相對(duì)硬件定時(shí)器要差一些。在RTOS等操作系統(tǒng)中,都帶有軟件定時(shí)器,原理大同小異。典型的實(shí)現(xiàn)方法是:通過(guò)一個(gè)硬件定時(shí)器產(chǎn)生固定的時(shí)鐘節(jié)拍,每次硬件定時(shí)器中斷到,就對(duì)一個(gè)全局的時(shí)間標(biāo)記加一,每個(gè)軟件定時(shí)器都保存著到期時(shí)間,程序需要定期掃描所有運(yùn)行中的軟件定時(shí)器,將各個(gè)到期時(shí)間與全局時(shí)鐘標(biāo)記做比較,以判斷對(duì)應(yīng)軟件定時(shí)器是否到期,到期則執(zhí)行相應(yīng)的回調(diào)函數(shù),并關(guān)閉該定時(shí)器
程序如下,通過(guò)一個(gè)硬件定時(shí)器產(chǎn)生固定的時(shí)鐘節(jié)拍,用4個(gè)LED演示效果:
- #include "reg51.h"
- //#include "STC89C5xRC.h"
- sbit LED1=P1^0;
- sbit LED2=P1^1;
- sbit LED3=P1^2;
- sbit LED4=P1^3;
- unsigned char softTimer_8s_flag = 0; //8s定時(shí)器flag
- #define NULL 0
- #define SOFT_TIMER_MAX 4 //定時(shí)器個(gè)數(shù)
- //定義定時(shí)器ID
- #define ID_1S_LED_TASK 0
- #define ID_2S_LED_TASK 1
- #define ID_4S_LED_TASK 2
- #define ID_8S_LED_TASK 3
- typedef void (*pFun)(void); //callback 函數(shù)指針類型
- typedef enum tmrMode {
- MODE_ONE_SHOT = 0, //單次模式
- MODE_PERIODIC, //周期模式
- } tmrMode;
- typedef enum tmrState {
- SOFT_TIMER_STOPPED = 0, //停止
- SOFT_TIMER_RUNNING, //運(yùn)行
- SOFT_TIMER_TIMEOUT, //超時(shí)
- SOFT_TIMER_WAITING //等待
- } tmrState;
- typedef struct softTimer {
- unsigned char state; //狀態(tài)
- unsigned char mode; //模式
- unsigned int period; //定時(shí)周期
- unsigned int count; //定時(shí)計(jì)數(shù)用
- pFun callback; //定時(shí)器回調(diào)函數(shù)
- } softTimer;
- //定時(shí)器結(jié)構(gòu)數(shù)組
- softTimer softTimerList[SOFT_TIMER_MAX] = {0};
- //設(shè)定定時(shí)器
- void softTimer_Creat(unsigned char id,tmrMode mode,unsigned int interval,pFun cb)
- {
- softTimerList[id].mode = mode;
- softTimerList[id].period = interval;
- softTimerList[id].count = 0;
- softTimerList[id].callback = cb;
- softTimerList[id].state = SOFT_TIMER_STOPPED;
- }
- //打開(kāi)定時(shí)器
- void softTimer_Start(unsigned int id)
- {
- softTimerList[id].state = SOFT_TIMER_RUNNING;
- }
- //停止定時(shí)器
- void softTimer_Stop(unsigned int id)
- {
- softTimerList[id].state = SOFT_TIMER_STOPPED;
- }
- //清除定時(shí)器狀態(tài)(用于執(zhí)行事件后手動(dòng)清除定時(shí)器狀態(tài))
- void softTimer_Clr(unsigned int id)
- {
- if(softTimerList[id].mode == MODE_ONE_SHOT){
- softTimerList[id].state = SOFT_TIMER_STOPPED;
- }else{
- softTimerList[id].state = SOFT_TIMER_RUNNING;
- }
- }
- //獲取定時(shí)器狀態(tài)
- unsigned char softTimer_GetState(unsigned int id)
- {
- return softTimerList[id].state;
- }
- void softTimer_Update(void) //更新定時(shí)器狀態(tài),在硬件定時(shí)器中1ms調(diào)用一次
- {
- unsigned char id;
- for(id = 0 ;id <= SOFT_TIMER_MAX ; id++ ){
- switch (softTimerList[id].state){
- case SOFT_TIMER_STOPPED:
- break;
- case SOFT_TIMER_RUNNING:
- if(softTimerList[id].count < softTimerList[id].period){
- softTimerList[id].count ++;
- }else{
- softTimerList[id].count = 0;
- softTimerList[id].state = SOFT_TIMER_TIMEOUT;
- softTimerList[id].callback();
- }
- break;
- case SOFT_TIMER_TIMEOUT:
- if(softTimerList[id].mode == MODE_ONE_SHOT) {
- softTimerList[id].state = SOFT_TIMER_STOPPED;
- } else {
- softTimerList[id].count ++;
- softTimerList[id].state = SOFT_TIMER_RUNNING;
- }
- break;
- default: //state error
- break;
- }
- }
- }
- void Timer0Init(void) //1毫秒@12.000MHz
- {
- TMOD = 0x00; //設(shè)置定時(shí)器模式
- TL0 = 0xC0; //設(shè)置定時(shí)初值
- TH0 = 0xE0; //設(shè)置定時(shí)初值
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- }
- void Interrupt() interrupt 1
- {
- TL0 = 0xC0; //重載定時(shí)初值
- TH0 = 0xE0; //重載定時(shí)初值
-
- softTimer_Update(); //1ms更新一次softTimer
- }
- void Delayms(unsigned int ms) //@12.000MHz
- {
- unsigned char i, j;
- while(--ms) {
- i = 2;
- j = 239;
- do {
- while (--j);
- } while (--i);
- }
- }
- void softTimer_1s_cb(void)
- {
- LED1 = ~LED1;
- }
- void softTimer_2s_cb(void)
- {
- LED2 = ~LED2;
- }
- void softTimer_4s_cb(void)
- {
- LED3 = ~LED3;
- }
- void softTimer_8s_cb(void)
- {
- softTimer_8s_flag = 1;
- }
- void main() //主函數(shù)
- {
- LED1=0;LED2=0;LED3=0;LED4=0;
-
- //配置相應(yīng)定時(shí)器
- softTimer_Creat(ID_1S_LED_TASK,MODE_PERIODIC,1000,softTimer_1s_cb);
- softTimer_Creat(ID_2S_LED_TASK,MODE_PERIODIC,2000,softTimer_2s_cb);
- softTimer_Creat(ID_4S_LED_TASK,MODE_ONE_SHOT,4000,softTimer_4s_cb);
- softTimer_Creat(ID_8S_LED_TASK,MODE_PERIODIC,8000,softTimer_8s_cb);
-
- //打開(kāi)相應(yīng)定時(shí)器
- softTimer_Start(ID_1S_LED_TASK);
- softTimer_Start(ID_2S_LED_TASK);
- softTimer_Start(ID_4S_LED_TASK);
- softTimer_Start(ID_8S_LED_TASK);
-
- Timer0Init();//初始化定時(shí)器0
- while(1) {
-
- //盡量少用延時(shí),如果事件處理耗時(shí)較長(zhǎng),應(yīng)在main中執(zhí)行
- if(softTimer_8s_flag == 1)
- {
- LED4=~LED4;
- Delayms(200);//模擬耗時(shí)事件
- softTimer_8s_flag = 0;
- }
- }
- }
復(fù)制代碼
51hei截圖20191102225852.png (56.18 KB, 下載次數(shù): 79)
下載附件
2019-11-2 23:32 上傳
程序及仿真:
51單片機(jī)軟件定時(shí)器測(cè)試.7z
(48.06 KB, 下載次數(shù): 109)
2019-11-2 23:23 上傳
點(diǎn)擊文件名下載附件
程序及 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|