標題: 51單片機旋轉(zhuǎn)編碼器模塊測試代碼 [打印本頁]
作者: pengxxx 時間: 2020-5-5 15:28
標題: 51單片機旋轉(zhuǎn)編碼器模塊測試代碼
模塊圖片
旋轉(zhuǎn)編碼器.jpg (1.18 MB, 下載次數(shù): 108)
下載附件
2020-5-5 15:18 上傳
測試平臺:STC89C516單片機 晶振:12MHz
其他單片機(如STC12單片機)或晶振,請在程序的LCD1602.c和rotary_encoder.c文件中修改延時函數(shù)
連線如圖(連線的接口在程序的port.h文件里)
旋轉(zhuǎn)編碼器連線.jpg (1.57 MB, 下載次數(shù): 90)
下載附件
2020-5-5 15:18 上傳
測試代碼功能:
將程序下載到開發(fā)板,LCD顯示0FF,顯示數(shù)字000.
按下旋轉(zhuǎn)編碼器的按鍵,OFF變?yōu)?/font>ON,轉(zhuǎn)動旋轉(zhuǎn)編碼器就可以在LCD1602中看到數(shù)字變化.
再次按下旋轉(zhuǎn)按鍵,ON變?yōu)?/font>OFF,此時轉(zhuǎn)動旋轉(zhuǎn)編碼器不可以在LCD1602中看到數(shù)字變化.
結(jié)尾:
測試程序的注釋也比較詳細,自我感覺這個程序?qū)^慢的轉(zhuǎn)速和正常的轉(zhuǎn)速的兼容性都比較好,只有極少數(shù)情況出現(xiàn)丟步,已經(jīng)實現(xiàn)較好的實現(xiàn)了旋轉(zhuǎn)編碼器的功能了.
本帖測試程序參考過以下帖子
http://www.torrancerestoration.com/bbs/dpj-93972-1.html
單片機源程序如下:
- #include <intrins.h>
- #include "public.h"
- #include "rotary_encoder.h"
- #include "LCD1602.h"
- #include "port.h"
- void rotary_encoder_delay50us()//12.000MHz
- {
- u8 i;
- _nop_();
- i=22;
- while(--i);
- }
- void rotary_encoder_delay10ms() //12.000MHz
- {
- u8 i,j;
- i=20;
- j=113;
- do
- {
- while (--j);
- }while (--i);
- }
- //旋轉(zhuǎn)編碼器初始化
- void rotary_encoder_init()
- {
- ROTARY_ENCODER_CLK=1;
- ROTARY_ENCODER_DT=1;
- ROTARY_ENCODER_SW=1;
-
- IT0=1;
- EX0=1;
- EA=1;
-
- LCD1602_print_char(0,0,'O');
- LCD1602_print_char(0,1,'F');
- LCD1602_print_char(0,2,'F');
-
- LCD1602_print_char(1,0,'0'+0);
- LCD1602_print_char(1,1,'0'+0);
- LCD1602_print_char(1,2,'0'+0);
- }
- //掃描旋轉(zhuǎn)編碼器,返回值為1代表正轉(zhuǎn),返回值為0代表反轉(zhuǎn),返回值為0xFF代表未旋轉(zhuǎn)或旋轉(zhuǎn)錯誤
- u8 scan_rotary_encoder()
- {
- u8 rotary_encoder_state;//旋轉(zhuǎn)編碼器狀態(tài)
- u16 forced_out;//強制退出
-
- //旋轉(zhuǎn)編碼器狀態(tài)
- //如果在剛開始ROTARY_ENCODER_CLK和ROTARY_ENCODER_DT都為1,則狀態(tài)為1
- //如果在剛開始ROTARY_ENCODER_CLK和ROTARY_ENCODER_DT都為0,則狀態(tài)為0
- if((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT)) rotary_encoder_state=1;
- else if((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)) rotary_encoder_state=0;
-
- //ROTARY_ENCODER_CLK和ROTARY_ENCODER_DT為同一電平時檢測
- if(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
- {
- //用最多150ms時間來等待ROTARY_ENCODER_CLK電平或ROTARY_ENCODER_DT電平變化(此時AB為11或00)
- forced_out=3000;
- while(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
- {
- --forced_out;
- rotary_encoder_delay50us();
- if(!forced_out) return 0xFF;//超時則強制退出,返回錯誤碼
- }
-
- //每次電平變化必定旋轉(zhuǎn)了編碼器,電平變化后要消抖
- rotary_encoder_delay10ms();
-
- //當ROTARY_ENCODER_CLK為低電平,ROTARY_ENCODER_DT為高電平時
- if((!ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))
- {
- //用150ms時間來等待ROTARY_ENCODER_DT電平變化(此時AB為01)
- forced_out=3000;
- while((!ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))
- {
- --forced_out;
- rotary_encoder_delay50us();
- if(!forced_out) return 0xFF;//超時則強制退出,返回錯誤碼
- }
-
- //每次電平變化必定旋轉(zhuǎn)了編碼器,電平變化后要消抖
- rotary_encoder_delay10ms();
-
- //當ROTARY_ENCODER_CLK為低電平,而且ROTARY_ENCODER_DT也為低電平
- //或ROTARY_ENCODER_CLK為高電平,而且ROTARY_ENCODER_DT也為高電平(AB為11或00)
- //此時 AB從11到01到00 或 AB從00到01到11
- if(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
- {
- //如果旋轉(zhuǎn)編碼器的狀態(tài)為1則返回1,代表正轉(zhuǎn)一下
- if(rotary_encoder_state) return 1;
- //如果旋轉(zhuǎn)編碼器的狀態(tài)為0則返回0,代表反轉(zhuǎn)一下
- else return 0;
- }
- //若AB不為11或不為00則返回旋轉(zhuǎn)編碼器錯誤碼
- else return ROTARY_ENCODER_ERROR;
- }
- //當ROTARY_ENCODER_CLK為高電平,ROTARY_ENCODER_DT為低電平時
- else
- {
- //當ROTARY_ENCODER_CLK為高電平,ROTARY_ENCODER_DT為低電平時
- if((ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT))
- {
- //用150ms時間來等待ROTARY_ENCODER_CLK電平變化(此時AB為10)
- forced_out=3000;
- while((ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT))
- {
- --forced_out;
- rotary_encoder_delay50us();
- if(!forced_out) return 0xFF;//超時則強制退出,返回錯誤碼
- }
-
- //每次電平變化必定旋轉(zhuǎn)了編碼器,電平變化后要消抖
- rotary_encoder_delay10ms();
-
- //當ROTARY_ENCODER_CLK為低電平,而且ROTARY_ENCODER_DT也為低電平
- //或ROTARY_ENCODER_CLK為高電平,而且ROTARY_ENCODER_DT也為高電平(AB為11或00)
- //此時 AB從11到10到00 或 AB從00到10到11
- if(((ROTARY_ENCODER_CLK)&&(ROTARY_ENCODER_DT))||((!ROTARY_ENCODER_CLK)&&(!ROTARY_ENCODER_DT)))
- {
- //如果旋轉(zhuǎn)編碼器的狀態(tài)為0則返回1,代表正轉(zhuǎn)一下
- if(!rotary_encoder_state) return 1;
- //如果旋轉(zhuǎn)編碼器的狀態(tài)為1則返回0,代表反轉(zhuǎn)一下
- else return 0;
- }
- //若AB不為11或不為00則返回旋轉(zhuǎn)編碼器錯誤碼
- else return ROTARY_ENCODER_ERROR;
- }
- }
- }
- //未響應返回旋轉(zhuǎn)編碼器錯誤碼
- return 0xFF;
- }
- //旋轉(zhuǎn)編碼器中斷
- void rotary_encoder_interrupt() interrupt 0
- {
- static u8 dat=0;
- u8 temp=0xFF;//臨時變量先賦旋轉(zhuǎn)編碼器錯誤碼的值
- if(!ROTARY_ENCODER_SW)//檢查按鍵是否按下
- {
- rotary_encoder_delay10ms();//若按鍵按下,則消抖
- if(!ROTARY_ENCODER_SW)//再次檢查按鍵是否按下
- {
- while(!ROTARY_ENCODER_SW);//按鍵按住則程序卡死在這里
- rotary_encoder_delay10ms();//松手消抖
-
- LCD1602_print_char(0,0,'O');
- LCD1602_print_char(0,1,'N');
- LCD1602_print_char(0,2,' ');
-
- while(ROTARY_ENCODER_SW)//現(xiàn)在掃描旋轉(zhuǎn)編碼器
- {
- //掃描旋轉(zhuǎn)編碼器,返回值為1代表正轉(zhuǎn),返回值為0代表反轉(zhuǎn),返回值為0xFF代表未旋轉(zhuǎn)或旋轉(zhuǎn)錯誤
- temp=scan_rotary_encoder();
-
- if(temp!=0xFF)//去除旋轉(zhuǎn)編碼器錯誤碼
- {
- //利用 unsigned char 特性
- //當temp為255時,再加1則溢出,變?yōu)?
- //同理,當temp為0時,再減1則變?yōu)?55
- if(temp==0x01) ++dat;
- if(temp==0x00) --dat;
-
- //LCD1602打印字符(行,列,字符)
- LCD1602_print_char(1,0,'0'+(dat/100%10));
- LCD1602_print_char(1,1,'0'+(dat/10%10));
- LCD1602_print_char(1,2,'0'+(dat/1%10));
- }
- }
- rotary_encoder_delay10ms();//按鍵按下,則消抖
-
- while(!ROTARY_ENCODER_SW);//按鍵按住則程序卡死在這里
- rotary_encoder_delay10ms();//松手消抖
-
- LCD1602_print_char(0,0,'O');
- LCD1602_print_char(0,1,'F');
- LCD1602_print_char(0,2,'F');
- }
- }
- }
復制代碼
鏈接:
全部資料51hei下載地址:
旋轉(zhuǎn)編碼器測試代碼.rar
(1.44 MB, 下載次數(shù): 138)
2020-5-5 15:24 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者: 深海咸魚 時間: 2020-5-10 17:21
謝謝分享,我試了下在仿真里數(shù)值似乎沒有變化啊
作者: pengxxx 時間: 2020-5-11 08:12
這段代碼我沒有用仿真測試過,都是用實物測試的,下面的GIF是實物測試
b26cdbb381f849e2a540218d01265ba5 00_00_00-00_00_30.gif (10.57 MB, 下載次數(shù): 146)
下載附件
2020-5-11 08:11 上傳
作者: wjianing 時間: 2020-7-9 11:43
這不是正交信號嗎,怎么你編碼器的絲印都是串行輸出的
作者: pengxxx 時間: 2020-7-21 21:32
我實在找不到編輯按鈕在哪了,直接發(fā)吧
旋轉(zhuǎn)編碼器V1.1版
測試平臺:STC89C516單片機 12MHz晶振
其他平臺可能要在RotaryEncoder.c文件中修改延時函數(shù)
接口定義在port.h文件中
版本特性:
1.旋轉(zhuǎn)編碼器程序加入旋轉(zhuǎn)編碼器按鍵的單擊雙擊以及長按
2.精簡旋轉(zhuǎn)編碼器代碼
旋轉(zhuǎn)編碼器V1.1.rar
(35.09 KB, 下載次數(shù): 47)
2020-7-21 21:28 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
鏈接:https://pan.baidu.com/s/1DDse2uiioNi6ByMBjVnB2Q
提取碼:peng
作者: lzzasd 時間: 2020-7-22 08:30
樓主用的中斷方式 占用1個中斷 代碼中的11 00這兩個狀態(tài)很關(guān)鍵 配合01 10就能很準確的判斷方向
作者: 滄海一粒 時間: 2020-7-22 09:28
我贊同樓上的意見,根據(jù)狀態(tài) 判斷出 旋轉(zhuǎn)方向,是正轉(zhuǎn)還是反轉(zhuǎn)
作者: scorpioxz 時間: 2020-10-26 16:44
樓主e6b2cwz6c編碼器用過嗎?這種三相的脈沖輸出應該怎么做
作者: hefq 時間: 2021-2-27 15:15
GGG.gif (212.56 KB, 下載次數(shù): 84)
下載附件
2021-2-27 15:14 上傳
用103做了一個,用按鈕模擬是對的,我沒有編碼器,用壞鼠標里的滾輪接上,竟然亂跑,一會加一會減,難道是滾輪壞了
作者: hefq 時間: 2021-2-27 15:28
51hei圖片20210227152550.png (1.41 MB, 下載次數(shù): 62)
下載附件
2021-2-27 15:27 上傳
拆開后是這個樣子了,看來要打磨一下
作者: tyrl800 時間: 2021-3-2 09:10
太復雜了,看了頭通,可以優(yōu)化吧
作者: 985524550 時間: 2021-6-12 08:14
樓主,你好,我需要增加2個LED燈,正轉(zhuǎn)=LED1;反正=LED2;來測試編碼器方向,如何增加,求大家指點下
作者: zhycong 時間: 2021-12-25 15:28
好東西!給無私奉獻點個贊!
作者: xiexugang 時間: 2021-12-26 00:41
這個旋轉(zhuǎn)編碼器程序程序,寫的太復雜了.應該幾行C代碼就可以實現(xiàn).
當A相在剛導通的瞬間,同時檢測B相是否也接通,若沒有接通,說明A相先接通是正轉(zhuǎn)
若B相已經(jīng)接通,說明B相已經(jīng)先接通了,是反轉(zhuǎn)
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |