久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10868|回復: 13
收起左側

51單片機旋轉編碼器模塊測試代碼

  [復制鏈接]
ID:658665 發表于 2020-5-5 15:28 | 顯示全部樓層 |閱讀模式
模塊圖片 旋轉編碼器.jpg
測試平臺:STC89C516單片機 晶振:12MHz
其他單片機(STC12單片機)或晶振,請在程序的LCD1602.crotary_encoder.c文件中修改延時函數


連線如圖(連線的接口在程序的port.h文件里)

旋轉編碼器連線.jpg


測試代碼功能:
將程序下載到開發板,LCD顯示0FF,顯示數字000.
按下旋轉編碼器的按鍵,OFF變為ON,轉動旋轉編碼器就可以在LCD1602中看到數字變化.
再次按下旋轉按鍵,ON變為OFF,此時轉動旋轉編碼器不可以在LCD1602中看到數字變化.

結尾:
    測試程序的注釋也比較詳細,自我感覺這個程序對較慢的轉速和正常的轉速的兼容性都比較好,只有極少數情況出現丟步,已經實現較好的實現了旋轉編碼器的功能了.

本帖測試程序參考過以下帖子
http://www.zg4o1577.cn/bbs/dpj-93972-1.html

單片機源程序如下:
  1. #include <intrins.h>
  2. #include "public.h"
  3. #include "rotary_encoder.h"
  4. #include "LCD1602.h"
  5. #include "port.h"

  6. void rotary_encoder_delay50us()//12.000MHz
  7. {
  8.         u8 i;
  9.         _nop_();
  10.         i=22;
  11.         while(--i);
  12. }

  13. void rotary_encoder_delay10ms()        //12.000MHz
  14. {
  15.         u8 i,j;

  16.         i=20;
  17.         j=113;
  18.         do
  19.         {
  20.                 while (--j);
  21.         }while (--i);
  22. }

  23. //旋轉編碼器初始化
  24. void rotary_encoder_init()
  25. {
  26.         ROTARY_ENCODER_CLK=1;
  27.         ROTARY_ENCODER_DT=1;
  28.         ROTARY_ENCODER_SW=1;
  29.        
  30.         IT0=1;
  31.         EX0=1;
  32.         EA=1;
  33.        
  34.         LCD1602_print_char(0,0,'O');
  35.         LCD1602_print_char(0,1,'F');
  36.         LCD1602_print_char(0,2,'F');
  37.        
  38.         LCD1602_print_char(1,0,'0'+0);
  39.         LCD1602_print_char(1,1,'0'+0);
  40.         LCD1602_print_char(1,2,'0'+0);
  41. }

  42. //掃描旋轉編碼器,返回值為1代表正轉,返回值為0代表反轉,返回值為0xFF代表未旋轉或旋轉錯誤
  43. u8 scan_rotary_encoder()
  44. {
  45.         u8 rotary_encoder_state;//旋轉編碼器狀態
  46.         u16 forced_out;//強制退出
  47.        
  48.         //旋轉編碼器狀態
  49.         //如果在剛開始ROTARY_ENCODER_CLK和ROTARY_ENCODER_DT都為1,則狀態為1
  50.         //如果在剛開始ROTARY_ENCODER_CLK和ROTARY_ENCODER_DT都為0,則狀態為0
  51.         if((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT)) rotary_encoder_state=1;
  52.         else if((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)) rotary_encoder_state=0;
  53.        
  54.         //ROTARY_ENCODER_CLK和ROTARY_ENCODER_DT為同一電平時檢測
  55.         if(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
  56.         {
  57.                 //用最多150ms時間來等待ROTARY_ENCODER_CLK電平或ROTARY_ENCODER_DT電平變化(此時AB為11或00)
  58.                 forced_out=3000;
  59.                 while(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
  60.                 {
  61.                         --forced_out;
  62.                         rotary_encoder_delay50us();
  63.                         if(!forced_out) return 0xFF;//超時則強制退出,返回錯誤碼
  64.                 }
  65.                
  66.                 //每次電平變化必定旋轉了編碼器,電平變化后要消抖
  67.                 rotary_encoder_delay10ms();
  68.                
  69.                 //當ROTARY_ENCODER_CLK為低電平,ROTARY_ENCODER_DT為高電平時
  70.                 if((!ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))
  71.                 {
  72.                         //用150ms時間來等待ROTARY_ENCODER_DT電平變化(此時AB為01)
  73.                         forced_out=3000;
  74.                         while((!ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))
  75.                         {
  76.                                 --forced_out;
  77.                                 rotary_encoder_delay50us();
  78.                                 if(!forced_out) return 0xFF;//超時則強制退出,返回錯誤碼
  79.                         }
  80.                        
  81.                         //每次電平變化必定旋轉了編碼器,電平變化后要消抖
  82.                         rotary_encoder_delay10ms();
  83.                        
  84.                         //當ROTARY_ENCODER_CLK為低電平,而且ROTARY_ENCODER_DT也為低電平
  85.                         //或ROTARY_ENCODER_CLK為高電平,而且ROTARY_ENCODER_DT也為高電平(AB為11或00)
  86.                         //此時  AB從11到01到00  或  AB從00到01到11
  87.                         if(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
  88.                         {
  89.                                 //如果旋轉編碼器的狀態為1則返回1,代表正轉一下
  90.                                 if(rotary_encoder_state) return 1;
  91.                                 //如果旋轉編碼器的狀態為0則返回0,代表反轉一下
  92.                                 else return 0;
  93.                         }
  94.                         //若AB不為11或不為00則返回旋轉編碼器錯誤碼
  95.                         else return ROTARY_ENCODER_ERROR;
  96.                 }
  97.                 //當ROTARY_ENCODER_CLK為高電平,ROTARY_ENCODER_DT為低電平時
  98.                 else
  99.                 {
  100.                         //當ROTARY_ENCODER_CLK為高電平,ROTARY_ENCODER_DT為低電平時
  101.                         if((ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT))
  102.                         {
  103.                                 //用150ms時間來等待ROTARY_ENCODER_CLK電平變化(此時AB為10)
  104.                                 forced_out=3000;
  105.                                 while((ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT))
  106.                                 {
  107.                                         --forced_out;
  108.                                         rotary_encoder_delay50us();
  109.                                         if(!forced_out) return 0xFF;//超時則強制退出,返回錯誤碼
  110.                                 }
  111.                                
  112.                                 //每次電平變化必定旋轉了編碼器,電平變化后要消抖
  113.                                 rotary_encoder_delay10ms();
  114.                                
  115.                                 //當ROTARY_ENCODER_CLK為低電平,而且ROTARY_ENCODER_DT也為低電平
  116.                                 //或ROTARY_ENCODER_CLK為高電平,而且ROTARY_ENCODER_DT也為高電平(AB為11或00)
  117.                                 //此時  AB從11到10到00  或  AB從00到10到11
  118.                                 if(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
  119.                                 {
  120.                                         //如果旋轉編碼器的狀態為0則返回1,代表正轉一下
  121.                                         if(!rotary_encoder_state) return 1;
  122.                                         //如果旋轉編碼器的狀態為1則返回0,代表反轉一下
  123.                                         else return 0;
  124.                                 }
  125.                                 //若AB不為11或不為00則返回旋轉編碼器錯誤碼
  126.                                 else return ROTARY_ENCODER_ERROR;
  127.                         }
  128.                 }
  129.         }
  130.         //未響應返回旋轉編碼器錯誤碼
  131.         return 0xFF;
  132. }

  133. //旋轉編碼器中斷
  134. void rotary_encoder_interrupt() interrupt 0
  135. {
  136.         static u8 dat=0;
  137.         u8 temp=0xFF;//臨時變量先賦旋轉編碼器錯誤碼的值
  138.         if(!ROTARY_ENCODER_SW)//檢查按鍵是否按下
  139.         {
  140.                 rotary_encoder_delay10ms();//若按鍵按下,則消抖
  141.                 if(!ROTARY_ENCODER_SW)//再次檢查按鍵是否按下
  142.                 {
  143.                         while(!ROTARY_ENCODER_SW);//按鍵按住則程序卡死在這里
  144.                         rotary_encoder_delay10ms();//松手消抖
  145.                        
  146.                         LCD1602_print_char(0,0,'O');
  147.                         LCD1602_print_char(0,1,'N');
  148.                         LCD1602_print_char(0,2,' ');
  149.                        
  150.                         while(ROTARY_ENCODER_SW)//現在掃描旋轉編碼器
  151.                         {       
  152.                                 //掃描旋轉編碼器,返回值為1代表正轉,返回值為0代表反轉,返回值為0xFF代表未旋轉或旋轉錯誤
  153.                                 temp=scan_rotary_encoder();
  154.                                
  155.                                 if(temp!=0xFF)//去除旋轉編碼器錯誤碼
  156.                                 {
  157.                                         //利用 unsigned char 特性
  158.                                         //當temp為255時,再加1則溢出,變為0
  159.                                         //同理,當temp為0時,再減1則變為255
  160.                                         if(temp==0x01) ++dat;
  161.                                         if(temp==0x00) --dat;
  162.                                        
  163.                                         //LCD1602打印字符(行,列,字符)
  164.                                         LCD1602_print_char(1,0,'0'+(dat/100%10));
  165.                                         LCD1602_print_char(1,1,'0'+(dat/10%10));
  166.                                         LCD1602_print_char(1,2,'0'+(dat/1%10));
  167.                                 }
  168.                         }
  169.                         rotary_encoder_delay10ms();//按鍵按下,則消抖
  170.                        
  171.                         while(!ROTARY_ENCODER_SW);//按鍵按住則程序卡死在這里
  172.                         rotary_encoder_delay10ms();//松手消抖
  173.                        
  174.                         LCD1602_print_char(0,0,'O');
  175.                         LCD1602_print_char(0,1,'F');
  176.                         LCD1602_print_char(0,2,'F');
  177.                 }
  178.         }
  179. }
復制代碼

鏈接:
游客,本帖隱藏的內容需要積分高于 1 才可瀏覽,您當前積分為 0

全部資料51hei下載地址:

旋轉編碼器測試代碼.rar (1.44 MB, 下載次數: 138)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:658665 發表于 2020-7-21 21:32 | 顯示全部樓層
我實在找不到編輯按鈕在哪了,直接發吧

旋轉編碼器V1.1版
測試平臺:STC89C516單片機        12MHz晶振
其他平臺可能要在RotaryEncoder.c文件中修改延時函數
接口定義在port.h文件中

版本特性:

1.旋轉編碼器程序加入旋轉編碼器按鍵的單擊雙擊以及長按
2.精簡旋轉編碼器代碼
旋轉編碼器V1.1.rar (35.09 KB, 下載次數: 47)
回復

使用道具 舉報

ID:748377 發表于 2020-5-10 17:21 | 顯示全部樓層
謝謝分享,我試了下在仿真里數值似乎沒有變化啊
回復

使用道具 舉報

ID:658665 發表于 2020-5-11 08:12 | 顯示全部樓層
深海咸魚 發表于 2020-5-10 17:21
謝謝分享,我試了下在仿真里數值似乎沒有變化啊

這段代碼我沒有用仿真測試過,都是用實物測試的,下面的GIF是實物測試
b26cdbb381f849e2a540218d01265ba5 00_00_00-00_00_30.gif

回復

使用道具 舉報

ID:799404 發表于 2020-7-9 11:43 | 顯示全部樓層
這不是正交信號嗎,怎么你編碼器的絲印都是串行輸出的
回復

使用道具 舉報

ID:514317 發表于 2020-7-22 08:30 | 顯示全部樓層
樓主用的中斷方式   占用1個中斷     代碼中的11   00這兩個狀態很關鍵      配合01 10就能很準確的判斷方向
回復

使用道具 舉報

ID:56960 發表于 2020-7-22 09:28 | 顯示全部樓層
我贊同樓上的意見,根據狀態 判斷出   旋轉方向,是正轉還是反轉
回復

使用道具 舉報

ID:833183 發表于 2020-10-26 16:44 | 顯示全部樓層
樓主e6b2cwz6c編碼器用過嗎?這種三相的脈沖輸出應該怎么做
回復

使用道具 舉報

ID:605142 發表于 2021-2-27 15:15 | 顯示全部樓層
GGG.gif
用103做了一個,用按鈕模擬是對的,我沒有編碼器,用壞鼠標里的滾輪接上,竟然亂跑,一會加一會減,難道是滾輪壞了
回復

使用道具 舉報

ID:605142 發表于 2021-2-27 15:28 | 顯示全部樓層
51hei圖片20210227152550.png
拆開后是這個樣子了,看來要打磨一下
回復

使用道具 舉報

ID:275826 發表于 2021-3-2 09:10 | 顯示全部樓層
太復雜了,看了頭通,可以優化吧
回復

使用道具 舉報

ID:743823 發表于 2021-6-12 08:14 | 顯示全部樓層
樓主,你好,我需要增加2個LED燈,正轉=LED1;反正=LED2;來測試編碼器方向,如何增加,求大家指點下
回復

使用道具 舉報

ID:789448 發表于 2021-12-25 15:28 | 顯示全部樓層
好東西!給無私奉獻點個贊!
回復

使用道具 舉報

ID:69115 發表于 2021-12-26 00:41 | 顯示全部樓層
這個旋轉編碼器程序程序,寫的太復雜了.應該幾行C代碼就可以實現.
當A相在剛導通的瞬間,同時檢測B相是否也接通,若沒有接通,說明A相先接通是正轉
若B相已經接通,說明B相已經先接通了,是反轉
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产xxxx搡xxxxx搡麻豆 | 91亚洲免费 | 成人久草 | 成人深夜小视频 | 日韩视频在线播放 | 亚洲在线久久 | 老牛影视av一区二区在线观看 | 亚洲精品1| 欧美lesbianxxxxhd视频社区 | 农夫在线精品视频免费观看 | 中文字幕亚洲精品 | 自拍偷拍亚洲一区 | 国产精品亚洲综合 | 天天插天天狠天天透 | 黄色激情毛片 | av中文网| 欧美成人aaa级毛片在线视频 | 在线国产一区 | 中国一级特黄真人毛片免费观看 | 天堂久久网 | 中文字幕在线不卡播放 | 在线亚洲欧美 | 亚洲不卡| 亚洲精品www久久久 www.蜜桃av | 91久久国产精品 | 91精品一区二区三区久久久久 | 国产一级特黄aaa大片评分 | av官网在线 | 久久综合一区 | 亚洲欧美综合 | 97视频网站 | 日韩欧美在线视频 | 能看的av| 天天综合网永久 | 天天夜夜人人 | 99久久婷婷国产综合精品电影 | 99精品免费在线观看 | 久久夜视频 | 久久久久久久久久久91 | 国产精品久久久久一区二区三区 | 密桃av|