|
1黑幣
- #include <reg52.h>
- signed long beats = 0; //電機(jī)轉(zhuǎn)動節(jié)拍總數(shù)
- void KeyDriver();
- void main()
- {
- EA = 1; //使能總中斷
- TMOD = 0x01; //設(shè)置T0為模式1
- TH0 = 0xFC; //為T0賦初值0xFC67,定時(shí)1ms
- TL0 = 0x67;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
-
- while (1)
- {
- KeyDriver(); //調(diào)用按鍵驅(qū)動函數(shù)
- }
- }
- /* 步進(jìn)電機(jī)啟動函數(shù),angle-需轉(zhuǎn)過的角度 */
- void StartMotor(signed long angle)
- {
- //在計(jì)算前關(guān)閉中斷,完成后再打開,以避免中斷打斷計(jì)算過程而造成錯(cuò)誤
- EA = 0;
- beats = (angle * 4076) / 360; //實(shí)測為4076拍轉(zhuǎn)動一圈
- EA = 1;
- }
- /* 步進(jìn)電機(jī)停止函數(shù) */
- void StopMotor()
- {
- EA = 0;
- beats = 0;
- EA = 1;
- }
- /* 按鍵動作函數(shù),根據(jù)鍵碼執(zhí)行相應(yīng)的操作,keycode-按鍵鍵碼 */
- void KeyAction(unsigned char keycode)
- {
- static bit dirMotor = 0; //電機(jī)轉(zhuǎn)動方向
-
- if ((keycode>=0x30) && (keycode<=0x39)) //控制電機(jī)轉(zhuǎn)動1-9圈
- {
- if (dirMotor == 0)
- StartMotor(360*(keycode-0x30));
- else
- StartMotor(-360*(keycode-0x30));
- }
- else if (keycode == 0x26) //向上鍵,控制轉(zhuǎn)動方向?yàn)檎D(zhuǎn)
- {
- dirMotor = 0;
- }
- else if (keycode == 0x28) //向下鍵,控制轉(zhuǎn)動方向?yàn)榉崔D(zhuǎn)
- {
- dirMotor = 1;
- }
- else if (keycode == 0x25) //向左鍵,固定正轉(zhuǎn)90度
- {
- StartMotor(90);
- }
- else if (keycode == 0x27) //向右鍵,固定反轉(zhuǎn)90度
- {
- StartMotor(-90);
- }
- else if (keycode == 0x1B) //Esc鍵,停止轉(zhuǎn)動
- {
- StopMotor();
- }
- }
- /* 按鍵驅(qū)動函數(shù),檢測按鍵動作,調(diào)度相應(yīng)動作函數(shù),需在主循環(huán)中調(diào)用 */
- void KeyDriver()
- {
- unsigned char i, j;
- static unsigned char backup[4][4] = { //按鍵值備份,保存前一次的值
- {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
- };
-
- for (i=0; i<4; i++) //循環(huán)檢測4*4的矩陣按鍵
- {
- for (j=0; j<4; j++)
- {
- if (backup[i][j] != KeySta[i][j]) //檢測按鍵動作
- {
- if (backup[i][j] != 0) //按鍵按下時(shí)執(zhí)行動作
- {
- KeyAction(KeyCodeMap[i][j]); //調(diào)用按鍵動作函數(shù)
- }
- backup[i][j] = KeySta[i][j]; //刷新前一次的備份值
- }
- }
- }
- }
- /* 電機(jī)轉(zhuǎn)動控制函數(shù) */
- void TurnMotor()
- {
- unsigned char tmp; //臨時(shí)變量
- static unsigned char index = 0; //節(jié)拍輸出索引
- unsigned char code BeatCode[8] = { //步進(jìn)電機(jī)節(jié)拍對應(yīng)的IO控制代碼
- 0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
- };
-
- if (beats != 0) //節(jié)拍數(shù)不為0則產(chǎn)生一個(gè)驅(qū)動節(jié)拍
- {
- if (beats > 0) //節(jié)拍數(shù)大于0時(shí)正轉(zhuǎn)
- {
- index++; //正轉(zhuǎn)時(shí)節(jié)拍輸出索引遞增
- index = index & 0x07; //用&操作實(shí)現(xiàn)到8歸零
- beats--; //正轉(zhuǎn)時(shí)節(jié)拍計(jì)數(shù)遞減
- }
- else //節(jié)拍數(shù)小于0時(shí)反轉(zhuǎn)
- {
- index--; //反轉(zhuǎn)時(shí)節(jié)拍輸出索引遞減
- index = index & 0x07; //用&操作同樣可以實(shí)現(xiàn)到-1時(shí)歸7
- beats++; //反轉(zhuǎn)時(shí)節(jié)拍計(jì)數(shù)遞增
- }
- tmp = P1; //用tmp把P1口當(dāng)前值暫存
- tmp = tmp & 0xF0; //用&操作清零低4位
- tmp = tmp | BeatCode[index]; //用|操作把節(jié)拍代碼寫到低4位
- P1 = tmp; //把低4位的節(jié)拍代碼和高4位的原值送回P1
- }
- else //節(jié)拍數(shù)為0則關(guān)閉電機(jī)所有的相
- {
- P1 = P1 | 0x0F;
- }
- }
- /* T0中斷服務(wù)函數(shù),用于按鍵掃描與電機(jī)轉(zhuǎn)動控制 */
- void InterruptTimer0() interrupt 1
- {
- static bit div = 0;
-
- TH0 = 0xFC; //重新加載初值
- TL0 = 0x67;
- KeyScan(); //執(zhí)行按鍵掃描
- //用一個(gè)靜態(tài)bit變量實(shí)現(xiàn)二分頻,即2ms定時(shí),用于控制電機(jī)
- div = ~div;
- if (div == 1)
- {
- TurnMotor();
- }
- }
復(fù)制代碼 |
|