|
- #include <reg52.h> //51芯片管腳定義頭文件
- #include <intrins.h> //內部包含延時函數 _nop_();
- #define uchar unsigned char
- #define uint unsigned int
- uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //正轉相序
- uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1}; //反轉相序
- sbit K1 = P3^2; //運行與停止
- sbit K2 = P3^3; //速率調整
- sbit K3 = P3^4; //方向轉換
-
- sbit BEEP = P3^6; //蜂鳴器
- sbit RS = P2^0; //液晶管腳定義
- sbit RW = P2^1;
- sbit E = P2^2;
- sbit BF=P0^7; //忙碌標志位
- bit on_off=0; //運行與停止標志
- bit direction=1; //方向標志
- uchar rate=2; //預設定速率
- uchar data_temp;
- uchar u=0,v=0;
-
- uchar code cdis1[ ] = {" STEPPING MOTOR "};
- uchar code cdis2[ ] = {"CONTROL PROCESS"};
- uchar code cdis3[ ] = {" STOP "};
- uchar code cdis4[ ] = {" RATE: "};
- uchar code cdis5[ ] = {" RUNNING "};
- /********************************************************/
- /*
- /* 延時t毫秒
- /* 11.0592MHz時鐘,延時約1ms
- /*
- /********************************************************/
- void delay(uint t)
- {
- uchar k;
- while(t--)
- {
- for(k=0; k<125; k++)
- { }
- }
- }
- /********************************************************/
- void delayB(uchar x) //x*0.14MS
- {
- uchar i;
- while(x--)
- {
- for (i=0; i<13; i++)
- { }
- }
- }
- /********************************************************/
- void beep()
- {
- uchar j;
- for (j=0;j<100;j++)
- {
- delayB(4);
- BEEP=!BEEP; //BEEP取反
- }
- BEEP=1; //關閉蜂鳴器
- delay(170);
- }
- /********************************************************/
- /*
- /*檢查LCD忙狀態
- /*BF為1時,忙,等待。為0時,閑,可寫指令與數據。
- /*
- /********************************************************/
- bit BusyTest()
- {
- bit result;
- RS = 0;
- RW = 1;
- E= 1;
- _nop_();
- _nop_();
- result = BF;
- E = 0;
- return(result);
- }
- /*****************************************************
- 函數功能:將模式設置指令或顯示地址寫入液晶模塊
- 入口參數:dictate
- ***************************************************/
- void WriteInstruction (unsigned char dictate)
- {
- while(BusyTest()==1); //如果忙就等待
- RS=0; //根據規定,RS和R/W同時為低電平時,可以寫入指令
- RW=0;
- E=0; //E置低電平(寫指令時,
- // 就是讓E從0到1發生正跳變,所以應先置"0"
- _nop_();
- _nop_(); //空操作兩個機器周期,給硬件反應時間
- P0=dictate; //將數據送入P0口,即寫入指令或地址
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個機器周期,給硬件反應時間
- E=1; //E置高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個機器周期,給硬件反應時間
- E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令
- }
- /*****************************************************
- 函數功能:指定字符顯示的實際地址
- 入口參數:x
- ***************************************************/
- void WriteAddress(unsigned char x)
- {
- WriteInstruction(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
- }
- /*****************************************************
- 函數功能:將數據(字符的標準ASCII碼)寫入液晶模塊
- 入口參數:y(為字符常量)
- ***************************************************/
- void WriteData(unsigned char y)
- {
- while(BusyTest()==1);
- RS=1; //RS為高電平,RW為低電平時,可以寫入數據
- RW=0;
- E=0; //E置低電平(寫指令時,,
- // 就是讓E從0到1發生正跳變,所以應先置"0"
- P0=y; //將數據送入P0口,即將數據寫入液晶模塊
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個機器周期,給硬件反應時間
- E=1; //E置高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個機器周期,給硬件反應時間
- E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令
- }
- /*****************************************************
- 函數功能:對LCD的顯示模式進行初始化設置
- ***************************************************/
- void LcdInt(void)
- {
- delay(15); //延時15ms,首次寫指令時應給LCD一段較長的反應時間
- WriteInstruction (0x38); //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
- delay(5); //延時5ms
- WriteInstruction (0x38);
- delay(5);
- WriteInstruction (0x38); //3次寫 設置模式
- delay(5);
- WriteInstruction (0x0c); //顯示模式設置:顯示開,無
- delay(5);
- WriteInstruction (0x06); //顯示模式設置:光標右移,字符不移
- delay(5);
- WriteInstruction (0x01); //清屏幕指令,將以前的顯示內容清除
- delay(5);
- }
- /********************************************************/
- /*
- /* LCD1602初始顯示子程序
- /*
- /********************************************************/
- void LcdInt_Dis()
- {
- uchar i=0;
- LcdInt();
- delay(15);
- WriteInstruction(0x01);
- delay(5);
- WriteAddress(0x00);
- delay(5);
- while(cdis1[i]!='\0'){
- WriteData(cdis1[i]);
- delay(5);
- i++;
- }
- WriteAddress(0x40);
- delay(5);
- i=0;
- while(cdis2[i]!='\0'){
- WriteData(cdis2[i]);
- delay(5);
- i++;
- }
- delay(3000);
- WriteInstruction(0x01); //清屏
- delay(5);
- i=0;
- WriteAddress(0x00);
- delay(5);
- while(cdis3[i]!='\0'){
- WriteData(cdis3[i]);
- delay(5);
- i++;
- }
- WriteAddress(0x40);
- delay(5);
- i=0;
- while(cdis4[i]!='\0'){
- WriteData(cdis4[i]);
- delay(5);
- i++;
- }
- WriteAddress(0x0c);
- delay(5);
- for(i=0;i<2;i++) //顯示方向符號
- WriteData(0x3e);
- }
-
- /********************************************************/
- /*
- /*數據顯示子程序
- /*
- /********************************************************/
- void data_dis()
- {
- data_temp = rate; //顯示速率
- WriteAddress(0x4c);
- WriteData(data_temp+0x30);
- delay(5);
- }
- /********************************************************
- /*
- /* 顯示運行方向符號
- /*
- /********************************************************/
- void dr_dis()
- {
- uchar i=0;
- WriteAddress(0x0c); //顯示方向符號
- if(direction==1) //正轉方向標
- {
-
- for(i=0;i<2;i++){
- WriteData(0x3e);
- delay(5);
- }
-
- }
- else
- {
- for(i=0;i<2;i++){ //反轉方向標志
- WriteData(0x3c);
- delay(5);
- }
-
- }
- }
- /********************************************************
- /*
- /* 顯示運行狀態
- /*
- /********************************************************/
- void run_dis()
- {
- uchar i=0;
- if(on_off==1){
- WriteAddress(0x00);
- delay(5);
- for(i=0;cdis5[i]!='\0';i++){
- WriteData(cdis5[i]);
- delay(5);
- }
- }
- else{
- WriteAddress(0x00);
- delay(5);
- for(i=0;cdis3[i]!='\0';i++){
- WriteData(cdis3[i]);
- delay(5);
- }
- }
- }
- /********************************************************/
- /*
- /*步進電機正轉
- /*
- /********************************************************/
- void motor_ffw()
- {
- unsigned char i;
- unsigned char j;
- for (j=0; j<8; j++)
- {
- for (i=0; i<8; i++) //一個周期轉45度
- {
- P1 = FFW[i]; //取數據
- delay(rate); //調節轉速
- }
- }
- }
-
- /********************************************************/
- /*
- /*步進電機反轉
- /*
- /********************************************************/
- void motor_rev()
- {
- unsigned char i=0;
- unsigned int j=0;
- for (j=0; j<8; j++)
- {
- for (i=0; i<8; i++) //一個周期轉45度
- {
- P1 = REV[i]; //取數據
- delay(rate); //調節轉速
- }
- }
- }
-
-
- /********************************************************
- *
- * 主程序
- *
- *********************************************************/
- void main()
- {
- LcdInt_Dis(); //液晶初始化
- TMOD=0X01; //定時器T0工作方式1
- EA=1; //開總中斷
- ET0=1; //開T0中斷
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256; //定時1ms;
- TR0=1; //啟動T0
- P1=0X0F; //關閉電機
- while(1){
- /**************************************/
- if(K1==0){
- delay(15); //延時消陡
- if(K1==0){
- on_off=~on_off; //取反
- beep();
- while(K1==0); //等待按鍵釋放
- }
-
- }
-
- /**************************************/
- if(K2==0){
- delay(15);
- if(K2==0){
- rate++;
- if(rate==0x0a) //若rate=10,則回到2重新開始
- rate=2;
- beep();
- while(K2==0);
- }
- }
- /**************************************/
- if(K3==0){
- delay(15);
- if(K3==0){
- direction=~direction;
- beep();
- while(K3==0);
- }
- }
- /**************************************/
- data_dis();
- run_dis();
- dr_dis();
- };
- }
-
- /***************************************
- 定時器0中斷
- ***************************************/
- void t0() interrupt 1
- {
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;
- v++;
- if(v<rate) //每個脈沖間隔v*1ms
- return;
- else{
- v=0;
- if(on_off==1){
- if(u==8)
- u=0;
- if(direction==1) //正轉脈沖
- P1=FFW[u];
- else
- P1=REV[u]; //反轉脈沖
- u++;
- }
- }
- }
-
復制代碼
|
|