亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標(biāo)題:
51單片機(jī)基于一個定時器實現(xiàn)多個軟件定時器
[打印本頁]
作者:
lw1997
時間:
2019-11-2 23:31
標(biāo)題:
51單片機(jī)基于一個定時器實現(xiàn)多個軟件定時器
本帖最后由 lw1997 于 2019-11-2 23:33 編輯
軟件定時器是用程序模擬出來的定時器,可以由一個硬件定時器模擬出成千上萬個軟件定時器,這樣程序在需要使用較多定時器的時候就不會受限于硬件資源的不足,這是軟件定時器的一個優(yōu)點,即數(shù)量不受限制。但由于軟件定時器是通過程序?qū)崿F(xiàn)的,其運行和維護(hù)都需要耗費一定的CPU資源,同時精度也相對硬件定時器要差一些。在RTOS等操作系統(tǒng)中,都帶有軟件定時器,原理大同小異。典型的實現(xiàn)方法是:通過一個硬件定時器產(chǎn)生固定的時鐘節(jié)拍,每次硬件定時器中斷到,就對一個全局的時間標(biāo)記加一,每個軟件定時器都保存著到期時間,程序需要定期掃描所有運行中的軟件定時器,將各個到期時間與全局時鐘標(biāo)記做比較,以判斷對應(yīng)軟件定時器是否到期,到期則執(zhí)行相應(yīng)的回調(diào)函數(shù),并關(guān)閉該定時器
程序如下,通過一個硬件定時器產(chǎn)生固定的時鐘節(jié)拍,用4個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定時器flag
#define NULL 0
#define SOFT_TIMER_MAX 4 //定時器個數(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, //運行
SOFT_TIMER_TIMEOUT, //超時
SOFT_TIMER_WAITING //等待
} tmrState;
typedef struct softTimer {
unsigned char state; //狀態(tài)
unsigned char mode; //模式
unsigned int period; //定時周期
unsigned int count; //定時計數(shù)用
pFun callback; //定時器回調(diào)函數(shù)
} softTimer;
//定時器結(jié)構(gòu)數(shù)組
softTimer softTimerList[SOFT_TIMER_MAX] = {0};
//設(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;
}
//打開定時器
void softTimer_Start(unsigned int id)
{
softTimerList[id].state = SOFT_TIMER_RUNNING;
}
//停止定時器
void softTimer_Stop(unsigned int id)
{
softTimerList[id].state = SOFT_TIMER_STOPPED;
}
//清除定時器狀態(tài)(用于執(zhí)行事件后手動清除定時器狀態(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;
}
}
//獲取定時器狀態(tài)
unsigned char softTimer_GetState(unsigned int id)
{
return softTimerList[id].state;
}
void softTimer_Update(void) //更新定時器狀態(tài),在硬件定時器中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è)置定時器模式
TL0 = 0xC0; //設(shè)置定時初值
TH0 = 0xE0; //設(shè)置定時初值
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Interrupt() interrupt 1
{
TL0 = 0xC0; //重載定時初值
TH0 = 0xE0; //重載定時初值
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)定時器
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);
//打開相應(yīng)定時器
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();//初始化定時器0
while(1) {
//盡量少用延時,如果事件處理耗時較長,應(yīng)在main中執(zhí)行
if(softTimer_8s_flag == 1)
{
LED4=~LED4;
Delayms(200);//模擬耗時事件
softTimer_8s_flag = 0;
}
}
}
復(fù)制代碼
51hei截圖20191102225852.png
(56.18 KB, 下載次數(shù): 79)
下載附件
2019-11-2 23:32 上傳
程序及仿真:
51單片機(jī)軟件定時器測試.7z
(48.06 KB, 下載次數(shù): 109)
2019-11-2 23:23 上傳
點擊文件名下載附件
程序及
下載積分: 黑幣 -5
作者:
wulingqing
時間:
2019-11-3 11:17
這種想法好,謝謝樓主
作者:
1481714970
時間:
2019-11-3 20:29
想法很好,學(xué)到了學(xué)到了
作者:
jifengjianwu
時間:
2020-1-10 07:07
謝謝樓主分享,學(xué)習(xí)了。
作者:
hello1994
時間:
2020-1-22 11:30
怎么中定時器中斷中調(diào)用定時器更新函數(shù),這樣會導(dǎo)致定時不準(zhǔn)確。為什么不在主函數(shù)中調(diào)用?在定時器就是只更新計時變量。
作者:
hello1994
時間:
2020-1-22 11:36
如果采用在硬件定時器中斷中變量計數(shù)的這種形式,需要添加防止計時變量溢出措施。如:變量自動清零同時校驗延時時間是否超出定時范圍
作者:
13534702358
時間:
2020-3-21 11:14
好厲害的樣子!有點復(fù)雜了 看不是很懂
作者:
wjd801008
時間:
2020-10-27 08:54
謝謝分享,樓主辛苦了!
作者:
q651881054
時間:
2022-1-7 08:30
經(jīng)過壓力測試了么?
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1