實驗的仿真題圖
{(7N$WN36LFVRZ1S}U13U5T.png (71.34 KB, 下載次數: 165)
下載附件
2019-12-31 22:11 上傳
步進電機是那個寶買的28BYJ-48 驅動模塊的ULN2003a也那個寶買的
接線圖如下
IMG_20191231_221336.jpg (2.93 MB, 下載次數: 137)
下載附件
2019-12-31 22:14 上傳
也可以按照自己的代碼來接線,我是按自己代碼的串口設置接的線。
話不多說先上代碼:
首先電機轉動的代碼
uchar phasecw[8] ={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//正轉 電機導通相序 D-C-B-A
uchar phaseccw[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//反轉 電機導通相序 A-B-C-D
//順時針轉動
- void MotorCW(void)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- MotorData=phasecw[i];
- Delay_ms(speed);//轉速調節
- }
- i=0;
- }
- //逆時針轉動
- void MotorCCW(void)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- MotorData=phaseccw[i];
- Delay_ms(speed);//轉速調節
- }
- }
復制代碼 根據步進電機的原理:依次給4相高電平就可以驅動步進電機轉動而A,B,C,D四相 分別對應P1.0,P1.1,P1.2,P1.3口所以只有讓P1口依次為0x01,0x02,0x04,0x08就行了,如果要反轉就把它倒過來依次為0x08,0x04,0x02,0x01.一圈4步,所以叫四相四拍。但是我不推薦使用這種,它的一步角度較大電機會有較大抖動。所以采用了四相八拍0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09這樣電機轉動也相對平穩不易出事。
為了實現電機的不停頓轉動我將轉動函數放在了死循環里,但是在死循環里我們無法控制電機了怎么辦了就在死循環里加入一個按鍵函數這樣死循環不停掃描按鍵我們就可以在k1 里面通過sem控制電機的正反轉了。
死循環:while(sem&&sam)
{
MotorCW();
Delay_ms(speed);//轉速調節
keypros();
}
while(!sem&&sam)
{
MotorCCW();
Delay_ms(speed);//轉速調節
按鍵控制:
if(k1==0) //檢測按鍵K1是否按下
{
Delay_ms(10); //消除抖動 一般大約10ms
if(k1==0) //再次判斷按鍵是否按下
{
sam=1;
sem=!sem;
}
while(!k1); //檢測按鍵是否松開
}
為什么要用一個鍵控制正反轉了?不僅僅是因為按鍵不夠,更重要的是能消除鍵位沖突,鍵位沖突是指同時按下不同的鍵產生的沖突。消除鍵位沖突也是每次實驗應該考慮的事情。但是這樣也產生了新的問題就是當我們用兩個鍵控制正反轉時,單片機上電后電機不會轉動。而用上述方法的話上電電機就進入死循環開始轉動,所以引入sam控制電機的開始于停止。當sam為0與上sem可以使sem失去控制能力,也就是電機不轉了。這樣也就解決此問題還能控制電機停止
if(k2==0) //檢測按鍵K1是否按下
{
Delay_ms(10); //消除抖動 一般大約10ms
if(k2==0) //再次判斷按鍵是否按下
{
sam=0;
}
while(!k2); //檢測按鍵是否松開
}
我們由步進電機原理可知電機是一步一步的走的,如果我們控制了它每一步的間隔時間就可以達到控制電機的速度的目的。但是對于我買的步進電機來說速度變換的一定程度就不明顯了所以我設置了限位這樣就減少代碼的bug,所以寫出按鍵控制速度代碼如下
if(k3==0) //檢測按鍵K1是否按下
{
Delay_ms(10); //消除抖動 一般大約10ms
if(k3==0) //再次判斷按鍵是否按下
{
speed++;
if(speed>6)
{
speed=6;
}
}
while(!k3); //檢測按鍵是否松開
}
if(k4==0) //檢測按鍵K1是否按下
{
Delay_ms(10); //消除抖動 一般大約10ms
if(k4==0) //再次判斷按鍵是否按下
{
speed--;
if(speed<1)
{
speed=1;
}
}
while(!k3); //檢測按鍵是否松開
}
}
理解了這些代碼的原理就可以寫出總代碼了
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define MotorData P1 //步進電機控制接口定義
- uchar phasecw[8] ={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//正轉 電機導通相序 D-C-B-A
- uchar phaseccw[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//反轉 電機導通相序 A-B-C-D
- uint sem=0,sam=0,speed=3;//信號量,sem控制正反轉,sam設置電機是否轉動,1轉動,0不轉動
- sbit k1=P3^1;
- sbit k2=P3^0;
- sbit k3=P3^2;
- sbit k4=P3^3;
- //ms延時函數
- void Delay_ms(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<112;j++);
- }
- //順時針轉動
- void MotorCW(void)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- MotorData=phasecw[i];
- Delay_ms(speed);//轉速調節
- }
- i=0;
- }
- //逆時針轉動
- void MotorCCW(void)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- MotorData=phaseccw[i];
- Delay_ms(speed);//轉速調節
- }
- }
- //按鍵函數
- void keypros()
- {
- if(k1==0) //檢測按鍵K1是否按下
- {
- Delay_ms(10); //消除抖動 一般大約10ms
- if(k1==0) //再次判斷按鍵是否按下
- {
- sam=1;
- sem=!sem;
- }
- while(!k1); //檢測按鍵是否松開
- }
- if(k2==0) //檢測按鍵K1是否按下
- {
- Delay_ms(10); //消除抖動 一般大約10ms
- if(k2==0) //再次判斷按鍵是否按下
- {
- sam=0;
- }
- while(!k2); //檢測按鍵是否松開
- }
- if(k3==0) //檢測按鍵K1是否按下
- {
- Delay_ms(10); //消除抖動 一般大約10ms
- if(k3==0) //再次判斷按鍵是否按下
- {
- speed++;
- if(speed>6)
- {
- speed=6;
- }
-
- }
- while(!k3); //檢測按鍵是否松開
- }
- if(k4==0) //檢測按鍵K1是否按下
- {
- Delay_ms(10); //消除抖動 一般大約10ms
- if(k4==0) //再次判斷按鍵是否按下
- {
- speed--;
- if(speed<1)
- {
- speed=1;
- }
-
- }
- while(!k3); //檢測按鍵是否松開
- }
- }
- //主函數
- void main(void)
- {
- while(1)
- {
- MotorData=0x00; //設初值
- keypros();
- while(sem&&sam)
- {
- MotorCW();
- Delay_ms(speed);//轉速調節
- keypros();
- }
- while(!sem&&sam)
- {
- MotorCCW();
- Delay_ms(speed);//轉速調節
- keypros();
- }
- }
- }
復制代碼 本文大體就是這樣,如果有什么疑問可以在評論區留言,我會盡量回答。
最后附上代碼包:
步進電機實驗.zip
(20.67 KB, 下載次數: 561)
2019-12-31 23:01 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|