这个可以直接用在铣床和车床上。遥控步进电机lcd1602液晶显示
下载:
遥控步进电机1602显示.rar
(133.63 KB, 下载次数: 51)
部分源码预览:
- /********************************************************************
- ***********************************************************************/
- #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:;
- }
复制代码
|