日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀] 從事單片機(jī)工作有幾年了,一直想做一個系列總結(jié),正好趕上今天下雨,俗話說:下雨天,宅家天。吃飽喝足,閑來無事,正好寫篇博客,算是這個系列的開頭第一篇,以后有時間就寫點(diǎn),這個“系列死了”也不奇怪。有不對

從事單片機(jī)工作有幾年了,一直想做一個系列總結(jié),正好趕上今天下雨,俗話說:下雨天,宅家天。吃飽喝足,閑來無事,正好寫篇博客,算是這個系列的開頭第一篇,以后有時間就寫點(diǎn),這個“系列死了”也不奇怪。有不對的地方或者您有什么好的建議請留言,思想是碰撞的火花,請大家暢所欲言。

按鍵是單片機(jī)系統(tǒng)中最常用的一個東東,簡單人機(jī)交互界面基本都有按鍵存在。猶記得剛開始接觸單片機(jī)時候,讀取一個按鍵IO值,就當(dāng)做鍵值來處理,發(fā)現(xiàn)一次按鍵經(jīng)常識別為好幾次,查閱資料才發(fā)現(xiàn)要“消抖”,于是加個delay_ms(5),連續(xù)讀取幾次,確定單次有效值。這就是后來不怎么跑多任務(wù),不注重實(shí)時性時經(jīng)?!妗姆椒?,如果你還在用,那么下面的文字對你有用,如果你已經(jīng)知道了,那就請飛過吧,反正我也是隨便寫寫,你也就隨性看看。


下面就是一個很典型的例子:


boolkey_get_value(void)

{

boolbNewIoValue=0;

staticbools_bOldIoValue=0;

uint8_ti=0;

for(i=0;i<4;i++){

bNewIoValue=io_read();

if(s_bOldIoValue!=bNewIoValue){

i=0;

s_bOldIoValue=bNewIoValue;

continue;

}

delay_ms(5);

}

returns_bOldIoValue;

}


我們來看看代碼“阻塞在什么地方”?有代碼分析可知,主要在delay_ms(5)這里,在這里通過“軟件延時”來達(dá)到消除抖動的目的。那么我們換一種思路,假如我們的task執(zhí)行到delay_ms(5)這里,便退出(讓出運(yùn)行權(quán)),同時啟動一個“計(jì)數(shù)時鐘”,當(dāng)?shù)?MS時候,就再起運(yùn)行起來,這樣就變?yōu)榱恕胺亲枞薄榱诉_(dá)到這個目的,不管如何實(shí)現(xiàn)都需要一個“硬時基”,用于異步計(jì)數(shù)。

說下思路:就是tick時鐘到,調(diào)用一次io_read(),并做消抖,然后獲取一次有效按鍵值。好,到這里我們消除了delay_ms(5),那么我們繼續(xù)思考,對于按鍵的值的“獲得”我們可以說有“實(shí)時性要求”,例如:我按下按鍵,你要能夠及時獲得這個動作。但是按鍵值獲得之后,按鍵的狀態(tài)判斷(down、short_press、long_press、repeat_press、up)相對來說可以暫緩,還有按鍵狀態(tài)獲得之后,其對應(yīng)的處理函數(shù)又可分為緊急和非緊急兩類(緊急類的先不討論),非緊急類的又可以通過key_message_queue暫存按鍵消息,然后慢慢去執(zhí)行消化。數(shù)據(jù)流程圖如圖所示:





這么處理的原因,是把有實(shí)時要求的任務(wù)和沒有要求的任務(wù)分開,運(yùn)用“生產(chǎn)者-消費(fèi)者”模型。



思路介紹完了,下面說說具體模塊:


注意:

1、最多255個按鍵;

2、每個按鍵都有按下、短按、長按、雙擊、抬起五個狀態(tài);

下載地址:http://download.csdn.net/download/wuhenyouyuyouyu/9952815

(下載分?jǐn)?shù)限制,為什么不能設(shè)置為0分了?)


一、配置


public.h
宏KEY_MODE_SCHEDULER_IS_USER_CALL


1:按鍵的調(diào)度函數(shù)由用戶調(diào)度;
0:按鍵的調(diào)度函數(shù)由系統(tǒng)自動調(diào)度;


宏KEY_NUM 配置按鍵個數(shù)

app_cfg.h


模塊配置
#define KEY_ELIMINATE_JITTER_NUM 5 //按鍵消抖次數(shù)


#define KEY_MODE_QUEUE_LONG 10 //key消息隊(duì)列大小


#define KEY_NORMAL_VALUE 1 //定義按鍵常態(tài)值


#define KEY_SCAN_CYCLE 10 //鍵值掃描周期:單位ms


#define KEY_SHORT_PRESSED_TIMER 1000 //短按判定時間:單位ms


#define KEY_LONG_PRESSED_TIMER 3000 //長按判定時間:單位ms


#define KEY_REPEAT_TIMER 500 //連按判定周期:單位ms


#define KEY_GET_VALUE_IS_INLINE_FUNCTION 0 //為inline函數(shù)還是callback函數(shù)


按鍵消息配置:為0,則不發(fā)送;為1,則發(fā)送
#define KEY_MODE_IS_ENABLE_MESSAGE_DOWN 1
#define KEY_MODE_IS_ENABLE_MESSAGE_SHORT 1
#define KEY_MODE_IS_ENABLE_MESSAGE_LONG 1
#define KEY_MODE_IS_ENABLE_MESSAGE_REPEAT 1
#define KEY_MODE_IS_ENABLE_MESSAGE_UP 1


加鎖控制


......



二、用戶實(shí)現(xiàn)函數(shù)
用戶需提供按鍵掃描函數(shù),原型bool key_mode_get_key_value(uint8_t chKeyID)


bool 按鍵狀態(tài)
chKeyID 按鍵的ID


宏KEY_GET_VALUE_IS_INLINE_FUNCTION控制函數(shù)為inline類型,還是callback。


三、使用


int main(void)
{
key_message_t tKeyMessage;
//初始化
//關(guān)中斷

......

USER_KEY_MODE_INIT(NULL);//key_mode_get_key_value()為inline函數(shù)

......

//開中斷

while(1){
#if(KEY_MODE_SCHEDULER_IS_USER_CALL)
USER_KEY_MODE_SCHEDULER();
#endif


if(key_mode_get_message(&tKeyMessage)){
key_function[tKeyMessage.chKeyID](tKeyMessage.chKeyMessage);//按鍵處理
}
}
}


//心跳定時器
void systick(void)
{
......
USER_KEY_MODE_SCAN();
......
}


四、補(bǔ)充


#define __C99__


#ifndef __C99__
#define SAFE_ATOM_CODE(__CODE) {
istate_t tState = GET_GLOBAL_INTERRUPT_STATE();
DISABLE_GLOBAL_INTERRUPT();
{
__CODE;
}
SET_GLOBAL_INTERRUPT_STATE(tState);
}
#else
#define SAFE_ATOM_CODE(...) {
istate_t tState = GET_GLOBAL_INTERRUPT_STATE();
DISABLE_GLOBAL_INTERRUPT();
{
__VA_ARGS__;
}
SET_GLOBAL_INTERRUPT_STATE(tState);
}


#endif


五、技術(shù)交流群號


如果有BUG請留言或者進(jìn)入技術(shù)群:344659218


六、修改記錄

2017.08.29

1、修復(fù)BUG,用下面的函數(shù)替換掉原來的


/*****************************************************************************

*Function:key_mode_scan_sub_state

*PreCondition:None

*Input:void

*Output:void

*SideEffects:None

*Overview:KEY模塊掃描子函數(shù)

*Note:被key_mode_scheduler調(diào)用

*****************************************************************************/

staticfsm_rt_tkey_mode_judge_sub_state(key_mode_temp_t*ptKeyStruct)

{

key_mode_key_queue_t*ptThis=NULL;

#defineRESET_FMS_JUDGE_SBU(__ID){s_tKeyArray[__ID].tState=KEY_MODE_JUDGE_FSM_START;}

#defineKEY_MODE_POST_MESSAGE(__MESSAGE)do{

ptThis = malloc_key_queue();

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計(jì)中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計(jì)工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉