|
前幾天看到論壇里的舊帖《自己動(dòng)手制作 “POV LED” 旋轉(zhuǎn)LED顯示屏》,文中樓主提到......外部中斷函數(shù)產(chǎn)生了兩次以上......
估計(jì)就是霍爾傳感器接到外部中斷IO上。實(shí)際磁鋼每次經(jīng)過(guò)霍爾元件時(shí),單片機(jī)觸發(fā)了兩次或多次外部中斷。這使我想起前一陣子的自制繞線機(jī)的事情。
前一陣子,有個(gè)電路上需要壓電陶瓷片,得用自制磁芯變壓器。初級(jí)10繞制00圈,次級(jí)是30和60圈。
希望繞線時(shí)能控制銅線位置,這樣初級(jí)每層銅線比較整齊,所以要求繞線速度必須要低。后來(lái)發(fā)現(xiàn)用兩節(jié)七號(hào)鎳氫電池給TT直流減速電機(jī)供電,轉(zhuǎn)速差不多一秒一圈。速度低,比較合適,我可以拉著銅線,適時(shí)調(diào)整繞線銅線位置。
減速電機(jī)軸一端套上碼盤,另一端套上變壓器骨架的。當(dāng)時(shí),先用的紅外對(duì)射模塊(其他名稱有測(cè)速傳感器模塊 計(jì)數(shù)器模塊 電機(jī)測(cè)試模塊 槽型光耦模塊等等),碼盤上有20個(gè)孔,用黑膠帶封了19個(gè),只留下一個(gè)孔,這樣碼盤轉(zhuǎn)動(dòng)一圈,紅外模塊只會(huì)輸出一次下降沿。
單片機(jī)程序下載后,運(yùn)行時(shí)發(fā)現(xiàn),實(shí)際數(shù)碼管上的計(jì)數(shù)數(shù)值不是按一遞增的,大多數(shù)時(shí)候是按二遞增的,偶爾會(huì)按一遞增或按三、四遞增的。
以為是紅外模塊有故障,換了一個(gè),現(xiàn)象依舊。換傳感器,在碼盤邊緣粘上一個(gè)小磁鋼,換用霍爾傳感器模塊,單片機(jī)運(yùn)行時(shí)也是同樣的現(xiàn)象。
奇怪了,當(dāng)時(shí)因?yàn)橹庇米儔浩鳎瑳]再分析故障了,在代碼里面計(jì)數(shù)數(shù)值除以二,結(jié)果再顯示在數(shù)碼管上。按此方法繞制了磁芯變壓器,裝上電路可正常工作的。后來(lái)就沒有再查找這個(gè)計(jì)數(shù)故障了。
碼盤紅外模塊電機(jī)安裝總成.JPG (66.47 KB, 下載次數(shù): 99)
下載附件
2018-6-28 21:39 上傳
直到看到那個(gè)舊帖,才想起來(lái),也有人遇到同樣的問題了(樓主當(dāng)時(shí)還是個(gè)初中生,真厲害。。。
但對(duì)樓主分析的原因不敢茍同,于是翻了翻單片機(jī)教程和幾本書,有了自己的想法。
以下是個(gè)人看法,業(yè)余水平,歡迎各位看官拍磚。
無(wú)論是紅外對(duì)射模塊,還是霍爾傳感器,其實(shí)電路上就是運(yùn)放比較器,比較器是能穩(wěn)定可靠工作的,應(yīng)該不是故障源頭。問題應(yīng)該集中在紅外發(fā)射接收對(duì)管和霍爾元件裝置上。
紅外發(fā)射管發(fā)射的紅外線光束是散射的。不像激光那樣筆直和纖細(xì)。減速軸上安裝的碼盤也沒有和紅外對(duì)射模塊嚴(yán)格定位,做到碼盤平面與對(duì)射光軸嚴(yán)格垂直。由于碼盤還在運(yùn)動(dòng),難免有抖動(dòng)的。那么光電接收管收到的紅外光很可能既有發(fā)射管直射過(guò)來(lái)的,也包括從碼盤小孔側(cè)壁上反射過(guò)來(lái)的,甚至還可能還包括衍射過(guò)來(lái)的紅外光。
主要因?yàn)闄C(jī)械抖動(dòng)或振動(dòng),紅外線的傳播有了多個(gè)路徑,多個(gè)路徑傳播的紅外線中就有那么幾個(gè)光線強(qiáng)度足以致模塊輸出了低電平信號(hào),也就有了下降沿。霍爾元件和磁鋼也是類似的。若是有示波器或邏輯分析儀,抓取一段,就能看到這個(gè)直觀現(xiàn)象的。
還記得機(jī)械按鍵嘛,使用時(shí)必須“消抖”,否則就可能出現(xiàn)多次中斷的情況。既然如此,那就“消抖”是了。
人手按按鍵,前后幾十毫秒的時(shí)間,和機(jī)械按鍵不一樣的是,這里機(jī)械抖動(dòng)或振動(dòng)很可能不到一毫秒,需要實(shí)測(cè)才知道的。我沒有那些測(cè)試設(shè)備,那么就用笨辦法,一個(gè)一個(gè)地試驗(yàn)。哪位有條件的,抽空抓取一段看看。所以,消抖的方法不能像機(jī)械按鍵那么簡(jiǎn)單的。
我想到的辦法是單穩(wěn)態(tài)電路。
收到外部觸發(fā)信號(hào)后,電路被觸發(fā),進(jìn)入單穩(wěn)態(tài);
單穩(wěn)態(tài)時(shí)間要稍長(zhǎng),這樣就無(wú)視后來(lái)的幾個(gè)觸發(fā)信號(hào)了;
單穩(wěn)態(tài)時(shí)間也不能太長(zhǎng),以免影響下一次正常的觸發(fā)信號(hào)。
555.JPG (31 KB, 下載次數(shù): 118)
下載附件
2018-6-28 21:40 上傳
我用的是555時(shí)基集成電路,多試了幾個(gè)電容和電阻,調(diào)整了RC參數(shù),計(jì)數(shù)就正確了。最后用的是0.1微法的電解電容和150歐姆的電阻,計(jì)算時(shí)間常數(shù)是1.1*0.1*150=16.5微秒。想通了,就簡(jiǎn)單了!
555面包板.JPG (62.1 KB, 下載次數(shù): 107)
下載附件
2018-6-28 21:41 上傳
8位數(shù)碼管.JPG (43.7 KB, 下載次數(shù): 100)
下載附件
2018-6-28 21:46 上傳
后來(lái),換用碼盤,沒有遮孔的,計(jì)數(shù)也正常了。減速電機(jī)換用4節(jié)鎳氫電池供電,提高轉(zhuǎn)速(大概2、3圈每秒),計(jì)數(shù)也是正常的。
整裝.JPG (44.4 KB, 下載次數(shù): 90)
下載附件
2018-6-28 21:41 上傳
準(zhǔn)備繞線了。
視頻太大附件也傳不了的。
繞完了.JPG (79.97 KB, 下載次數(shù): 89)
下載附件
2018-6-28 21:47 上傳
繞完了。
當(dāng)然了,若是用在其他更高速的地方,估計(jì)還得再調(diào)整RC參數(shù)的。
單片機(jī)源程序如下:
- #include<reg52.h>
- sbit flashLed=P1^1; //閃爍燈
- unsigned char T0RH = 0; //T0重載值的高字節(jié)
- unsigned char T0RL = 0; //T0重載值的低字節(jié)
- unsigned int uiCount=0;
- bit flag200ms=0;
- unsigned char code Tab[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x7F,0xFF};
- unsigned char ledChar[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
- /* 配置并啟動(dòng)T0,ms-T0定時(shí)時(shí)間 */
- void ConfigTimer0(unsigned int ms)
- {
- unsigned long tmp;
- tmp = 11059200 / 12;
- tmp = (tmp * ms) / 1000;
- tmp = 65536 - tmp;
- tmp = tmp + 18;
- T0RH = (unsigned char)(tmp>>8);
- T0RL = (unsigned char)tmp;
- TMOD &= 0xF0;
- TMOD |= 0x01;
- TH0 = T0RH;
- TL0 = T0RL;
- ET0 = 1;
- TR0 = 1;
- }
- void LedScan()
- {
- static unsigned char i = 0; //動(dòng)態(tài)掃描索引
- unsigned char location=0x01;
- P0=0xFF; //關(guān)閉所有段選位,顯示消隱
- P2=0xff;
- location=location<<i;
- location=~location;
- P0=ledChar[i];
- P2=location;
- i++;
- i=i%8;
- }
- /* T0中斷服務(wù)函數(shù),執(zhí)行數(shù)碼管掃描顯示 */
- void InterruptTimer0() interrupt 1
- {
- static unsigned char tc=0;
- tc++;
- TH0 = T0RH; //重新加載重載值
- TL0 = T0RL;
- if(tc==200)
- {
- tc=0;
- flag200ms=1;
- flashLed=~flashLed;
- }
- LedScan(); //數(shù)碼管掃描顯示
- }
- //外部中斷函數(shù)
- void INT0_Count() interrupt 0
- {
- uiCount++;
- }
- void main(void)
- {
- unsigned char k=0;
- unsigned int uiTmp=0;
- EX0=1; //允許外部中斷INT0中斷
- IT0=1; //外部中斷INT0采用脈沖負(fù)跳變觸發(fā)方式
- EA = 1;
- uiCount=0;
- ConfigTimer0(1); //配置T0定時(shí)1ms
- while (1)
- {
- if(flag200ms)
- {
- flag200ms=0;
- uiTmp=uiCount;
- for(k=0;k<8;k++)
- ledChar[k]=0xff;
- ledChar[7]=Tab[uiTmp%10];
- if(uiTmp>=10)
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
繞線計(jì)數(shù)器a51程序.zip
(24.56 KB, 下載次數(shù): 29)
2018-6-28 21:49 上傳
點(diǎn)擊文件名下載附件
51程序 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|