這個可以直接用在銑床和車床上。遙控步進電機lcd1602液晶顯示
0.png (59.59 KB, 下載次數: 98)
下載附件
2017-2-5 02:21 上傳
下載:
遙控步進電機1602顯示.rar
(133.63 KB, 下載次數: 51)
2017-2-4 19:13 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
部分源碼預覽:
- /********************************************************************
- ***********************************************************************/
- #include <reg51.h>
- #include <intrins.h>
- #include "lcd1602.h"
- #define uchar unsigned char
- #define uint unsigned int
- uchar LCD_ID_1[16] = {"Red Control"};
- uchar LCD_ID_2[16] = {"You press the:-"};
- void delay(uchar x); //x*0.14MS
- void delay1(int ms);
- uchar distemp = 0;
- sbit IRIN = P3^3; //紅外接收器數據線
- uchar IRCOM[7];
- sbit E=P1^2; //1602使能引腳
- sbit RW=P1^1; //1602讀寫引腳
- sbit RS=P1^0; //1602數據/命令選擇引腳
- unsigned char cMode = 0;
- unsigned char s1_num;
- unsigned int iSetData, iCurData;
- signed char RL; // 方向
- signed char iSet[3];
- signed char iCur[3];
- unsigned char T0_NUM;
- unsigned char fx_flag;
- unsigned char fx_flag2 = 0;
- sbit MotorEn = P2^1; // 使能
- sbit FX = P2^0; // 方向
- sbit CLK = P2^2; // 脈沖
- unsigned int gStep = 0;
- unsigned long gMainchong = 0;
- unsigned int gJd = 0;
- unsigned char dj_flag = 0;
- /********************************************************************
- * 名稱 : Delay()
- * 功能 : 延時,延時時間大概為1毫秒
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Delay_1ms(uint i)
- {
- uint x,j;
- for(j=0;j<i;j++)
- for(x=0;x<=148;x++);
- }
- /********************************************************************
- * 名稱 : delay()
- * 功能 : 延時,延時時間大概為140US。
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Delay2()
- {
- int i,j;
- for(i=0; i<=10; i++)
- for(j=0; j<=2; j++)
- ;
- }
- /********************************************************************
- * 名稱 : enable(uchar del)
- * 功能 : 1602命令函數
- * 輸入 : 輸入的命令值
- * 輸出 : 無
- ***********************************************************************/
- void enable(uchar del)
- {
- // P0 = del;
- P2 = del;
- RS = 0;
- RW = 0;
- E = 0;
- Delay2();
- E = 1;
- Delay2();
- }
- /********************************************************************
- * 名稱 : write(uchar del)
- * 功能 : 1602寫數據函數
- * 輸入 : 需要寫入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void write(uchar del)
- {
- // P0 = del;
- P2 = del;
- RS = 1;
- RW = 0;
- E = 0;
- Delay2();
- E = 1;
- Delay2();
- }
- /********************************************************************
- * 名稱 : L1602_init()
- * 功能 : 1602初始化,請參考1602的資料
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void L1602_init(void)
- {
- enable(0x38);
- Delay_1ms(5);
- enable(0x38);
- Delay_1ms(5);
- enable(0x38);
- Delay_1ms(5);
- enable(0x38);
- enable(0x08);
- enable(0x0c);
- enable(0x04);
- enable(0x01);
- }
- /********************************************************************
- * 名稱 : L1602_char(uchar hang,uchar lie,char sign)
- * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調用該函數如下
- L1602_char(1,5,'b')
- * 輸入 : 行,列,需要輸入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void L1602_char(uchar hang,uchar lie,char sign)
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- enable(a);
- write(sign);
- }
- /********************************************************************
- * 名稱 : L1602_string(uchar hang,uchar lie,uchar *p)
- * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
- L1602_string(1,5,"ab cd ef;")
- * 輸入 : 行,列,需要輸入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void L1602_string(uchar hang,uchar lie,uchar *p)
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- enable(a);
- while(1)
- {
- if(*p == '\0') break;
- write(*p);
- p++;
- }
- }
- /**********************************************************/
- void delay(unsigned char x) //x*0.14MS
- {
- unsigned char i;
- while(x--)
- {
- for (i = 0; i<13; i++) {}
- }
- }
- /**********************************************************/
- void delay1(int ms)
- {
- unsigned char y;
- while(ms--)
- {
- for(y = 0; y<250; y++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- //
- void Ang2()
- {
- iCurData = gMainchong*0.9/8.0;
- if(iCurData > 999)
- iCurData = 0;
- write_sfm(2, 7, iCurData);
- }
- // 計算并顯示42步進電機角度
- void Ang3()
- {
- float f_ja;
- unsigned char ge;
- f_ja = (float)(gMainchong*0.9/8.0);
- ge = ((unsigned int)(f_ja*10.0)) % 10 ;
- // if(f_ja > 5)
- // iCurData += 1;
- write_sfm(2, 7, iCurData);
- }
- // 42步進電機左轉
- void left(unsigned int Speed,unsigned int road)
- {
- //步進節拍A-D-C-B
- FX = 1;
- do{
- CLK=CLK^0x01; // 輸出脈沖
- mDelay(road); //這里的延時就可控制轉速
- gMainchong++; // 作為顯示角度的脈沖數
- Ang2(); // 計算并顯示角度
- // 顯示方向箭頭
- switch(fx_flag)
- {
- case 0:
- write_string(2, 13, "<");
- break;
- case 1:
- write_string(2, 14, "<");
- break;
- case 2:
- write_string(2, 15, "<");
- break;
- case 3:
- write_string(2, 13, " ");
- break;
- default:
- break;
- }
- Speed--;
- }
- while(Speed);
- Ang3(); // 計算并顯示角度
- MotorEn = 0; // 步進電機停止
- iCurData = 0;
- TR0 = 0; // 關閉定時器
- write_string(2, 13, "<<<");
- }
- // 42步進電機
- void right(unsigned int Speed,unsigned int road) // 脈沖數 間隔時間
- {
- //步進節拍:A-B-C-D
- FX = 0;
- do{
- CLK=CLK^0x01; // 輸出脈沖
- mDelay(road); //這里的延時就可控制轉速
- gMainchong++; // 作為顯示角度的脈沖數
- Ang2(); // 計算并顯示角度
- fx_flag2++;
- if(fx_flag2 >= 50)
- {
- fx_flag++;
- fx_flag2 = 0;
- if(fx_flag >= 5)
- fx_flag = 0;
- }
-
- // 顯示方向箭頭
- switch(fx_flag)
- {
- case 0:
- write_string(2, 13, ">");
- break;
- case 1:
- write_string(2, 14, ">");
- break;
- case 2:
- write_string(2, 15, ">");
- break;
- case 3:
- write_string(2, 13, " ");
- break;
- default:
- break;
- }
- Speed--; // 脈沖數在減小
- }
- while(Speed);
- Ang3(); // 計算并顯示角度
- MotorEn = 0; // 步進電機停止
- iCurData = 0;
- TR0 = 0; // 關閉定時器
- write_string(2, 13, ">>>");
- }
- // 8細分
- void RightStepAll()
- {
- unsigned int ja = 0;
- ja = (unsigned int)((iSetData/0.9)*8.0); // 脈沖
- if(ja != 0)
- right(ja, 10);
- }
- void LeftStepAll()
- {
- unsigned int ja = 0;
- ja = (unsigned int)((iSetData/0.9)*8.0); // 脈沖
- if(ja != 0)
- left(ja, 10);
- }
- void hw_disponse()
- {
- if(IRCOM[2] == 0x0c) // 功能鍵
- {
- s1_num++;
- cMode = 0; // 功能模式
- if(s1_num ==1) // 第1次被按下
- {
- write_com(0x80+7); // 角度 百位
- write_com(0x0f); // 光標閃爍
- }
- if(s1_num ==2)
- {
- write_com(0x80+8);
- }
- if(s1_num == 3)
- {
- write_com(0x80+9);
- }
- if(s1_num == 4)
- {
- write_com(0x80+13);
- }
- if(s1_num == 5)
- {
- s1_num = 0; // 記錄按鍵清零
- cMode = 0; // 退出模式
- write_com(0x0c); // 取消光標閃爍
- }
- }
- else if(IRCOM[2] == 0x18) // +
- {
- cMode = 0;
- if(s1_num == 1) // 百
- {
- iSet[0]++;
- if(iSet[0] >= 10)
- iSet[0] = 0;
- iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
- write_sfm(1, 7, iSetData);
- write_com(0x80+7);
- }
- if(s1_num == 2)
- {
- iSet[1]++;
- if(iSet[1] >= 10)
- iSet[1] = 0;
- iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
- write_sfm(1, 7, iSetData);
- write_com(0x80+8);
- }
- if(s1_num == 3)
- {
- iSet[2]++;
- if(iSet[2] >= 10)
- iSet[2] = 0;
- iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
- write_sfm(1, 7, iSetData);
- write_com(0x80+9);
- }
- if(s1_num == 4) // 方向
- {
- RL++;
- if(RL > 1)
- RL = 0;
- if(RL == 0)
- write_string(1, 13, "R");
- else
- write_string(1, 13, "L");
- write_com(0x80+13);
- }
- }
- else if(IRCOM[2] == 0x5e) //-
- {
- cMode = 0;
- if(s1_num == 1)
- {
- iSet[0]--;
- if(iSet[0] < 0)
- iSet[0] = 9;
- iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
- write_sfm(1, 7, iSetData);
- write_com(0x80+7);
- }
- if(s1_num == 2)
- {
- iSet[1]--;
- if(iSet[1] < 0)
- iSet[1] = 9;
- iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
- write_sfm(1, 7, iSetData);
- write_com(0x80+8);
- }
- if(s1_num == 3)
- {
- iSet[2]--;
- if(iSet[2] < 0)
- iSet[2] = 9;
- iSetData = iSet[0]*100 + iSet[1]*10 + iSet[2];
- write_sfm(1, 7, iSetData);
- write_com(0x80+9);
- }
- if(s1_num == 4) // 方向
- {
- RL--;
- if(RL < 0)
- RL = 1;
- if(RL == 0)
- write_string(1, 13, "R");
- else
- write_string(1, 13, "L");
- write_com(0x80+13);
- }
- }
- else if(IRCOM[2] == 0x08) // 運行
- {
- cMode = 0;
- gMainchong = 0;
- iCurData = 0;
- // write_sfm(2, 7, iCurData); // 當前角度已經復位
- write_sfm(2, 7, 66);
- write_string(2, 13, " ");
- // T0_Init();
- MotorEn = 1; // added 5-30
- // TR0 = 1; // 啟動
- if(RL == 0) // 右轉
- RightStepAll();
- if(RL == 1)
- LeftStepAll();
- }
- else
- {
- ;
- }
- }
- /*******************************************************************/
- main()
- {
-
- IE = 0x84; //允許總中斷中斷,使能 INT1 外部中斷
- TCON = 0x10; //觸發方式為脈沖負邊沿觸發
-
- IRIN=1; //I/O口初始化
-
- delay1(10); //延時
- MotorEn = 0; // L297 使能(只有智能,才能正常工作,否則停止)
- init_1602(); //lcd1602初始化
- write_string(1, 2, "set:");
- write_sfm(1,7,iSetData);
- write_string(2, 2, "cur:");
- write_sfm(2,7,0);
- mDelay(1);
- write_string(1, 13, "R");
- write_string(2, 13, ">>>");
- iSetData = 0;
-
- while(1);
- } //end main
- /**********************************************************/
- void IR_IN() interrupt 2 using 0
- {
- unsigned char j,k,N=0;
- EX1 = 0;
- delay(15);
- if (IRIN==1)
- { EX1 =1;
- return;
- }
- //確認IR信號出現
- while (!IRIN) //等IR變為高電平,跳過9ms的前導低電平信號。
- {delay(1);}
- for (j=0;j<4;j++) //收集四組數據
- {
- for (k=0;k<8;k++) //每組數據有8位
- {
- while (IRIN) //等 IR 變為低電平,跳過4.5ms的前導高電平信號。
- {delay(1);}
- while (!IRIN) //等 IR 變為高電平
- {delay(1);}
- while (IRIN) //計算IR高電平時長
- {
- delay(1);
- N++;
- if (N>=30)
- { EX1=1;
- return;} //0.14ms計數過長自動離開。
- } //高電平計數完畢
- IRCOM[j]=IRCOM[j] >> 1; //數據最高位補“0”
- if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //數據最高位補“1”
- N=0;
- }//end for k
- }//end for j
-
- if (IRCOM[2]!=~IRCOM[3])
- { EX1=1;
- goto LOOP; }
- switch(IRCOM[2])
- {
- case 0x16:
- distemp = 0;
- break;
- case 0x0c:
- distemp = 1;
- break;
- case 0x18:
- distemp = 2;
- break;
- case 0x5e:
- distemp = 3;
- break;
- case 0x08:
- distemp = 4;
- break;
- case 0x1c:
- distemp = 5;
- break;
- case 0x5a:
- distemp = 6;
- break;
- case 0x42:
- distemp = 7;
- break;
- case 0x52:
- distemp = 8;
- break;
- case 0x4a:
- distemp = 9;
- break;
- }
-
- hw_disponse();
- EX1 = 1;
- LOOP:;
- }
復制代碼
|