久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機C51編程幾個有用的模塊

單片機C51編程幾個有用的模塊

作者: 時間:2012-07-04 來源:網絡 收藏

為了能夠使用用SyncRecePackage或AsyncRecePackage函數從接收到的數據中識別出如上格式的數據包,有兩種方法:
第一種辦法是在Config.h文件中定義宏SCOMM_SimplePackageFormat,說明數據包為一種簡單格式,比如上面的協議。
之后還要定義兩個宏分別用來識別數據包頭和數據包尾,兩個宏分別是:
IsPackageHeader(x)和IsPackageTailer(x,y,z)
接收函數(SyncRecePackage和AsyncRecePackage)在沒有開始接收數據包(準確的說是還沒有從接收到的數據包中找到包頭的時候),會對接收到的每一個字節的數據調用IsPackageHeader宏,將相應的數據作為參數,如果IsPackageHeader宏的結果為TRUE,則認為找到了數據包頭,否則繼續對下一個字節進行判斷。
上面的協議對應的IsPackageHeader宏可以寫為:
#defineIsPackageHeader(x)((x)==0xff)
當接收到包頭之后,接收函數會對接下來的每一個字節數據調用IsPackagTailer宏來判斷是不是已經接收完數據包,三個參數分別為:
x:當前判斷的數據。
y:從包頭開始到當前被判斷的數據止的計數值,即當前已經接收到的字節數。
z:用戶在調用SyncRecePackage或AsyncRecePackage時指定的byParam參數。
與IsPackageHeader相似,如果宏IsPackageTailer的運算結果為TRUE,則認為接收到完整的數據包,則調用相應的回調函數(對于異步接收函數)或返回(對于接收函數)。如果運算結果為FALSE則繼續判斷下一個字節的數據。
上面的協議對應的IsPackageTailer宏可以寫為:
#defineIsPackageTailer(x,y,z)((y)>=(z))
當然,用戶也可以將IsPackageHeader和IsPackageTailer定義成為函數,通過BIT類型的返回值來向調用者提供與相應宏相同的信息。

另一種辦法需要在Config.h文件中定義宏SCOMM_ComplexPackageFormat。(需要注意的是,不能夠同時定義SCOMM_SimplePackageFormat和SCOMM_ComplexPackageFormat宏,否則會造成嚴重的不可預見性錯誤。
這時需要提供回調函數QueryPackageFormat,原形如下:
BYTEQueryPackageFormat(BYTEbyData,BYTEbyCount,BYTEbyParam);
函數中三個參數的含義與使用簡單數據包格式時判斷數據包尾的宏的參數相同。
函數通過返回值來通知作為調用者的接收函數對接收到的數據如何處理,但目前這種方法僅為需要處理復雜數據包格式時的一種可選方法,但不推薦。用戶如果想使用這種方法可以自己更改接收函數中相應的
#ifdefSCOM_ComplexPackageFormat
#endif//SCOMM_ComplexPackageFormat
預編譯指令之間的內容。
例如指定QueryPackageFormat的返回值的含義:
0:繼續找數據包頭或繼續找數據包尾。
1:找到數據包頭。
2:找到數據包尾。
3:數據包出錯,需要拋棄。
然后更改源代碼來實現上面的協議。

注意:當用戶需要使用字符串的時候,可以利用簡單的包裝函數將字符串轉換為字節數組。所以沒有必要提供專用的字符串處理函數。

鍵盤掃描模塊
鍵盤掃描模塊有兩種工作方式,一種為自動的由時鐘模塊調用,另一種是由程序員自行調用。
1)由時鐘模塊自動調用的方式
將時鐘模塊實現文件(Timer.h)及鍵盤掃描模塊的實現文件(KBScan。c)包含進工程,在Config.h文件中添加TIMER_KBSCANDELAY宏。時鐘模塊自動對時鐘中斷進行計數,當達到TIMER_KBSCANDELAY宏所定義的值后,自動調用鍵盤掃描模塊中的函數KBScanProcess()進行鍵盤掃描,也就是說,這個宏的值可以決定按鍵消抖動的時間。
用戶應該提供兩個回調函數OnKBScan()及OnKeysPressed()。在函數OnKBScan中進行鍵盤掃描,并返回掃描碼。掃描碼的類型缺省為BYTE,當鍵盤規模較大時,BYTE不能夠完全包含鍵盤信息時,可在Config.h文件中重定義宏KBVALUE,如下:
#defineKBVALUEWORD
這樣,就可以使用16位的鍵盤掃描碼,如果此時還達不到要求,可以將鍵盤掃描碼定義成一個結構,但這樣做將會增加代碼量及消耗更多的RAM資源,故不推薦。
掃描模塊調用OnKBScan取得掃描碼,并調用用戶可以重定義的宏IsNoKeyPressed來判斷是否有鍵按下,缺省的IsNoKeyPressed實現如下:
#defineIsNoKeyPressed(x)((x)==0x00)
即認為OnKBScan返回0掃描碼時為沒有鍵按下,如果掃描函數返回其它非零掃描碼做為無鍵按下的掃描碼時,可以在Config.h文件中重定義IsNoKeyPressed宏的實現。
8位鍵盤掃描碼(缺省值)時,相應的掃描函數為:
BYTEOnKBScan()
當掃描模塊經過軟件消抖動之后,發現有鍵按下,就會調用另一個回調函數OnKeysPressed。函數的聲明應該如下:
voidOnKeyPressed(BYTEbyKBValue,BYTEbyState)
其中中的參數byKBValue的類型為BYTE,此為缺省值,如果使用其它類型的掃描碼,就將此參數變為相應類型。這個值由OnKBScan返回。另一個參數byState在通常情況下為零。但當用戶在Config.h中定義宏KBSCAN_BRUSTCOUNT,同時鍵盤上的某鍵被按住不放時,掃描模塊對它自己的調用(注意這里和TIMER_KBSCANDELAY宏不同,TIMER_KBSCANDELAY是時鐘中斷足夠的次數后調用掃描模塊,而KBSCAN_BRUSHCOUNT為掃描模塊自身的被調用次數)進行計數,當達到KBSCAN_BRUSTCOUNT時,掃描模塊調用OnKeysPressed,此時第一個參數的含義不變,而byState變成1,同時計數器復位,又經過一段時間后,用值為3的byState調用OnKeysPressed。這樣就可以很方便的實現多功能鍵或者檢測某鍵的長時間被按下。
2)由用戶自行調用
由用戶自行在程序中調用掃描模塊,而不是由時鐘中斷自行調用。其它與方式1相同。

注意:
1)函數KBScanProcess為非阻塞函數,它將在很快的時間內返回,等待再次分配給它執行的機會。
2)函數KBScanProcess是在時鐘中斷外部運行的,它的過程可以被任何中斷打斷,但不影響系統運行。
3)byState的最大值為250,之后被復位為零。


上一頁 1 2 3 下一頁

評論


相關推薦

技術專區

關閉