單片機的應用特别地多,其用途非常廣泛,我們這些案例隻是涉及其基本部分,沒有深究,但是也是要作為一個了解的,今天就學習一下步進電機和可控步進電機
步進電機
實驗現象
發現步進電機按照一定速度逆時針旋轉,同時發現SM接口處左側的led燈以一定頻率閃爍
(PS:在沒有步進電機的情況下,可以通過檢視led的閃爍來判斷步進電機是否處于工作狀态下)
工作原理
步進電機
電脈沖信号轉變為角位移或線位移的開環控制元步進電機件
(在非超載的情況下,電機的轉速、停止的位置隻取決于脈沖信号的頻率和脈沖數,而不受負載變化的影響,)
- 當步進驅動器接收到一個脈沖信号,它就驅動步進電機按設定的方向轉動一個固定的角度,稱為“步距角”,它的旋轉是以固定的角度一步一步運作的。
- 可以通過控制脈沖個數來控制角位移量,進而達到準确定位的目的;
- 同時可以通過控制脈沖頻率來控制電機轉動的速度和加速度,進而達到調速的目的
勵磁方式是一相勵磁,勵磁表在程式中為0111、1011、1101、1110,程式連續不停地在不同口送入脈沖信号,即可使步進電機旋轉,通過設定定時器的定時時間減慢步進電機的旋轉速度
電路原理圖:
擴充:
步進電機的勵磁方式有三種:
-
一相勵磁
在每一瞬間,步進電機隻有一個線圈導通。每送一個勵磁信号,步進電機旋轉5.625°,這是三種勵磁方式中最簡單的一種
順序表如下:
-
二相勵磁
在每一瞬間,步進電機有兩個線圈同時導通。每送一個勵磁信号,步進電機旋轉5.625°
順序表如下:
-
一-二相勵磁
為一相勵磁與二相勵磁交替導通的方式。每送一個勵磁信号,步進電機旋轉2.8125°
順序表如下:
代碼解析
設計流程圖如下:
設定其勵磁的順序表的元素,通過中斷實作
void time0() interrupt 1
{
switch(i++)//控制步進電機不同IO脈沖電平
{
case 1: s1=1;s2=0;s3=0;s4=0;break;
case 2: s1=0;s2=1;s3=0;s4=0;break;
case 3: s1=0;s2=0;s3=1;s4=0;break;
case 4: s1=0;s2=0;s3=0;s4=1;break;
}
if(i==5)
i=1;
}
初始化
void init_sys()
{
P4M0=0Xff; //P4口推挽輸出
P4M1=0X00;
// LED =0; //數位管顯示
P4 =0X00; //P4口設定低電平,避免複位時對接口造成影響
TMOD = 0x00; //設定定時器0,16位
TH0 = (65536-10000)/256; //設定5ms
TL0 = (65536-10000)%256;
TCON = 0X10; //定時器開始計時
IE = 0x82; //開啟CPU中斷,定時器0中斷
}
最後主函數中設定永真循環即可
可控步進電機
實驗現象
現象與步進電機相同,隻是增加了控制功能
即:
K2鍵可控制步進電機的旋轉方向
K3鍵控制步進電機的旋轉與停止
工作原理
通過在P4.1、P4.2、P4.3、P4.4口每隔5ms*sudu的時間輸入高電平(sudu值由Key1鍵進行确定,并在數位管最右端顯示,分别為1-12這12個檔位,數值越大,轉速越慢)
并結合Key2鍵确認旋轉方向(按下按鍵則按相反方向進行旋轉)
再結合Key3鍵控制步進電機旋轉還是停止
代碼解析
工程設計流程圖如下:
-
反轉部分代碼
(隻需要判斷按鍵是否按下,包含按鍵消抖,就利用條件語句,選擇不同的順序,原來1 2 3 4對應的順序表,現在反過來對應即可)
void Xstep_Process()
{
static uchar i = 1;
if( btRotationFlag == 0 )
{
switch( i++ )
{
case 1:
sbtS1 = 1; sbtS2 = 0; sbtS3 = 0; sbtS4 = 0; break;
case 2:
sbtS1 = 0; sbtS2 = 1; sbtS3 = 0; sbtS4 = 0; break;
case 3:
sbtS1 = 0; sbtS2 = 0; sbtS3 = 1; sbtS4 = 0; break;
case 4:
sbtS1 = 0; sbtS2 = 0; sbtS3 = 0; sbtS4 = 1; break;
default:
sbtS1 = 0; sbtS2 = 0; sbtS3 = 0; sbtS4 = 0; break;
}
if( i == 5 )
i = 1;
}
else
{
switch( i++ )
{
case 1:
sbtS1 = 0; sbtS2 = 0; sbtS3 = 0; sbtS4 = 1; break;
case 2:
sbtS1 = 0; sbtS2 = 0; sbtS3 = 1; sbtS4 = 0; break;
case 3:
sbtS1 = 0; sbtS2 = 1; sbtS3 = 0; sbtS4 = 0; break;
case 4:
sbtS1 = 1; sbtS2 = 0; sbtS3 = 0; sbtS4 = 0; break;
default:
sbtS1 = 0; sbtS2 = 0; sbtS3 = 0; sbtS4 = 0; break;
}
if( i == 5 )
i = 1;
}
}
-
數位管顯示部分
設定其初始值為一定的檔數,改變一個數字改變一下頻率,得到不同的部分,再利用數位管部分的知識成功顯示即可
void Seg7LedDisplay( uchar s, uchar e )
{
unsigned char arrSegSelect[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x00};
static int i;
P2 = ( P2 & 0xf0 ) | i;
switch( i )
{
case 0:
P0 = arrSegSelect[cstDig0]; break;
case 1:
P0 = arrSegSelect[cstDig1]; break;
case 2:
P0 = arrSegSelect[cstDig2]; break;
case 3:
P0 = arrSegSelect[cstDig3]; break;
case 4:
P0 = arrSegSelect[cstDig4]; break;
case 5:
P0 = arrSegSelect[cstDig5]; break;
case 6:
P0 = arrSegSelect[cstDig6]; break;
case 7:
P0 = arrSegSelect[cstDig7]; break;
case 8:
P0 = cstDig8; break;
default:
P0 = 0x00; break;
}
if( ++i > e ) i = s;
}
-
主函數部分
包含其判斷使能是否有效,即步進電機能否工作
以及是什麼擋位的使能有效,進而得到多長時間的間隔改變轉動頻率
void main()
{
Init();
ucLedTmp = 0x00;
while( 1 )
{
if( btT10usFlag )
{
btT10usFlag = 0; T10us_Process();
}
if( btT100usFlag )
{
btT100usFlag = 0; T100us_Process();
}
if( btT1msFlag )
{
btT1msFlag = 0; T1ms_Process();
}
if( btT10msFlag )
{
btT10msFlag = 0; T10ms_Process();
}
if( btT100msFlag )
{
btT100msFlag = 0; T100ms_Process();
}
if( ( btTXmsFlag && btTXmsFlag_en ) )
{
btTXmsFlag = 0; TXms_Process();
}
}
}
-
中斷服務處理部分
中斷為10次,即計數10次,就會開啟一種新狀态
-
初始化部分
與步進電機類似,增加部分統計變量的初值
-
各節拍的處理函數
不同地方的顯示,選擇不同的頻率
void T10us_Process()
{
}
void T100us_Process()
{
ucClockXms++;
if ( ucClockXms == ( cstClockXmsMaxNum ) )
{
ucClockXms = 0; btTXmsFlag = 1;
}
}
void T1ms_Process()
{
Seg7LedDisplay( cstDigBegin, cstDigEnd );
}
void T10ms_Process()
{
Key_Scan();
}
void TXms_Process()
{
Xstep_Process();
}
void T100ms_Process()
{
ucSpeed_Seg = ucSpeed;
}
-
按鍵掃描即消抖部分
參照按鍵消抖代碼即可