仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
步进电机和直流电机能够单独工作,仿真开始,两个电机均不转动,然后通过按键控制对应的点击正反转,代码清晰,作者留有添加电机控速的代码空间,并且可以很简单的加入代码控速模块。
其中还有一些小细节,直流电机反转的时候,无法对步进电机进行操作,即在直流电机反转过程中,控制步进电机正反转的按钮无效。其余情况下,可随意控制直流电机和步进电机的正反转
系统还有工作指示灯,对应步进电机和直流电机工作情况。
此外,还提供了一个声光报警系统,当单刀双掷开关拨至阻塞时,电路报警,电路警示灯亮,蜂鸣器响,两个电机立刻停止工作。
单片机源程序如下:
- #include<reg52.h>
- #include<stdio.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit key1=P3^0; //用户按键
- sbit key2=P3^1;
- sbit key3=P3^5;
- sbit key4=P3^6;
- sbit danger=P3^2;
- sbit beez=P2^2;
- sbit PWM1=P3^3;
- sbit PWM2=P3^4;
- sbit led1=P2^0;
- sbit led2=P2^1;
- uchar code F_Rotation[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //步进电机驱动
- uchar i;
- uint flag1,flag2,flag3,flag4;
- /******************************************************************/
- /* 延时函数Xms */
- /******************************************************************/
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /******************************************************************/
- /* 独立按键扫描函数 */
- /******************************************************************/
- void keyscan()
- {
- P3=0xff;//拉高P3,以读取P3口值
- if(key1==0)//键1被按下
- {
- delay(5);//延时消抖
- if(key1==0)
- {
- flag1++;
- flag1%=2;
- }
- while(!key1);
- delay(5);//延时消抖
- while(!key1);//松手检测
- }
- if(key2==0)
- {
- delay(5);
- if(key2==0)
- {
- flag2++;
- flag2%=2;
- }
- while(!key2);
- delay(5);
- while(!key2);
- }
- if(key3==0)
- {
- delay(5);
- if(key3==0)
- {
- flag3++;
- flag3%=2;
- }
- while(!key3);
- delay(5);
- while(!key3);
- }
- if(key4==0)
- {
- delay(5);
- if(key4==0)
- {
- flag4++;
- flag4%=2;
- }
- while(!key4);
- delay(5);
- while(!key4);
- }
- }
- void main()
- {
- TMOD=0x01;
- EA=1;
- EX0=1;
- ET0=0;
- TH0=(65536-(14648))/256;
- TL0=(65536-(14648))%256;
- TR0=0;
-
- while(1)
- {
- //步进正转
- keyscan();
- while(flag1==1)
- {
- led1=0;
- keyscan();
- if(!flag1){ led1=1; led2=1; break;}
- if(flag2){ led1=1; led2=1; flag1=0; break;}
- if(flag3){ led1=1; led2=1; flag1=0; break;}
- if(flag4){ led1=1; led2=1; flag1=0; break;}
- for(;i<8;i++)
- {
- keyscan();
- P1 = F_Rotation[i];
- if(!flag1){ led1=1; led2=1; break;}
- if(flag2){ led1=1; led2=1; flag1=0; break;}
- if(flag3){ led1=1; led2=1; flag1=0; break;}
- if(flag4){ led1=1; led2=1; flag1=0; break;}
- delay(100);
- }
- i=0;
- led1=1;
- }
- //步进反转
- keyscan();
- while(flag2==1)
- {
- led1=0;
- keyscan();
- if(flag1){ led1=1; led2=1; flag2=0; break;}
- if(!flag2){ led1=1; led2=1; break;}
- if(flag3){ led1=1; led2=1; flag2=0; break;}
- if(flag4){ led1=1; led2=1; flag2=0; break;}
- for(;i>0;i--)
- {
- keyscan();
- P1 = F_Rotation[i];
- if(flag1){ led1=1; led2=1; flag2=0; break;}
- if(!flag2){ led1=1; led2=1; break;}
- if(flag3){ led1=1; led2=1; flag2=0; break;}
- if(flag4){ led1=1; led2=1; flag2=0; break;}
- delay(100);
- }
- i=8;
- led1=1;
- }
- //直流正转
- keyscan();
- while(flag3==1)
- {
- led2=0;
- keyscan();
- if(flag1){ led1=1; led2=1; flag3=0; break;}
- if(flag2){ led1=1; led2=1; flag3=0; break;}
- if(!flag3){ led1=1; led2=1; break;}
- if(flag4){ led1=1; led2=1; flag3=0; break;}
- PWM1=0;
- PWM2=0;
- delay(100);
- PWM1=1;
- delay(100);
- led2=1;
- }
- //直流反转
- keyscan();
- while(flag4==1)
- {
- led2=0;
- keyscan();
- if(flag1);
- if(flag2);
- if(flag3){ led1=1; led2=1; flag4=0; break;}
- if(!flag4){ led1=1; led2=1; break;}
- PWM1=0;
- PWM2=0;
- delay(100);
- PWM2=1;
- delay(100);
- led2=1;
- }
- }
- }
- void int0(void) interrupt 0
- {
- while(danger==0)
- {
- beez=0;
- led1=1;
- led2=1;
- while(!danger);
- beez=1;
- }
- }
复制代码
所有资料51hei提供下载:
步进电机加直流电机.rar
(69.73 KB, 下载次数: 42)
|