【單片機(jī)到嵌入式之路】序列之3:苦逼的CPU
軟件平臺
本文引用地址:http://www.ex-cimer.com/article/274193.htm硬件平臺:單片機(jī)
編譯環(huán)境:keil
二、苦逼的CPU
【事故起因】:單片機(jī)是單核的,所以在做多線程問題的時候,我們要考慮的太多。但是大部分人都會讓單片機(jī)一直工作,比如while死循環(huán),然后就抱怨單片機(jī)太簡單了,只能點(diǎn)燈,其它的事情就不行了。
【現(xiàn)場分析】:1.單片機(jī)是單核的;
2.做多線程,方法兩種:a.上操作系統(tǒng),b.仿操作系統(tǒng);
3.自己想釋放單片機(jī)的CPU,但是格局有限,就怪單片機(jī);
4.要想馬兒跑,必須給馬兒吃草。要想單片機(jī)多工作,必須優(yōu)化代碼,多下功夫。
【案例列舉】:單燈閃爍
void main(void)
{
LED_Init(); //LED初始化
while(1)
{
LED = ON; //LED亮
Delay_Ms(1000); //延時1s
LED = OFF; //LED滅
Delay_Ms(1000); //延時1s
}
}
【案例分析】:單燈閃爍分析
聲明幾點(diǎn):1.如果你只用單片機(jī)作為單燈閃爍,那么單片機(jī)就完全可以;
2.如果你不想玩那么高級,那么單機(jī)這樣也是OK的;
3.如果你想玩高級的,那么肯定不行。
分析:咋一看,程序沒有什么問題,但是暗藏玄機(jī)。
1.程序被死循環(huán)卡死;
2.死循環(huán)里面就是一個產(chǎn)生2s周期的頻率,那么燈就是2s閃爍一次;
3.單片機(jī)就這樣被你“征服”了。但是你這是把單片機(jī)浪費(fèi)了。
這是單片機(jī)CPU的苦啊,他是沒有口啊,有口要罵人的哦!O(∩_∩)O哈哈~
三、單片機(jī)CPU的苦衷——請釋放CPU
1.硬件電路分析
用上面的電路來做分析,當(dāng)P1口為低電平的時候,LED燈才亮,高電平則滅。
1.軟件分析
由硬件可以知道,我們可以通過宏定義來對接口進(jìn)行簡單的定義
#define LED_Light P1 //LED燈端口
#define LED_ON() LED_Light = 0x00 //LED燈亮
#define LED_OFF() LED_Light = 0xFF //LED燈滅
現(xiàn)在端口也定義好了,下面單片機(jī)要哭訴了。
3.你誤解了單片機(jī)
單片機(jī)其實(shí)可以干很多活,結(jié)果你誤解了。
為了讓單片機(jī)不白忙活我們可以通過兩種方式來實(shí)現(xiàn)LED燈閃爍:a.定時器中斷,b.計(jì)時+標(biāo)志位。
A.定時器中斷
定時器中斷大家都知道,這里就不說了,就是產(chǎn)生xms的中斷就可以了。
B.計(jì)時+標(biāo)志位
計(jì)時+標(biāo)志位太有用了,這一下幫單片機(jī)洗清沉冤了。我們只要產(chǎn)生一個對200ms的時間,然后對該時間進(jìn)行計(jì)數(shù)到了5次,然后就清0該計(jì)數(shù)值,同時反轉(zhuǎn)LED燈的狀態(tài)即可。
代碼部分:
unsigned int LedTimeCount = 0 ; //LED計(jì)數(shù)器
unsigned char LedStatus = 0 ; //LED狀態(tài)標(biāo)志, 0表示亮,1表示熄滅
/***************************************
* 函數(shù)描述:LED燈線程處理函數(shù)
* 輸入?yún)?shù):No
* 返 回 值:No
* 說 明:通過標(biāo)志位來實(shí)現(xiàn)LED的反轉(zhuǎn)
* 修改記錄:
****************************************/
void LEDThread_Process(void)
{
if(0 == LedStatus) //如果LED的狀態(tài)為0,則點(diǎn)亮LED
{
LED_ON() ; //點(diǎn)亮LED燈
}
else //否則熄滅LED
{
LED_OFF() ;
}
}
/***************************************
* 函數(shù)描述:計(jì)時和標(biāo)志位函數(shù)
* 輸入?yún)?shù):No
* 返 回 值:No
* 說 明:狀態(tài)標(biāo)志位改變
* 修改記錄:
****************************************/
void LEDStatus_Change(void)
{
if(Sys_200MS) //系統(tǒng)200ms時標(biāo)到
{
Sys_200MS = 0 ;
LedTimeCount ++ ; //LED計(jì)數(shù)器加1
if(LedTimeCount >= 5) //計(jì)數(shù)達(dá)到5,即1s到了,改變LED的狀態(tài)。
{
LedTimeCount = 0 ;
LedStatus = ! LedStatus;
}
}
}
/***************************************
* 函數(shù)描述:主函數(shù)
* 輸入?yún)?shù):No
* 返 回 值:No
* 說 明:
* 修改記錄:
****************************************/
void main(void)
{
while(1)
{
LEDThread_Process() ;
LEDStatus_Change() ;
}
}
通過上面的程序就可以釋放單片機(jī)的CPU。因?yàn)長ED燈亮滅是有標(biāo)志位(LedStatus)來決定,而標(biāo)志位由計(jì)數(shù)器(LedTimeCount)來決定,兩個函數(shù)都沒有綁架單片機(jī)的CPU,所以單片機(jī)的CPU是自由的。終于洗冤了。O(∩_∩)O哈哈~
到此結(jié)束!!! 謝謝閱讀,歡迎拍磚!!!!
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)單片機(jī)相關(guān)文章:單片機(jī)教程
單片機(jī)相關(guān)文章:單片機(jī)視頻教程
單片機(jī)相關(guān)文章:單片機(jī)工作原理
塵埃粒子計(jì)數(shù)器相關(guān)文章:塵埃粒子計(jì)數(shù)器原理 全息投影相關(guān)文章:全息投影原理
評論