單片機的程序框架
寫(xiě)的很好
很多思路是我之前所困擾的,這個(gè)解決了自己的很多問(wèn)題
可以憑借此建立模版,吃透之后對以后工程有質(zhì)的提高。
(感覺(jué)論壇上的高手很多,多看看多學(xué)學(xué),總會(huì )有收獲)
再把文章最后的“實(shí)用的單片機系統ms3”源碼打出來(lái)研究一下。04年就寫(xiě)出來(lái)的東西,用到14年還這么多人挺,確實(shí)經(jīng)典。
多思考,多總結,不要總是悶頭做??!不斷的提高自己,才有收獲??!讓自己學(xué)到東西!
工程的框架感覺(jué)就三種
1、裸奔、順序執行、大循環(huán) 新手和小程序都這樣
2、時(shí)間片輪轉 下面轉的就是類(lèi)似這種,個(gè)人比較喜歡這種,再貼一份介紹的很好的網(wǎng)址http://blog.chinaunix.net/attachment/attach/26/98/16/5926981659d4246ddc2fd7b9 58acbe0afbda5ad38b.txt
3、操作系統 小的RTX51、ucos這些,大點(diǎn)linux,都是很常見(jiàn)。
個(gè)人感覺(jué)51、avr、freescale、msp430、stm32這些低端單片機用時(shí)間片輪轉就比較好,時(shí)間和底層把握的都比較好。
用arm7、9、11像2440、6410這些跑linux這些比較好。
轉載的正文
從07年參加全國大學(xué)生電子設計大賽初次接觸單片機開(kāi)發(fā)至今已經(jīng)有4年了,初學(xué)單片機時(shí),都會(huì )糾結于其各個(gè)模塊功能的應用,如串口(232,485)對各種功能IC的控制,電機控制PWM,中斷應用,定時(shí)器應用,人機界面應用,CAN總線(xiàn)等. 這是一個(gè)學(xué)習過(guò)程中必需的階段,是基本功。很慶幸,在參加電子設計大賽賽前培訓時(shí),MCU周?chē)目刂贫加柧毜暮茉鷮?shí)。經(jīng)過(guò)這個(gè)階段后,后來(lái)接觸不同的MCU就會(huì )發(fā)現,都大同小異,各有各的優(yōu)勢而已,學(xué)任何一種新的MCU都很容易入手包括一些復雜的處理器。而且對MCU的編程控制會(huì )提升一個(gè)高度概況——就是對各種外圍進(jìn)行控制(如果是對復雜算法的運算就會(huì )
用DSP了),而外圍與MCU的通信方式一般也就幾種時(shí)序:IIC,SPI,intel8080,M6800。這樣看來(lái)MCU周?chē)木幊叹褪且粋€(gè)很簡(jiǎn)單的東西了。
然而這只是嵌入式開(kāi)發(fā)中的一點(diǎn)皮毛而已,在接觸過(guò)多種MCU,接觸過(guò)復雜設計要求,跑過(guò)操作系統等等后,我們在回到單片機的裸機開(kāi)發(fā)時(shí),就不知不覺(jué)的就會(huì )考慮到整個(gè)程序設計的架構問(wèn)題;一個(gè)好的程序架構,是一個(gè)有經(jīng)驗的工程師和一個(gè)初學(xué)者的分水嶺。
以下是我對單片機程序框架以及開(kāi)發(fā)中一些常用部分的認識總結:
任何對時(shí)間要求苛刻的需求都是我們的敵人,在必要的時(shí)候我們只有增加硬件成本來(lái)消滅它;比如你要8個(gè)數碼管來(lái)顯示,我們在沒(méi)有相關(guān)的硬件支持的時(shí)候必須用MCU以動(dòng)態(tài)掃描的方式來(lái)使其工作良好;而動(dòng)態(tài)掃描將或多或少的阻止了MCU處理其他的事情。在MCU負擔很重的場(chǎng)合,我會(huì )選擇選用一個(gè)類(lèi)似max8279外圍ic來(lái)解決這個(gè)困擾;
然而慶幸的是,有著(zhù)許多不是對時(shí)間要求苛刻的事情:
例如鍵盤(pán)的掃描,人們敲擊鍵盤(pán)的速率是有限的,我們無(wú)需實(shí)時(shí)掃描著(zhù)鍵盤(pán),甚至可以每隔幾十ms才去掃描一下;然而這個(gè)幾十ms的間隔,我們的MCU還可以完成許多的事情;
單片機雖然是裸機奔跑,但是往往現實(shí)的需要決定了我們必須跑出操作系統的姿態(tài)——多任務(wù)程序;
比如一個(gè)常用的情況有4個(gè)任務(wù):
1 鍵盤(pán)掃描;
2 led數碼管顯示;
3 串口數據需要接受和處理;
4 串口需要發(fā)送數據;
如何來(lái)構架這個(gè)單片機的程序將是我們的重點(diǎn);
讀書(shū)時(shí)代的我會(huì )把鍵盤(pán)掃描用查詢(xún)的方式放在主循環(huán)中,而串口接收數據用中斷,在中斷服務(wù)函數中組成相應的幀格式后置位相應的標志位,在主函數的循環(huán)中進(jìn)行數據的處理,串口發(fā)送數據以及l(fā)ed的顯示也放在主循環(huán)中;
這樣整個(gè)程序就以標志變量的通信方式,相互配合的在主循環(huán)和后臺中斷中執行;
然而必須指出其不妥之處:
每個(gè)任務(wù)的時(shí)間片可能過(guò)長(cháng),這將導致程序的實(shí)時(shí)性能差。如果以這樣的方式在多加幾個(gè)任務(wù),使得一個(gè)循環(huán)的時(shí)間過(guò)長(cháng),可能鍵盤(pán)掃描將很不靈敏。所以若要建立一個(gè)良好的通用編程模型,我們必須想辦法,消去每個(gè)任務(wù)中費時(shí)間的部分以及把每個(gè)任務(wù)再次分解;下面來(lái)細談每個(gè)任務(wù)的具體措施:
1 鍵盤(pán)掃描
鍵盤(pán)掃描是單片機的常用函數,以下指出常用的鍵盤(pán)掃描程序中,嚴重阻礙系統實(shí)時(shí)性能的地方;
眾所周知,一個(gè)鍵按下之后的波形是這樣的(假定低有效):
在有鍵按下后,數據線(xiàn)上的信號出現一段時(shí)間的抖動(dòng),然后為低,然后當按鍵釋放時(shí),信號抖動(dòng)一段時(shí)間后變高。當然,在數據線(xiàn)為低或者為高的過(guò)程中,都有可能出現一些很窄的干擾信號。
unsigned char kbscan(void)
{
unsigned char sccode,recode;
P2=0xf8;
if ((P2&0xf8)!=0xf8)
{
delay(100); //延時(shí)20ms去抖--------這里太費時(shí)了,很糟糕
if((P2&0xf8)!=0xf8)
{
sccode=0xfe;
while((sccode&0x08)!=0)
{
P2=sccode;
if ((P2&0xf8)!=0xf8)
break;
sccode=(sccode<<1)|0x01;
}
recode=(P2&0xf8)|0x0f;
return(sccode&recode);
}
}
return (KEY_NONE);
}
鍵盤(pán)掃描是需要軟件去抖的,這沒(méi)有爭議,然而該函數中用軟件延時(shí)來(lái)去抖(ms級別的延時(shí)),這是一個(gè)維持系統實(shí)時(shí)性能的一個(gè)大忌諱;
一般還有一個(gè)判斷按鍵釋放的代碼:
While( kbscan() != KEY_NONE)
; //死循環(huán)等待
這樣很糟糕,如果把鍵盤(pán)按下一直不放,這將導致整個(gè)系統其它的任務(wù)也不能執行,這將是個(gè)很?chē)乐氐腷ug。
有人會(huì )這樣進(jìn)行處理:
While(kbsan() != KEY_NONE )
{
Delay(10);
If(Num++ > 10)
Break;
}
即在一定得時(shí)間內,如果鍵盤(pán)一直按下,將作為有效鍵處理。這樣雖然不導致整個(gè)系統其它任務(wù)不能運行,但也很大程度上,削弱了系統的實(shí)時(shí)性能,因為他用了延時(shí)函數;
用DSP了),而外圍與MCU的通信方式一般也就幾種時(shí)序:IIC,SPI,intel8080,M6800。這樣看來(lái)MCU周?chē)木幊叹褪且粋€(gè)很簡(jiǎn)單的東西了。
任何對時(shí)間要求苛刻的需求都是我們的敵人,在必要的時(shí)候我們只有增加硬件成本來(lái)消滅它;比如你要8個(gè)數碼管來(lái)顯示,我們在沒(méi)有相關(guān)的硬件支持的時(shí)候必須用MCU以動(dòng)態(tài)掃描的方式來(lái)使其工作良好;而動(dòng)態(tài)掃描將或多或少的阻止了MCU處理其他的事情。在MCU負擔很重的場(chǎng)合,我會(huì )選擇選用一個(gè)類(lèi)似max8279外圍ic來(lái)解決這個(gè)困擾;
然而慶幸的是,有著(zhù)許多不是對時(shí)間要求苛刻的事情:
例如鍵盤(pán)的掃描,人們敲擊鍵盤(pán)的速率是有限的,我們無(wú)需實(shí)時(shí)掃描著(zhù)鍵盤(pán),甚至可以每隔幾十ms才去掃描一下;然而這個(gè)幾十ms的間隔,我們的MCU還可以完成許多的事情;
單片機雖然是裸機奔跑,但是往往現實(shí)的需要決定了我們必須跑出操作系統的姿態(tài)——多任務(wù)程序;
比如一個(gè)常用的情況有4個(gè)任務(wù):
1
2
3
4
如何來(lái)構架這個(gè)單片機的程序將是我們的重點(diǎn);
讀書(shū)時(shí)代的我會(huì )把鍵盤(pán)掃描用查詢(xún)的方式放在主循環(huán)中,而串口接收數據用中斷,在中斷服務(wù)函數中組成相應的幀格式后置位相應的標志位,在主函數的循環(huán)中進(jìn)行數據的處理,串口發(fā)送數據以及l(fā)ed的顯示也放在主循環(huán)中;
這樣整個(gè)程序就以標志變量的通信方式,相互配合的在主循環(huán)和后臺中斷中執行;
然而必須指出其不妥之處:
每個(gè)任務(wù)的時(shí)間片可能過(guò)長(cháng),這將導致程序的實(shí)時(shí)性能差。如果以這樣的方式在多加幾個(gè)任務(wù),使得一個(gè)循環(huán)的時(shí)間過(guò)長(cháng),可能鍵盤(pán)掃描將很不靈敏。所以若要建立一個(gè)良好的通用編程模型,我們必須想辦法,消去每個(gè)任務(wù)中費時(shí)間的部分以及把每個(gè)任務(wù)再次分解;下面來(lái)細談每個(gè)任務(wù)的具體措施:
1 鍵盤(pán)掃描
鍵盤(pán)掃描是單片機的常用函數,以下指出常用的鍵盤(pán)掃描程序中,嚴重阻礙系統實(shí)時(shí)性能的地方;
眾所周知,一個(gè)鍵按下之后的波形是這樣的(假定低有效):
在有鍵按下后,數據線(xiàn)上的信號出現一段時(shí)間的抖動(dòng),然后為低,然后當按鍵釋放時(shí),信號抖動(dòng)一段時(shí)間后變高。當然,在數據線(xiàn)為低或者為高的過(guò)程中,都有可能出現一些很窄的干擾信號。
unsigned char kbscan(void)
{
unsigned char sccode,recode;
P2=0xf8;
if ((P2&0xf8)!=0xf8)
{
}
鍵盤(pán)掃描是需要軟件去抖的,這沒(méi)有爭議,然而該函數中用軟件延時(shí)來(lái)去抖(ms級別的延時(shí)),這是一個(gè)維持系統實(shí)時(shí)性能的一個(gè)大忌諱;
一般還有一個(gè)判斷按鍵釋放的代碼:
While( kbscan() != KEY_NONE)
; //死循環(huán)等待
這樣很糟糕,如果把鍵盤(pán)按下一直不放,這將導致整個(gè)系統其它的任務(wù)也不能執行,這將是個(gè)很?chē)乐氐腷ug。
有人會(huì )這樣進(jìn)行處理:
While(kbsan() != KEY_NONE )
{
}
即在一定得時(shí)間內,如果鍵盤(pán)一直按下,將作為有效鍵處理。這樣雖然不導致整個(gè)系統其它任務(wù)不能運行,但也很大程度上,削弱了系統的實(shí)時(shí)性能,因為他用了延時(shí)函數;
關(guān)鍵詞:
單片機程序框
技術(shù)專(zhuān)區
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線(xiàn)
- 開(kāi)關(guān)電源
- 單片機
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開(kāi)發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機控制
- 藍牙
- PLC
- PWM
- 汽車(chē)電子
- 轉換器
- 電源管理
- 信號放大器
評論