一、實驗?zāi)康暮鸵?br/>
了解步進電機的工作原理,學(xué)習(xí)用單片機的步進電機控制系統(tǒng)的硬件設(shè)計方法,掌握定時器和中斷系統(tǒng)的應(yīng)用,熟悉單片機應(yīng)用系統(tǒng)的設(shè)計與調(diào)試方法。
二、實驗設(shè)備
單片機測控實驗系統(tǒng)
步進電機控制實驗?zāi)K
Keil開發(fā)環(huán)境
STC-ISP程序下載工具
三、實驗內(nèi)容
編制MCS-51程序使步進電機按照規(guī)定的轉(zhuǎn)速和方向進行旋轉(zhuǎn),并將已轉(zhuǎn)動的步數(shù)顯示在數(shù)碼管上。
步進電機的轉(zhuǎn)速分為兩檔,當(dāng)按下S1開關(guān)時,加速旋轉(zhuǎn),速度從10轉(zhuǎn)/分加速到60轉(zhuǎn)/分。當(dāng)松開開關(guān)時,減速旋轉(zhuǎn),速度恢復(fù)為10轉(zhuǎn)/分。當(dāng)按下S2開關(guān)時,按照逆時針旋轉(zhuǎn);當(dāng)松開時,按照順時針旋轉(zhuǎn)。
本程序要求使用定時器中斷來實現(xiàn),不準(zhǔn)使用程序延時的方式。
四、實驗步驟
1、 預(yù)習(xí)
參考輔助材料,學(xué)習(xí)C51編程語言使用和步進電機原理。
2、 簡單程序錄入和調(diào)試
(1)關(guān)于C51的中斷
本程序需要使用定時器定時,并使用中斷來同步。中斷程序的典型例子如下:
格式:void 函數(shù)名()interrupt 中斷號 using 工作組
{
中斷服務(wù)程序內(nèi)容
}
注意:中斷不能返回任何值,所以前面是 void 后面是函數(shù)名,名字可以自己起,但不要與c語言的關(guān)鍵字相同;中斷函數(shù)不帶任何參數(shù),所以 函數(shù)名后面的()內(nèi)是 空的,中斷號是指單片機的幾個中斷源的序號。這個序號是單片機識別不同中斷的唯一標(biāo)志。所以一定要寫正確。
后面的using 工作組 是指這個這個中斷使用單片機內(nèi)存中 4 個工作寄存器的哪一組,c51 編譯后會自動分配工作組,因此最后這句話我們通常省略不寫。
c51 中斷寫法實例:
void T1-time() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
}
上面的意思是定時器 1 的中斷服務(wù)程序,定時器 1 的中斷服務(wù)序號是 3 ,因此我們要寫成 interrupt 3 ,服務(wù)程序的內(nèi)容是給 兩個初值寄存器裝入新值。。
寫中斷前的準(zhǔn)備:
A、TMOD 賦值 確定工作方式。T0 還是T1 的工作方式。
B、計算初值 裝入 TH0 TL0 或者 TH1 TL1
C、中斷方式時 ,對 IE 賦值,開放中斷。
D、使 TR0 和 TR1 置位,啟動定時器/計數(shù)器 定時/計數(shù)。
(2)關(guān)于定時器中斷的賦值
使用定時器時,首先應(yīng)由外部條件得到要定時的時間長度t,如本實驗中,就是根據(jù)要求的速度計算出的每一步之間的間隔。然后選擇適當(dāng)?shù)亩〞r器工作方式,去計算想要設(shè)定的計數(shù)器初值s,使用如下方程:
?。?定時器最大位數(shù) - s)× 定時周期 =t 【定時周期 = 12/CPU晶振頻率】
得到的s需要分成高8位和低8位,分別放入計數(shù)器THx和TLx中(x為0或1)。如果s為負數(shù),說明需要的定時時間太長,即使定時器的最大時間也無法滿足要求。這種情況下,需要加入軟件循環(huán)才能實現(xiàn)。我們可以將需要的定時時間分成n份,利用定時器達到t/n的時間長度,然后在定時器處理程序中,累計某一變量,如果到達n,說明總的時間t已經(jīng)達到。
要想使用定時器中斷,除了上面的定時器初值設(shè)定外,還需要將其他相關(guān)的特殊功能寄存器也都設(shè)置好。如果使用方式0和方式1,不要忘記在計數(shù)結(jié)束后重新恢復(fù)計數(shù)器初值。
3、 程序調(diào)試
用單步、斷點、連續(xù)方式調(diào)試程序,觀察狀態(tài)指示燈及電機狀態(tài),檢查運行結(jié)果。如果需要,可以將四個輸出信號的狀態(tài)同時輸出到P0口的某些位上,便于觀察。
4、 編寫程序,完成功能
五、實驗原理
1、我們使用的單片機系統(tǒng)的頻率是12M;步進電機轉(zhuǎn)動一周需要24步。
2、本步進電機實驗板,使用FAN8200作為驅(qū)動芯片。CPU通過如下4個引腳與FAN8200相連,即:
3、本實驗使用簡單的雙四拍工作模式即可,這也是FAN8200比較方便的工作方式。只要將CE1和CE2分別置為高,然后IN1和IN2按照預(yù)定的脈沖輸出,即01->11->10->00->01這個循環(huán)構(gòu)成一個方向旋轉(zhuǎn)的輸出脈沖,將此序列翻轉(zhuǎn),就是相反方向的輸出脈沖。
六、實驗代碼
1 #include
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; //用于計已轉(zhuǎn)動的步數(shù)
16 int flag=0; //用于給IN1、IN2傳值
17 //二極管顯示碼,存放在code區(qū)
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){ //顯示一個數(shù)字
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