溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

28BYJ-48步進電機掌握程序是怎樣的

發(fā)布時間:2022-01-10 09:27:32 來源:億速云 閱讀:127 作者:柒染 欄目:網(wǎng)絡安全

今天給大家介紹一下28BYJ-48步進電機掌握程序是怎樣的。,文章的內(nèi)容小編覺得不錯,現(xiàn)在給大家分享一下,覺得有需要的朋友可以了解一下,希望對大家有所幫助,下面跟著小編的思路一起來閱讀吧。

下面我們固然完成了用中綴掌握電機遷移轉(zhuǎn)變的程序,但實踐上這個程序照樣沒若干適用價值的,我們不克不及每次想讓它遷移轉(zhuǎn)變的時分都上下電啊,是吧。還有就是它不只能正轉(zhuǎn)還得能反轉(zhuǎn)啊,也就是說不只能轉(zhuǎn)過來,還得能轉(zhuǎn)回來呀。好吧,我們就來做一個實例程序吧,聯(lián)合第 8 章的按鍵程序,我們設計如許一個功用程序:按數(shù)字鍵 1~9,掌握電機轉(zhuǎn)過 1~9 圈;合營上下鍵改動遷移轉(zhuǎn)變偏向,按向上鍵后正向轉(zhuǎn) 1~9 圈,向下鍵則反向轉(zhuǎn) 1~9 圈;左鍵固定正轉(zhuǎn) 90 度,右鍵固定反轉(zhuǎn) 90;Esc 鍵終止遷移轉(zhuǎn)變。經(jīng)過這個程序,我們也可以進一步領(lǐng)會到若何用按鍵來掌握程序完成復雜的功用,以及掌握和履行模塊之間若何調(diào)和任務,而你的編程程度也可以在如許的理論演習中失掉錘煉和晉升。

			#include <reg52.h> sbit KEY_IN_1 = P2^4; sbit KEY_IN_2 = P2^5; sbit KEY_IN_3 = P2^6; sbit KEY_IN_4 = P2^7; sbit KEY_OUT_1 = P2^3; sbit KEY_OUT_2 = P2^2; sbit KEY_OUT_3 = P2^1; sbit KEY_OUT_4 = P2^0; unsigned char code KeyCodeMap[4][4] = { //矩陣按鍵編號到規(guī)范鍵盤鍵碼的映射表 { 0x31, 0x32, 0x33, 0x26 }, //數(shù)字鍵 1、數(shù)字鍵 2、數(shù)字鍵 3、向上鍵 { 0x34, 0x35, 0x36, 0x25 }, //數(shù)字鍵 4、數(shù)字鍵 5、數(shù)字鍵 6、向左鍵 { 0x37, 0x38, 0x39, 0x28 }, //數(shù)字鍵 7、數(shù)字鍵 8、數(shù)字鍵 9、向下鍵 { 0x30, 0x1B, 0x0D, 0x27 } //數(shù)字鍵 0、ESC 鍵、 回車鍵、 向右鍵 }; unsigned char KeySta[4][4] = { //全體矩陣按鍵的以后形態(tài) {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} }; signed long beats = 0; //電機遷移轉(zhuǎn)變節(jié)奏總數(shù) void KeyDriver(); void main(){ EA = 1; //使能總中綴 TMOD = 0x01; //設置 T0 為形式 1 TH0 = 0xFC; //為 T0 賦初值 0xFC67,準時 1ms TL0 = 0x67; ET0 = 1; //使能 T0 中綴 TR0 = 1; //啟動 T0 while (1){ KeyDriver(); //挪用按鍵驅(qū)動函數(shù) } } /* 步進電機啟動函數(shù),angle-需轉(zhuǎn)過的角度 */ void StartMotor(signed long angle){ //在盤算前封閉中綴,完成后再翻開,以防止中綴打斷盤算進程而形成毛病 EA = 0; beats = (angle * 4076) / 360; //實測為 4076 拍遷移轉(zhuǎn)變一圈 EA = 1; } /* 步進電機中止函數(shù) */ void StopMotor(){ EA = 0; beats = 0; EA = 1; } /* 按鍵舉措函數(shù),依據(jù)鍵碼履行響應的操作,keycode-按鍵鍵碼 */ void KeyAction(unsigned char keycode){ static bit dirMotor = 0; //電機遷移轉(zhuǎn)變偏向 //掌握電機遷移轉(zhuǎn)變 1-9 圈 if ((keycode>=0x30) && (keycode<=0x39)){ if (dirMotor == 0){ StartMotor(360*(keycode-0x30)); }else{ StartMotor(-360*(keycode-0x30)); } }else if (keycode == 0x26){ //向上鍵,掌握遷移轉(zhuǎn)變偏向為正轉(zhuǎn) dirMotor = 0; }else if (keycode == 0x28){ //向下鍵,掌握遷移轉(zhuǎn)變偏向為反轉(zhuǎn) dirMotor = 1; }else if (keycode == 0x25){ //向左鍵,固定正轉(zhuǎn) 90 度 StartMotor(90); }else if (keycode == 0x27){ //向右鍵,固定反轉(zhuǎn) 90 度 StartMotor(-90); }else if (keycode == 0x1B){ //Esc 鍵,中止遷移轉(zhuǎn)變 StopMotor(); } } /* 按鍵驅(qū)動函數(shù),檢測按鍵舉措,調(diào)劑響應舉措函數(shù),需在主輪回中挪用 */ void KeyDriver(){ unsigned char i, j; static unsigned char backup[4][4] = { //按鍵值備份,保管前一次的值 {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} }; for (i=0; i<4; i++){ //輪回檢測 4*4 的矩陣按鍵 for (j=0; j<4; j++){ if (backup[i][j] != KeySta[i][j]){ //檢測按鍵舉措 if (backup[i][j] != 0){ //按鍵按下時履行舉措 KeyAction(KeyCodeMap[i][j]); //挪用按鍵舉措函數(shù) } backup[i][j] = KeySta[i][j]; //刷新前一次的備份值 } } } } /* 按鍵掃描函數(shù),需在準時中綴中挪用,引薦挪用距離 1ms */ void KeyScan(){ unsigned char i; static unsigned char keyout = 0; //矩陣按鍵掃描輸入索引 static unsigned char keybuf[4][4] = { //矩陣按鍵掃描緩沖區(qū) {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF} }; //將一行的 4 個按鍵值移入緩沖區(qū) keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1; keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2; keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3; keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4; //消抖后更新按鍵形態(tài) for (i=0; i<4; i++){ //每行 4 個按鍵,所以輪回 4 次 if ((keybuf[keyout][i] & 0x0F) == 0x00){ //延續(xù) 4 次掃描值為 0,即 4*4ms 內(nèi)多是按下形態(tài)時,可以為按鍵已波動的按下 KeySta[keyout][i] = 0; }else if ((keybuf[keyout][i] & 0x0F) == 0x0F){ //延續(xù) 4 次掃描值為 1,即 4*4ms 內(nèi)多是彈起形態(tài)時,可以為按鍵已波動的彈起 KeySta[keyout][i] = 1; } } //履行下一次的掃描輸入 keyout++; //輸入索引遞增 keyout = keyout & 0x03; //索引值加到 4 即歸零 //依據(jù)索引,釋放以后輸入引腳,拉低下次的輸入引腳 switch (keyout){ case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; default: break; } } /* 電機遷移轉(zhuǎn)變掌握函數(shù) */ void TurnMotor(){ unsigned char tmp; //暫時變量 static unsigned char index = 0; //節(jié)奏輸入索引 unsigned char code BeatCode[8] = { //步進電機節(jié)奏對應的 IO 掌握代碼 0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6 }; if (beats != 0){ //節(jié)奏數(shù)不為 0 則發(fā)生一個驅(qū)動節(jié)奏 if (beats > 0){ //節(jié)奏數(shù)大于 0 時正轉(zhuǎn) index++; //正轉(zhuǎn)時節(jié)奏輸入索引遞增 index = index & 0x07; //用&操作完成到 8 歸零 beats--; //正轉(zhuǎn)時節(jié)奏計數(shù)遞加 }else{ //節(jié)奏數(shù)小于 0 時反轉(zhuǎn) index--; //反轉(zhuǎn)時節(jié)奏輸入索引遞加 index = index & 0x07; //用&操作異樣可以完成到-1 時歸 7 beats++; //反轉(zhuǎn)時節(jié)奏計數(shù)遞增 } tmp = P1; //用 tmp 把 P1 口以后值暫存 tmp = tmp & 0xF0; //用&操作清零低 4 位 tmp = tmp | BeatCode[index]; //用|操作把節(jié)奏代碼寫到低 4 位 P1 = tmp; //把低 4 位的節(jié)奏代碼和高 4 位的原值送回 P1 }else{ //節(jié)奏數(shù)為 0 則封閉電機一切的相 P1 = P1 | 0x0F; } } /* T0 中綴效勞函數(shù),用于按鍵掃描與電機遷移轉(zhuǎn)變掌握 */ void InterruptTimer0() interrupt 1{ static bit div = 0; TH0 = 0xFC; //從新加載初值 TL0 = 0x67; KeyScan(); //履行按鍵掃描 //用一個靜態(tài) bit 變量完成二分頻,即 2ms 準時,用于掌握電機 div = ~div; if (div == 1){ TurnMotor(); } }

這個程序是第 8 章和本章常識的一個綜合——用按鍵掌握步進電機遷移轉(zhuǎn)變。程序中有這么幾點值得留意,我們分述如下:

  • 針對電機要完成正轉(zhuǎn)和反轉(zhuǎn)兩個分歧的操作,我們并沒有運用正轉(zhuǎn)啟動函數(shù)和反轉(zhuǎn)啟動函數(shù)這么兩個函數(shù)來完成,也沒有在啟動函數(shù)界說的時分添加一個方式參數(shù)來指明其偏向。我們這里的啟動函數(shù) void StartMotor(signed long angle)與單向正轉(zhuǎn)時的啟動函數(shù)獨一的差別就是把方式參數(shù) angle 的類型從 unsigned long 改為了 signed long,我們用有符號數(shù)固有的正負特征來辨別正轉(zhuǎn)與反轉(zhuǎn),負數(shù)表現(xiàn)正轉(zhuǎn) angle 度,正數(shù)就表現(xiàn)反轉(zhuǎn) angle 度,如許處置是不是很簡練又很清楚明了呢?而你對有符號數(shù)和無符號數(shù)的差別用法是不是也更有領(lǐng)會了?

  • 針對終止電機遷移轉(zhuǎn)變的操作,我們界說了一個獨自的 StopMotor 函數(shù)來完成,雖然這個函數(shù)十分復雜,雖然它也只在 Esc 按鍵分支內(nèi)被挪用了,但我們依然把它獨自提出來作為了一個函數(shù)。而這種做法就是基于如許一條編程準繩:盡能夠用獨自的函數(shù)來完成硬件的某種操作,當一個硬件包括多個操作時,把這些操作函數(shù)組織在一同,構(gòu)成一個對下層的一致接口。如許的條理化處置,會使得全部程序?qū)哟蚊魑扔欣诔绦虻恼{(diào)試保護,又有利于功用的擴大。

  • 中綴函數(shù)中要處置按鍵掃描和電機驅(qū)動兩件工作,而為了防止中綴函數(shù)過于復雜,我們就又分出了按鍵掃描和電機驅(qū)動兩個函數(shù)(這也異樣契合上述 2 的編程準繩),而中綴函數(shù)的邏輯就變得簡練而明晰了。這里還有個矛盾,就是按鍵掃描我們選擇的準時工夫是 1ms,而本章之前的實例中電機節(jié)奏繼續(xù)工夫多是 2ms;很顯然,用 1ms 的準時可以定出 2ms 的距離,而用 2ms 的準時卻得不到精確的 1ms 距離;所以我們的做法就是,準時器仍然準時 1ms,然后用一個 bit 變量做標記,每 1ms 改動一次它的值,而我們只選擇值為 1 的時分履行一次舉措,如許就是 2ms 的距離了;假如我要 3ms、4ms呢,把 bit 改為 char 或 int 型,然后對它們遞增,判別到哪個值該歸零,就可以了。這就是在硬件準時器的根底上完成精確的軟件準時。

以上就是28BYJ-48步進電機掌握程序是怎樣的的全部內(nèi)容了,更多與28BYJ-48步進電機掌握程序是怎樣的相關(guān)的內(nèi)容可以搜索億速云之前的文章或者瀏覽下面的文章進行學習哈!相信小編會給大家增添更多知識,希望大家能夠支持一下億速云!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI