本文為大大維原創,最早於博客園發表,轉載請注明出處!!!
一、實驗目的和要求
了解步進電機的工作原理,學習用單片機的步進電機控制系統的硬件設計方法,掌握定時器和中斷系統的應用,熟悉單片機應用系統的設計與調試方法。
二、實驗設備
單片機測控實驗系統
步進電機控制實驗模塊
Keil開發環境
STC-ISP程序下載工具
三、實驗內容
編制MCS-51程序使步進電機按照規定的轉速和方向進行旋轉,並將已轉動的步數顯示在數碼管上。
步進電機的轉速分為兩檔,當按下S1開關時,加速旋轉,速度從10轉/分加速到60轉/分。當松開開關時,減速旋轉,速度恢復為10轉/分。當按下S2開關時,按照逆時針旋轉;當松開時,按照順時針旋轉。
本程序要求使用定時器中斷來實現,不准使用程序延時的方式。
四、實驗步驟
1、 預習
參考輔助材料,學習C51編程語言使用和步進電機原理。
2、 簡單程序錄入和調試
(1)關於C51的中斷
本程序需要使用定時器定時,並使用中斷來同步。中斷程序的典型例子如下:
格式:void 函數名()interrupt 中斷號 using 工作組
{
中斷服務程序內容
}
注意:中斷不能返回任何值,所以前面是 void 后面是函數名,名字可以自己起,但不要與c語言的關鍵字相同;中斷函數不帶任何參數,所以 函數名后面的()內是 空的,中斷號是指單片機的幾個中斷源的序號。這個序號是單片機識別不同中斷的唯一標志。所以一定要寫正確。
后面的using 工作組 是指這個這個中斷使用單片機內存中 4 個工作寄存器的哪一組,c51 編譯后會自動分配工作組,因此最后這句話我們通常省略不寫。
c51 中斷寫法實例:
void T1-time() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
}
上面的意思是定時器 1 的中斷服務程序,定時器 1 的中斷服務序號是 3 ,因此我們要寫成 interrupt 3 ,服務程序的內容是給 兩個初值寄存器裝入新值。。
寫中斷前的准備:
A、TMOD 賦值 確定工作方式。T0 還是T1 的工作方式。
B、計算初值 裝入 TH0 TL0 或者 TH1 TL1
C、中斷方式時 ,對 IE 賦值,開放中斷。
D、使 TR0 和 TR1 置位,啟動定時器/計數器 定時/計數。
(2)關於定時器中斷的賦值
使用定時器時,首先應由外部條件得到要定時的時間長度t,如本實驗中,就是根據要求的速度計算出的每一步之間的間隔。然后選擇適當的定時器工作方式,去計算想要設定的計數器初值s,使用如下方程:
(2定時器最大位數 - s)× 定時周期 =t 【定時周期 = 12/CPU晶振頻率】
得到的s需要分成高8位和低8位,分別放入計數器THx和TLx中(x為0或1)。如果s為負數,說明需要的定時時間太長,即使定時器的最大時間也無法滿足要求。這種情況下,需要加入軟件循環才能實現。我們可以將需要的定時時間分成n份,利用定時器達到t/n的時間長度,然后在定時器處理程序中,累計某一變量,如果到達n,說明總的時間t已經達到。
要想使用定時器中斷,除了上面的定時器初值設定外,還需要將其他相關的特殊功能寄存器也都設置好。如果使用方式0和方式1,不要忘記在計數結束后重新恢復計數器初值。
3、 程序調試
用單步、斷點、連續方式調試程序,觀察狀態指示燈及電機狀態,檢查運行結果。如果需要,可以將四個輸出信號的狀態同時輸出到P0口的某些位上,便於觀察。
4、 編寫程序,完成功能
五、實驗原理
1、 我們使用的單片機系統的頻率是12M;步進電機轉動一周需要24步。
2、 本步進電機實驗板,使用FAN8200作為驅動芯片。CPU通過如下4個引腳與FAN8200相連,即:
CPU | FAN8200 |
P1.1 | CE1 |
P1.4 | CE2 |
P3.2 | IN1 |
P1.0 | IN2 |
3、 本實驗使用簡單的雙四拍工作模式即可,這也是FAN8200比較方便的工作方式。只要將CE1和CE2分別置為高,然后IN1和IN2按照預定的脈沖輸出,即01->11->10->00->01這個循環構成一個方向旋轉的輸出脈沖,將此序列翻轉,就是相反方向的輸出脈沖。
六、實驗代碼
1 #include<reg52.h> 2 typedef unsigned int uint; 3 sfr P4=0xC0; 4 sfr P4SW=0xBB; 5 6 sbit s1=P3^6; 7 sbit s2=P3^7; 8 sbit CE1=P1^1; 9 sbit CE2=P1^4; 10 sbit IN1=P3^2; 11 sbit IN2=P1^0; 12 sbit CLK=P4^4; 13 sbit DAT=P4^5; 14 15 uint count=0; //用於計已轉動的步數 16 int flag=0; //用於給IN1、IN2傳值 17 //二極管顯示碼,存放在code區 18 uint code tab[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; 19 int main() 20 { 21 P4SW=0x70; 22 TMOD=0x01; 23 EA=1; 24 ET0=1; 25 TR0=1; 26 CE1=CE2=1; 27 28 while(1); 29 } 30 void rotateShun(int flag) 31 { 32 //01 11 10 00 33 switch(flag) 34 { 35 case 0: IN1=0; 36 IN2=1; 37 break; 38 case 1: IN1=1; 39 IN2=1; 40 break; 41 case 2: IN1=1; 42 IN2=0; 43 break; 44 case 3: IN1=0; 45 IN2=0; 46 break; 47 } 48 } 49 /*01 11 10 00 50 * 反方向輸出為 51 * 00 10 11 01 52 * 摁下按鍵后,需向后走一位,所以為 53 * 10 11 01 00 54 */ 55 void rotateNi(int flag) 56 { 57 //10 11 01 00 58 switch(flag) 59 { 60 case 0: IN1=1; 61 IN2=0; 62 break; 63 case 1: IN1=1; 64 IN2=1; 65 break; 66 case 2: IN1=0; 67 IN2=1; 68 break; 69 case 3: IN1=0; 70 IN2=0; 71 break; 72 } 73 } 74 75 void show(uint cnt){ //顯示一個數字 76 uint m, c,n; 77 m = tab[cnt]; 78 for (n = 0; n < 8; n++){ 79 CLK = 0; 80 //按位邏輯與,和1000 0000與,最高位保留,其他位置0,此處也可以與0x80比較大小來判斷 81 c= m & 0x80; //每次取一位,送往DAT 82 if(c==0) 83 DAT=0; 84 else 85 DAT=1; 86 CLK = 1; 87 m<<= 1; 88 } 89 } 90 91 void display(uint cnt){ //顯示 92 show(cnt%10); //個位 93 cnt /= 10; 94 show(cnt%10); //十位 95 show(cnt/10); //百位 96 } 97 98 void timeInt0() interrupt 1 99 { 100 if(s1==1) 101 { 102 /*不按s1,10r/min=240pace/min=960次/min, 103 *即每分鍾給IN1和IN0送值960次,每次間隔60/960=0.0625s=62.5ms 104 */ 105 TH0=(65536-62500)/256; 106 TL0=(65536-62500)%256; 107 if(s2==1) 108 { 109 rotateShun(flag); 110 } 111 if(s2==0) 112 { 113 rotateNi(flag); 114 } 115 } 116 if(s1==0) 117 { 118 /*按下s1,60r/min=1440pace/min=5760次/min, 119 *即每分鍾給IN1和IN0送值960次,每次間隔60/5760ms 120 */ 121 TH0=(65536-(uint)(60000/5760))/256; 122 TL0=(65536-(uint)(60000/5760))%256; 123 if(s2==1) 124 { 125 rotateShun(flag); 126 } 127 if(s2==0) 128 { 129 rotateNi(flag); 130 } 131 } 132 flag++; 133 if(flag>3) 134 { 135 flag=0; 136 count++; 137 if(count < 999) 138 { 139 display(count); 140 } 141 else{ 142 count = 0; 143 display(count); 144 } 145 } 146 }
七、一點想法
步進電機必須加驅動才可以運轉,驅動信號必須為脈沖信號,沒有脈沖的時候,步進電機靜止,如果加入適當的脈沖信號,就會以一定的角度(稱為步角)轉動,轉動的速度和脈沖的頻率成正比。改變脈沖的順序,可以方便的改變轉動的方向。
步進電機最好不使用整步狀態,整步狀態時振動大。
八、附錄
實驗電路原理圖:點擊查看