久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C語言中實現(xiàn)邊沿函數(shù)算法及應(yīng)用,,這是拋棄PLC留下的痛!

 昵稱21467945 2018-12-16

?本原創(chuàng)文章基于實踐經(jīng)驗,提供嚴(yán)謹(jǐn)可靠的設(shè)計原理及思路,。

后續(xù)準(zhǔn)備穿插一些有關(guān)單片機(jī)應(yīng)用C語言編程技巧的文章,,那么本期講解邊沿信號的應(yīng)用。很多從事PLC編程的朋友都知道,,不管是什么品牌的PLC,,都有上升沿和下降沿指令

?那么什么情況下我們才會使用或必須使用邊沿信號呢,?邊沿信號我們又如何獲取呢,?

圖1,任何一個開關(guān)信號(或數(shù)字信號)都可以分解成4個狀態(tài):①高電平 ②低電平 ③上升沿 ④下降沿,。

C語言中實現(xiàn)邊沿函數(shù)算法及應(yīng)用,,這是拋棄PLC留下的痛!

圖1:開關(guān)信號

?在PLC編程里,,上升沿指令和下降沿指令可以直接調(diào)用,;那么對于單片機(jī)的C語言編程,,又如何實現(xiàn)邊沿信號的判斷呢,?因為早期做過PLC編程的緣故,受PLC編程思路的影響,,對C語言編程急需簡單而高效的邊沿函數(shù),,于是痛定思痛,編寫了以下上升沿函數(shù)和下降沿函數(shù),,使用方便,、簡單暴力。

/************************************************* 上升沿函數(shù)*************************************************/u8 Posedge(u8 Old_Value,u8 m){ static u8 New_Value[100]; u8 _PLS[100]; _PLS[m] = Old_Value & (Old_Value ^ New_Value[m]); New_Value[m] = Old_Value; return(_PLS[m]);}

?上升沿函數(shù)的邏輯原理是:

第一次進(jìn)入函數(shù):

①Old_Value從0→1,;(此時New_Value[m]初始值為0)

②_PLS[m] = Old_Value & (Old_Value ^ New_Value[m])的運算結(jié)果為1(括號里異或運算為1),;

③New_Value[m])= Old_Value被賦值為1;

④返回_PLS[m]值為1,。

第二次及以后進(jìn)入函數(shù):

①New_Value[m]保持為1(因為被定義了static類型,,第二次調(diào)用不會被清0);

②_PLS[m] = Old_Value & (Old_Value ^ New_Value[m])的運算結(jié)果為0(括號里異或運算為0),;

③New_Value[m])= Old_Value仍然被賦值為1,;

④返回_PLS[m]值為0。

⑤Old_Value從1→0,,運算結(jié)果為0,,返回值也為0;

?所以上升沿函數(shù)只在變量0→1變化時返回值為1,。

另外形參m的取值范圍是0~99,,是為了區(qū)分不同Old_Value的實參,如果不同的實參用相同的m值(比如0),則該函數(shù)返回值會發(fā)生混亂,;具體應(yīng)用下面會附上實例,。

/************************************************ 下降沿函數(shù)************************************************/u8 Negedge(u8 Old_Value,u8 m){ static u8 New_Value[100]; u8 _PLF[100]; _PLF[m] = ~Old_Value & (~Old_Value ^ New_Value[m]); New_Value[m] = ~Old_Value; return(_PLF[m]);}

下降沿函數(shù)的原理與上升沿函數(shù)完全一樣,只需把Old_Value值取反即可,。

?應(yīng)用實例講解:

①以下為按鍵短按長按計數(shù)為例(單片機(jī)使用的是STM32F103系列的),。

if(Flag_1ms) //在1ms掃描周期內(nèi){ Flag_1ms = 0; if(SW1_IN == 0) //SW1按鍵長按,參數(shù)碼Cnt_Code以50ms間隔遞增 { if(Negedge(SW1_IN,0) == 1) Cnt_Code++; //SW1按鍵短按,,Cnt_Code只加1 i++; //以下為SW2按鍵長按計數(shù)間隔50ms if(i == 50) //取經(jīng)驗值50 { i = 0; Cnt_Code++; if(Cnt_Code == 101) Cnt_Code = 0; //Cnt_Code值范圍1--100 } }if(SW2_IN == 0) //SW2按鍵長按,,參數(shù)碼Cnt_Code以50ms間隔遞減 { if(Negedge(SW2_IN,1) == 1) Cnt_Code--; //SW1按鍵短按,Cnt_Code只減1 i++; //以下為SW2按鍵長按計數(shù)間隔50ms if(i == 50) //取經(jīng)驗值50 { i = 0; Cnt_Code--; if(Cnt_Code == 0) Cnt_Code = 100; } }}

是不是發(fā)現(xiàn)了一個bug,,本人沒有做按鍵的消抖處理,,別急,用邊沿函數(shù)處理開關(guān)信號完全不需要消抖處理,,是不是很簡單省事,!

if(Negedge(SW1_IN,0) == 1) Cnt_Code++;

上面代碼表示SW1按鍵按下時,函數(shù)Negedge(SW1_IN,0)返回值為1,,if條件語句判斷為真,,在1ms周期內(nèi)Cnt_Code加1;

if(Negedge(SW2_IN,1) == 1) Cnt_Code--;

邏輯同上,,但注意括號(SW2_IN,1)內(nèi)不是0,,而是1,是為了避免與前一個下降沿函數(shù)在調(diào)用時有沖突,。

②電池過壓保護(hù)程序

if(Posedge(Battery_Voltage > 14 ,0) == 1)//電池電壓大于14V{ Flag_OVP = 1; //過壓標(biāo)志置位}if(Posedge(Battery_Voltage < 14="" ,1)="=" 1)//電池電壓小于14v{="" flag_ovp="0;">

上面代碼的上升沿函數(shù)Posedge(Battery_Voltage > 14 ,0) 中判斷語句的假值→真值也可以作為上升沿來使用,,是不是很妙

以上的兩種用法只是上升沿函數(shù)和下降沿函數(shù)最為普遍的用法,,運用熟練后,,可以自由發(fā)揮,另外,,以上變量的數(shù)據(jù)類型我都定義為u8(unsigned char),,因為我的STM32的標(biāo)準(zhǔn)庫里沒有布爾類型(bool)的定義,我也一直沒使用過布爾類型,。變量定義如下:

u8 i; //按鈕長按間隔計數(shù)u8 Cnt_Code;//參數(shù)碼u8 Flag_OVP;//過壓標(biāo)志u8 Flag_1ms;//1ms標(biāo)志

?要點:

①上升沿函數(shù)和下降沿函數(shù)的返回值都為1,,且在當(dāng)前掃描周期內(nèi)有效,下一個周期就變?yōu)?了,,所以可以理解為其輸出了一個脈沖,;

按鍵消抖的常用方法是延時判斷,其實用邊沿函數(shù)處理開關(guān)信號完全不用消抖,,直接調(diào)用即可,;如果主函數(shù)有實時性要求較高的掃描程序存在,,延時函數(shù)的弊病就出來了,ta會嚴(yán)重影響掃描周期,。

③用于只需要執(zhí)行一次的指令(非保持),,如加一減一、移位,、交換,、存儲,以及一個變量受制于多個條件等,,如果不用上升沿或者下降沿,,那么代碼在每個周期都會被執(zhí)行一次,于是就不能達(dá)到理想效果,;

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多