溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

28BYJ-48步進(jìn)電機(jī)掌握程序根底

發(fā)布時(shí)間:2020-05-30 19:38:23 來(lái)源:網(wǎng)絡(luò) 閱讀:403 作者:yuw2018 欄目:網(wǎng)絡(luò)安全

處理了精度成績(jī),讓我們?cè)俅位氐轿覀兊碾姍C(jī)掌握程序上吧。下面給出的兩個(gè)例程都不是適用的程序,為什么?由于程序中存在大段的延時(shí),而在延時(shí)的時(shí)分是什么其它的事都干不了的,想想第二個(gè)程序,整整 200 秒什么其余事都干不了,這在實(shí)踐的掌握零碎中是相對(duì)不許可的。那么怎樣改革一下呢?當(dāng)然照樣用準(zhǔn)時(shí)中綴來(lái)完成了,既然每一個(gè)節(jié)奏繼續(xù)工夫是2ms,那我們直接用準(zhǔn)時(shí)器準(zhǔn)時(shí) 2ms 來(lái)刷新節(jié)奏就行了。改革后的程序如下:

			#include <reg52.h> unsigned long beats = 0; //電機(jī)遷移轉(zhuǎn)變節(jié)奏總數(shù) void StartMotor(unsigned long angle); void main(){ EA = 1; //使能總中綴 TMOD = 0x01; //設(shè)置 T0 為形式 1 TH0 = 0xF8; //為 T0 賦初值 0xF8CD,準(zhǔn)時(shí) 2ms TL0 = 0xCD; ET0 = 1; //使能 T0 中綴 TR0 = 1; //啟動(dòng) T0 StartMotor(360*2+180); //掌握電機(jī)遷移轉(zhuǎn)變 2 圈半 while (1); } /* 步進(jìn)電機(jī)啟動(dòng)函數(shù),angle-需轉(zhuǎn)過(guò)的角度 */ void StartMotor(unsigned long angle){ //在盤(pán)算前封閉中綴,完成后再翻開(kāi),以防止中綴打斷盤(pán)算進(jìn)程而形成毛病 EA = 0; beats = (angle * 4076) / 360; //實(shí)測(cè)為 4076 拍遷移轉(zhuǎn)變一圈 EA = 1; } /* T0 中綴效勞函數(shù),用于驅(qū)動(dòng)步進(jìn)電機(jī)扭轉(zhuǎn) */ void InterruptTimer0() interrupt 1{ unsigned char tmp; //暫時(shí)變量 static unsigned char index = 0; //節(jié)奏輸入索引 unsigned char code BeatCode[8] = { //步進(jìn)電機(jī)節(jié)奏對(duì)應(yīng)的 IO 掌握代碼 0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6 }; TH0 = 0xF8; //從新加載初值 TL0 = 0xCD; //節(jié)奏數(shù)不為 0 則發(fā)生一個(gè)驅(qū)動(dòng)節(jié)奏 if (beats != 0){ tmp = P1; //用 tmp 把 P1 口以后值暫存 tmp = tmp & 0xF0; //用&操作清零低 4 位 //用|操作把節(jié)奏代碼寫(xiě)到低 4 位 tmp = tmp | BeatCode[index]; //把低 4 位的節(jié)奏代碼和高 4 位的原值送回 P1 P1 = tmp; index++; //節(jié)奏輸入索引遞增 index = index & 0x07; //用&操作完成到 8 歸零 beats--; //總節(jié)奏數(shù)-1 }else{ //節(jié)奏數(shù)為 0 則封閉電機(jī)一切的相 P1 = P1 | 0x0F; } }

程序照樣比擬復(fù)雜的,電機(jī)遷移轉(zhuǎn)變的啟動(dòng)函數(shù) StartMotor 只擔(dān)任盤(pán)算一個(gè)需求的總節(jié)奏數(shù)beats,然后在中綴函數(shù)內(nèi)檢測(cè)這個(gè)變量,不為 0 時(shí)就履行節(jié)奏操作,同時(shí)將其減 1,直到減到 0 為止。
這里,我們要特殊闡明一下的是 StartMotor 函數(shù)中對(duì) EA 的兩次操作。我們可以看到對(duì)beats 的賦值盤(pán)算語(yǔ)句是夾在 EA=0;EA=1;這兩行語(yǔ)句兩頭的,也就是說(shuō)這行賦值盤(pán)算語(yǔ)句在履行前先封閉了中綴,而等它履行完后,才又從新翻開(kāi)了中綴。在它履行進(jìn)程中單片機(jī)是不會(huì)呼應(yīng)中綴的,即中綴函數(shù) InterruptTimer0 不會(huì)被履行,即便這時(shí)分準(zhǔn)時(shí)器溢出了,中綴發(fā)作了,也只能等候 EA 從新置 1 后,才干失掉呼應(yīng),中綴函數(shù) InterruptTimer0 才會(huì)被履行。
那么為什么要這么做呢?我們來(lái)想一下:在本書(shū)開(kāi)端我們就曾提到,我們所運(yùn)用的STC89C52 單片機(jī)是 8 位單片機(jī),這個(gè) 8 位的概念就是說(shuō)單片機(jī)操作數(shù)據(jù)時(shí)多是按 8 位即按1 個(gè)字節(jié)停止的,那么要操作多個(gè)字節(jié)(不管是讀照樣寫(xiě))就必需分屢次停止了。而我們程序中界說(shuō)的 beats 這個(gè)變量是 unsigned long 型,它要占用 4 個(gè)字節(jié),那么對(duì)它的賦值起碼也要分 4 次才干完成了。我們想象一下,假設(shè)在完成了個(gè)中第一個(gè)字節(jié)的賦值后,恰恰中綴發(fā)作了,InterruptTimer0 函數(shù)失掉履行,而這個(gè)函數(shù)內(nèi)能夠會(huì)對(duì) beats 停止減 1 的操作,減法就有能夠發(fā)作借位,借位就會(huì)改動(dòng)其它的字節(jié),但由于此時(shí)其它的字節(jié)還沒(méi)有被賦入新值,于是毛病就會(huì)發(fā)作了,減 1 所失掉的后果就不是預(yù)期的值了!所以要防止這種毛病的發(fā)作就得先臨時(shí)封閉中綴,等賦值完成后再翻開(kāi)中綴。而假如我們運(yùn)用的是 char 或 bit 型變量的話,由于它們多是在 CPU 的一次操作中就完成的,所以即便不關(guān)中綴,也不會(huì)發(fā)作毛病。成績(jī)剖析清晰了,若何棄取還得依據(jù)實(shí)踐狀況來(lái),趕上這類(lèi)成績(jī)的時(shí)分多多思索思索吧。


向AI問(wèn)一下細(xì)節(jié)

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

AI