找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5403|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

EC11增量型脈沖數(shù)字電位器單片機(jī)驅(qū)動(dòng)程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
論壇里的代碼都是用定時(shí)掃描端口的,沒有一例采用外中斷或端口變化中斷的。這種方法占用mcu時(shí)間極少,適用面廣(0~MHz級(jí)),代碼簡短,極其可靠。

單片機(jī)源程序如下:
  1. /*
  2. 所有微芯系mcu(例如PIC、九齊、義隆等)都有引腳變化中斷。
  3. 十速51mcu的P1有引腳變化中斷。
  4. PIN_A P10  開啟引腳變化中斷,可接P1任意端口P1x。
  5. PIN_B P11  不開啟引腳變化中斷,可接任意端口Pxx。
  6. */
  7. //只開啟一個(gè)引腳(PIN_A)變化中斷
  8. volatile u8 gPosition; // EC11 8位足夠。如需定位應(yīng)用,16位32位都有可能。
  9. u8 gPositionOld;
  10. void p1_change_int(void) interrupt 8
  11. { //加消抖電容,減少mcu開銷
  12.         bit bZZ = 0;//使用該臨時(shí)變量是為了加快端口讀取過程
  13.         if (PIN_A)
  14.         {//上跳
  15.                 if (!PIN_B)
  16.                         bZZ = 1;
  17.         }
  18.         else
  19.         {//下跳
  20.                 if (PIN_B)
  21.                         bZZ = 1;
  22.         }
  23.         if (bZZ)
  24.                 gPosition++; //正傳
  25.         else
  26.                 gPosition--; //反轉(zhuǎn)
  27.         INTFLG = 0;                 //清除變化中斷
  28. }

  29. void EC11_init(void)
  30. {
  31.         //開啟P10引腳變化中斷
  32.         gPositionOld=gPosition;
  33. }

  34. void EC11_Scan(void)
  35. {//定時(shí)執(zhí)行,選擇合適定時(shí)使任何時(shí)候(step<2)
  36.         u8 step=gPosition-gPositionOld;
  37.         if(0==step) return;
  38.         gPositionOld=gPosition;
  39.         if(step&0x80){
  40.                 step=0-step;
  41.                 //反轉(zhuǎn)處理 step為步數(shù)
  42.         }
  43.         else{
  44.                 //正傳處理 step為步數(shù)
  45.         }
  46. }
復(fù)制代碼



評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏15 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:390416 發(fā)表于 2022-6-15 11:35 | 只看該作者
//**********************************---祁緒電子---2020年5月 *************
// 按鍵或者旋轉(zhuǎn)編碼器 底層驅(qū)動(dòng) 加減函數(shù)
//*********************************************************************
void ROTARY_ROTARY_Scan_Drive(void)
{
        static xdata u8 count=0,Rotary_Flag=0;
        if(count>30)
        {
                count=0;
                if((ROTARY_B==0)&&(Rotary_Flag==0))                        //如果按鍵B按下,且flag是0       
                {
                        Rotary_Flag=1;
                        Rotary_Read_Data_Rotary++;                                //按鍵值增加1
                        if(Rotary_Read_Data_Rotary>Key_MAX)                //如果大于最大值 跳回0
                        {
                                Rotary_Read_Data_Rotary=Key_MIN;
                        }
                }
                if((ROTARY_A==0)&&(Rotary_Flag==0))                        //如果按鍵A按下,且flag是0       
                {
                        Rotary_Flag=1;
                        Rotary_Read_Data_Rotary--;                                //按鍵值減少1
                        if(Rotary_Read_Data_Rotary<Key_MIN)                //如果按鍵值等于0,跳回最大值
                        {
                                Rotary_Read_Data_Rotary=Key_MAX;
                        }
                }
                if((ROTARY_B!=0)&&(ROTARY_A!=0))                        //按鍵必須釋放,下次按鍵才有效
                {
                        Rotary_Flag=0;
                }
        }
        count++;
}

EC11很簡單 主函數(shù)不斷的掃描這個(gè)函數(shù) 就行了  ,兩個(gè)按鍵和EC11通用這段代碼
回復(fù)

使用道具 舉報(bào)

板凳
ID:401564 發(fā)表于 2022-6-15 16:12 | 只看該作者
為什么要節(jié)省MCU占用時(shí)間?是真的一個(gè)EC11讓整個(gè)程序停滯不前了嗎?有必要去省下那點(diǎn)時(shí)間嗎?
更多的時(shí)候,加一個(gè)電容才是不可取的.明明可以不要這個(gè)電容的,你卻要加電容?
自己DIY點(diǎn)小玩意玩玩也就無所謂了,批量的產(chǎn)品,一個(gè)一分錢的電容都是一個(gè)敏感的成本,而這個(gè)成本的增加只是不想讓單片機(jī)太累而已
回復(fù)

使用道具 舉報(bào)

地板
ID:887371 發(fā)表于 2022-6-16 09:29 | 只看該作者
Y_G_G 發(fā)表于 2022-6-15 16:12
為什么要節(jié)省MCU占用時(shí)間?是真的一個(gè)EC11讓整個(gè)程序停滯不前了嗎?有必要去省下那點(diǎn)時(shí)間嗎?
更多的時(shí)候,加 ...

EC11這種超慢速設(shè)備,可靠性不做要求的設(shè)備,好像隨便寫都能達(dá)到要求。
但節(jié)省MCU占用時(shí)間,總比浪費(fèi)要好吧(可讓改代碼用于極低主頻的mcu)。
并且這個(gè)節(jié)省還附帶了提高可靠性、代碼簡單,方便易用等好處。

我這代碼天然自帶消抖,這個(gè)電容不是必須,但有了這電容,mcu主頻可工作于10kHz。
回復(fù)

使用道具 舉報(bào)

5#
ID:887371 發(fā)表于 2022-6-16 09:47 | 只看該作者
本帖最后由 datouyuan 于 2022-6-16 09:52 編輯
Y_G_G 發(fā)表于 2022-6-15 16:12
為什么要節(jié)省MCU占用時(shí)間?是真的一個(gè)EC11讓整個(gè)程序停滯不前了嗎?有必要去省下那點(diǎn)時(shí)間嗎?
更多的時(shí)候,加 ...

假如這個(gè)EC11速度快了1000倍,并且還不允許丟步,掃描法還能不能用?
而用中斷法的方式,代碼不做修改還能用。

回復(fù)

使用道具 舉報(bào)

6#
ID:401564 發(fā)表于 2022-6-16 20:04 | 只看該作者
datouyuan 發(fā)表于 2022-6-16 09:29
EC11這種超慢速設(shè)備,可靠性不做要求的設(shè)備,好像隨便寫都能達(dá)到要求。
但節(jié)省MCU占用時(shí)間,總比浪費(fèi)要 ...

關(guān)鍵節(jié)省MCU時(shí)間來干嘛呢?總覺得提高M(jìn)CU效率是件好事,可關(guān)鍵是這用得著嗎?如果不是極端條件下,這種"優(yōu)化"一點(diǎn)意義都沒有,自己知道怎么優(yōu)化就行,并不需要每次都要優(yōu)化的
而且,用外部中斷的辦法并不是適用所有情況,因?yàn)榇蠖嗟膯纹瑱C(jī),外部中斷有最高等級(jí)的中斷,它會(huì)打斷其它所有的中斷,不知道你看過EC11的波形沒有,它轉(zhuǎn)動(dòng)一次,新的EC11抖動(dòng)有五六下,電平就固定了,如果是用了很久的時(shí)間,它抖動(dòng)有上百次的,以你的代碼,會(huì)直接打斷其它程序上百次,你試想一下,比如有波特率高點(diǎn)的串口,你能保證數(shù)據(jù)手準(zhǔn)確性?又或者是再去更改一下中斷優(yōu)先等級(jí)?
回復(fù)

使用道具 舉報(bào)

7#
ID:446113 發(fā)表于 2022-6-17 08:04 | 只看該作者
學(xué)習(xí)學(xué)習(xí)學(xué)習(xí),每天進(jìn)步一點(diǎn)點(diǎn)
回復(fù)

使用道具 舉報(bào)

8#
ID:887371 發(fā)表于 2022-6-17 11:55 | 只看該作者
Y_G_G 發(fā)表于 2022-6-16 20:04
關(guān)鍵節(jié)省MCU時(shí)間來干嘛呢?總覺得提高M(jìn)CU效率是件好事,可關(guān)鍵是這用得著嗎?如果不是極端條件下,這種"優(yōu)化" ...

你有幾條最基本的錯(cuò)誤:
1.提高M(jìn)CU效率,節(jié)約mcu的占用時(shí)間當(dāng)然是好事。
2.中斷就是要打斷程序,甚至頻繁打斷。假如中斷會(huì)對其它功能造成影響,最主要的解決辦法是減少相關(guān)代碼的占用時(shí)間,例如提高賣出主頻、提高代碼效率。
3.外部中斷雖是最高等級(jí)(非嵌入式優(yōu)先級(jí))的中斷,但它只會(huì)打斷嵌入式優(yōu)先級(jí)比它低的中斷。


在你說的極其惡劣環(huán)境下,甚至還差,我這代碼能保證波特率高點(diǎn)的串口數(shù)據(jù)準(zhǔn)確性,并且還保證了ec11的可靠性。這可靠性就是靠減少mcu占用時(shí)間保證的。
回復(fù)

使用道具 舉報(bào)

9#
ID:887371 發(fā)表于 2022-6-17 15:00 | 只看該作者
本帖最后由 datouyuan 于 2022-6-17 15:08 編輯
3.外部中斷雖是最高等級(jí)(非嵌入式優(yōu)先級(jí))的中斷,但它只會(huì)打斷嵌入式優(yōu)先級(jí)比它低的中斷。

你對很多基本知識(shí)有錯(cuò)誤理解,我表達(dá)能力又不好,所以多啰嗦幾句。
1.遠(yuǎn)古51嵌入式優(yōu)先級(jí)有2級(jí),現(xiàn)在很多51嵌入式優(yōu)先級(jí)有4級(jí)。
2.相同嵌入優(yōu)先級(jí)的中斷同時(shí)發(fā)生時(shí),mcu會(huì)先處理普通優(yōu)先級(jí)高的中斷,但不會(huì)打斷正在處理的中斷。提高代碼效率,減少mcu占用時(shí)間,能處理更多的中斷。
3.你所說的“外部中斷有最高等級(jí)的中斷,它會(huì)打斷其它所有的中斷”不會(huì)發(fā)生,因?yàn)槟悴惶匾庹{(diào)整嵌入式優(yōu)先級(jí)的話,外部中斷的嵌入優(yōu)先級(jí)是最低的。
4.使用中斷解決問題是單片機(jī)初學(xué)者必須掌握的技能,該整理下你的知識(shí)體系了。
5.一直圍繞著基礎(chǔ)討論,卻忽略了我這簡單代碼的精妙之處,希望你能仔細(xì)體會(huì)。
回復(fù)

使用道具 舉報(bào)

10#
ID:171036 發(fā)表于 2023-9-12 18:42 | 只看該作者
人人學(xué)會(huì)單片機(jī) 發(fā)表于 2022-6-15 11:35
//**********************************---祁緒電子---2020年5月 *************
// 按鍵或者旋轉(zhuǎn)編碼器 底 ...

count這個(gè)變量咋么計(jì)數(shù)  定時(shí)器計(jì)數(shù)  還是旋轉(zhuǎn)編碼開關(guān)旋動(dòng)就抖動(dòng)計(jì)數(shù)
回復(fù)

使用道具 舉報(bào)

11#
ID:406132 發(fā)表于 2023-10-27 15:40 | 只看該作者
雖然不會(huì)軟件,但能不用增加產(chǎn)品成本,就不要增加產(chǎn)品成本,畢竟消費(fèi)電子對成本比較敏感,老板來了句,為什么別人的可以做這么便宜?你的又要這個(gè)電容那個(gè)電容的……你不吐血?能解決項(xiàng)目工程的問題就好。
回復(fù)

使用道具 舉報(bào)

12#
ID:514317 發(fā)表于 2023-10-28 10:10 | 只看該作者
yanggo 發(fā)表于 2023-10-27 15:40
雖然不會(huì)軟件,但能不用增加產(chǎn)品成本,就不要增加產(chǎn)品成本,畢竟消費(fèi)電子對成本比較敏感,老板來了句,為什 ...

你這個(gè)說法不敢茍同   如果節(jié)省一兩個(gè)貼片電容就可以節(jié)省成本的話我無話可說    節(jié)省的途徑是以高可靠設(shè)計(jì)電路來節(jié)省使用元器件    試問你的功能都不穩(wěn)定節(jié)省這兩個(gè)電容有什么意義??   使用者使用時(shí)數(shù)字亂竄是什么使用體驗(yàn)??   還有設(shè)計(jì)的原則是程序盡可能優(yōu)化   寧愿讓MCU空轉(zhuǎn)也不能讓他堵塞運(yùn)行
回復(fù)

使用道具 舉報(bào)

13#
ID:996773 發(fā)表于 2023-10-30 10:47 | 只看該作者


這種數(shù)字電位器我也用了幾年了,從來不用防抖和電容,也不用中斷,中斷用在逐個(gè)點(diǎn)亮數(shù)碼管

我覺得保障顯示正常很重要,這電位器兩腳從00變化到01的時(shí)間對于主程序來說太漫長了,

把中斷用在編碼器也太浪費(fèi),我的程序大多數(shù)時(shí)間都是閑置狀態(tài)和軟件讀取數(shù)字電位器兩腳狀態(tài)
回復(fù)

使用道具 舉報(bào)

14#
ID:774081 發(fā)表于 2024-1-5 13:07 | 只看該作者
贊同樓主的理念!有的人的思維邏輯和你奇怪,如果你說人用兩條腿走路比較好,他都會(huì)提出殘疾人沒有兩條腿怎么走這樣類似的反駁理由。中斷不夠用你就用輪訓(xùn)唄!中斷多余的話,用中斷不是挺好的嗎?至于用不用電容,你買產(chǎn)品的時(shí)候一定希望產(chǎn)品里用電容吧,怎么你是制造者了就不想用電容了?匠心何在?
回復(fù)

使用道具 舉報(bào)

15#
ID:774081 發(fā)表于 2024-1-8 11:03 | 只看該作者
今天實(shí)測樓主的中斷方式檢測EC11的轉(zhuǎn)動(dòng),不好用!主要是判斷結(jié)果里正傳中夾雜反轉(zhuǎn)、反轉(zhuǎn)中夾雜正轉(zhuǎn)!一開始分析程序,發(fā)現(xiàn)對于一個(gè)U8變量step,你來一句“step=0-step;”就令人費(fèi)解。以下是我的代碼,同樣采取中斷,結(jié)果非常準(zhǔn)確穩(wěn)定,能完整輸出當(dāng)前轉(zhuǎn)動(dòng)方向和累計(jì)計(jì)數(shù)值(正轉(zhuǎn)增大數(shù)值,反轉(zhuǎn)減小數(shù)值),通過方向和計(jì)數(shù)就可用于特定的功能設(shè)計(jì)了。代碼對EC11的A腳進(jìn)行中斷響應(yīng)(下降沿檢測),響應(yīng)函數(shù)為:
void EC11_Change_Interupt(){
  static bool prev_A = 0;//必須為static!或者定義為一般的全局變量
  volatile bool curr_A = digitalRead(EC11_A);
  volatile bool curr_B = digitalRead(EC11_B);
  if((prev_A == 0) && (curr_A == 1)){
    if(curr_B == 0){
      count = count - 1;
      direction = 0;
    }
    else{
      count = count + 1;
      direction = 1;
    }
  }
  else if((prev_A == 1) && (curr_A == 0)){
    if(curr_B == 0){
      count = count + 1;
      direction = 1;
    }
    else{
      count = count - 1;
      direction = 0;
    }
  }
  prev_A = curr_A;
  if(direction){
    Serial1.println((String("正轉(zhuǎn):") + String(count)));
  }
  else{
    Serial1.println((String("反轉(zhuǎn):") + String(count)));
  }
}

對于SW腳,也可以通過下降沿中斷,使count歸零。以上代碼由圖形化軟件轉(zhuǎn)化而來,可能比較累贅,可以適當(dāng)去掉一些強(qiáng)制轉(zhuǎn)換和括號(hào)。
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表