直流电机控制系统

来源:互联网 发布:mac取消密码登录 编辑:程序博客网 时间:2024/05/02 06:10

在这里,和大家分享一下我用单片机做的一个直流电机控制系统。这是我在计算机学院的一个实训中做出来的,当时我是机械学院的,对嵌入式很感兴趣,就跨专业选了这个实训(教务网允许)。初衷嘛,我是想实现一个四旋翼飞行器,若能很好的控制4个高速电机的转速,就可以使飞行器飘起来。为此,我使用3D打印技术,制作了一个四旋翼的机架,将四个电机分别安装到4个翅膀上。下面就开始实施我的计划了!!(下面有成果图)
实现的效果是:电机的转速分为7个等级,对于4个电机,可以使用旋钮使整体调速,也可以用遥杆单独调速(在旋钮整体调速的基础上),并在显示屏上显示转速等级。
这里写图片描述
目录
1.课题简介 1
2.风扇控制系统的总体设计 1
3.电路设计 1
3.1 LED1602液晶显示屏电路图 1
3.2 旋钮的控制电路 2
3.3摇杆的控制电路 2
3.4显示模块:LCD1602液晶显示屏 2
4.程序设计 4
4.1单片机1主函数的流程图 4
4.2单片机1子函数1流程图 5
4.3单片机1子函数2流程图 6
4.4单片机2主函数设计 6
4.5单片机2 pwm中断程序设计 7
5 系统测试 8
5.1测试的原理 8
5.2测试的过程 8
6.附录 10
附录A:实物照片 10
附录B:源代码 10
7.总结 22
8.感谢 22
9. 参考文献 22

1.课题简介
随着时代的发展,科技的进步,微电子技术也在不断的发展。单片机的应用也越来越贴近生活,用单片机来实现一些电子设计也变得很容易。直流电机的控制在生产生活中很常见,本次设计是用单片机来控制简单的直流电机系统,通过控制模块来调节单片机的转速。
2.风扇控制系统的总体设计
这里写图片描述

3.电路设计
3.1 LED1602液晶显示屏电路图
(此处略,网上有各种资料)

3.2 旋钮的控制电路
介绍:旋钮模块一共有五个引脚,其中两根为电源和接地引脚。SW引脚的作用是旋钮按下去时,给单片机低电平的信号。另外两个引脚CLK与DT相互作用,来表示旋钮的正反转,当两个引脚的信号变化为11——01——00——10时,表示顺时针旋转。当两个引脚的信号变化为11—–10—–00—–01时,表示逆时针旋转。单片机检测整个模块传来的电信号,进行数据处理。

3.3摇杆的控制电路
摇杆模块一共有五个引脚,其中两根为电源和接地,SW引脚判断摇杆是否按下,VRx与VRy引脚是用来表示x方向与y方向的位移大小。在单片机系统设计中,其实是用数模转换模块PCF8591,通过I2C总线传输的方式进行数据传输,并在串口调试助手中一直检测x方向和y方向的电阻值变化

4.程序设计(这里本来有许多图,还不会用这个博客,图片弄不上去。。。。)

4.1单片机1主函数的流程图
这里写图片描述

4.2单片机1子函数1流程图
这里写图片描述

4.3单片机1子函数2流程图
这里写图片描述

4.4单片机2主函数设计
这里写图片描述

4.5单片机2 pwm中断程序设计
这里写图片描述

5 系统测试
5.1测试的原理
整个系统一共有两个控制模块,旋钮和摇杆,当旋钮顺时针旋转时,电机的转速逐渐升高,在LCD显示屏中显示电机的转速级别,逆时针旋转时,电机转速逐渐降低,直至为0.当按下旋钮时,电机的转速直接跳转为0。摇杆的作用是分别控制四个电机的转速,摇杆的方向分别为上,下,左,右时,对应的控制电机序号分别为一,二,三,四。按下旋钮,各个电机的转速增量变为0。同时,摇杆和旋钮可以共同作用,一起控制电动机的转速。
5.2测试的过程
(1)旋钮和摇杆的控制
这里写图片描述

6.附录
附录A:实物照片

附录B:源代码
单片机1源代码

#include <I2C.H>#include "lcd.h"#define uchar unsigned char#define  PCF8591 0x90    unsigned char AD_CHANNEL;unsigned long xdata  LedOut[8];unsigned char  D[32];sbit aPin=P1^0;sbit bPin=P1^1;sbit press=P1^2;sbit P2_0 = P2^0;sbit P2_1 = P2^1;sbit p22 = P2^2;//sbit p23 = P2^3;//sbit p24 = P2^4;//sbit p12 = P1^2;sbit p13 = P1^3;//sbit p14 = P1^4;//sbit p15 = P1^5;//sbit p16 = P1^6;sbit p17 = P1^7;unsigned char peng[]="0123456789";unsigned char date;unsigned int num;unsigned int suv;int a;unsigned char count;//unsigned char jd=8;//sbit pwm0=P2^2;//sbit pwm1=P2^3;//sbit pwm2=P2^4;//sbit pwm3=P2^3;sbit jia=P3^2;sbit jian=P3^3;unsigned char jd;  // int scan();void display(int m);void delay(int i);bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val);bit ISendByte(unsigned char sla,unsigned char c);unsigned char IRcvByte(unsigned char sla);void Initial_com(void);void xuanniu_process();void yaogan_process();void xuanniu_process()//{    a=a+scan();        if(a<0) a=0;        if(a>7) a=7;         display(a);        jd=a;        if(p12==0) a=0;        switch (jd)         {            case 0:p24=0;p23=0;p22=0;break;            case 1:p24=0;p23=0;p22=1;break;            case 2:p24=0;p23=1;p22=0;break;            case 3:p24=0;p23=1;p22=1;break;            case 4:p24=1;p23=0;p22=0;break;            case 5:p24=1;p23=0;p22=1;break;            case 6:p24=1;p23=1;p22=0;break;            case 7:p24=1;p23=1;p22=1;break;        }    }    void yaogan_process()//    {        switch(AD_CHANNEL)        {            case 0: ISendByte(PCF8591,0x41);                 D[0]=IRcvByte(PCF8591);  //                 break;              case 1: ISendByte(PCF8591,0x42);                 D[1]=IRcvByte(PCF8591);  //                 break;              case 2: ISendByte(PCF8591,0x43);                 D[2]=IRcvByte(PCF8591);  //                 break;                      case 3: ISendByte(PCF8591,0x40);                 D[3]=IRcvByte(PCF8591);  //ADC3                    break;                          case 4: DACconversion(PCF8591,0x40, D[4]); //                 break;                }        D[4]=D[3];  //                   if(++AD_CHANNEL>4) AD_CHANNEL=0;           delay(200);        delay(200);     SBUF=D[0];     delay(200);     SBUF=D[3];     delay(200);                if (D[0]<=130) num=0;//80else if (D[0]>130&&D[0]<136) num=1;else if (D[0]>=136) num=2;          if (D[3]<=110) suv=0;//80else if (D[3]>110&&D[0]<=134) suv=1;else if (D[3]>134)  suv=2;  //i have try a lot,but it seems that        if(num==0&&suv==1) {p15=0;p14=0;p13=0;} //right        if(num==2&&suv==1) {p15=0;p14=1;p13=0;}//left        if(num==1&&suv==0) {p15=0;p14=1;p13=1;}//up        if(num==1&&suv==2) {p15=1;p14=0;p13=1;}//down        if(num==1&&suv==1) {p15=0;p14=0;p13=1;}//center     if(RI)    {        date=SBUF;    //        SBUF=date;    //    RI=0;    }       }int scan(){    static int oldA=0;    static int oldB=0;    int result =0;    int newA =aPin,newB=bPin;    if(oldA!=newA||oldB!=newB)//something has changed    {        /*if (oldA==0&&oldB==0)        {           if (newA==1) result=1;            else result =-1;        }         else if (oldA==1&&oldB==1)            {           if (newA==1) result=-1;            else result =1;            if (oldA==0&&newA==1)            result = -(oldB * 2 - 1);                    //else result=0;            }    oldA=newA;         oldB=newB; return result;}void display(int m){               LcdWriteCom(0x80);                 LcdWriteData(peng[m]);}main(){        a=0;     count=0;    //Time0_Init();    LcdInit();    Initial_com();    while(1)    {xuanniu_process();//yaogan_process();//    //unsigned int num1;        }}void delay(int i){  uchar j,k;   for(j=i;j>0;j--)    for(k=125;k>0;k--);}bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val){   Start_I2c();              //Æô¶¯×ÜÏß   SendByte(sla);            //•¢ËÍÆ÷¼þµØÖ•   if(ack==0)return(0);   SendByte(c);              //•¢ËÍ¿ØÖÆ×Ö½Ú   if(ack==0)return(0);   SendByte(Val);            //•¢ËÍDACµÄÊýÖµ     if(ack==0)return(0);   Stop_I2c();               //½áÊø×ÜÏß   return(1);}bit ISendByte(unsigned char sla,unsigned char c){   Start_I2c();              //   SendByte(sla);            //   if(ack==0)return(0);      //   SendByte(c);              //   if(ack==0)return(0);   Stop_I2c();               //   return(1);}unsigned char IRcvByte(unsigned char sla){  unsigned char c;   Start_I2c();          //   SendByte(sla+1);      //   if(ack==0)return(0);//   c=RcvByte();          //   Ack_I2c(1);           //   Stop_I2c();           //   return(c);}void Initial_com(void){ EA|=1;        // ES|=1;        // ET1|=1;        // TMOD|=0x20;   // PCON|=0x00;   //SMOD=0 SCON|=0x50;   // TH1=0xfd;    // TL1=0xfd; TR1=1;       //}单片机2代码#include<reg51.h>   unsigned char count;sbit pwm0=P0^0;sbit pwm1=P0^1;sbit pwm2=P0^2;sbit pwm3=P0^3;//ÓÃÀ´¿ØÖƵç»úµÄËĸöÒý½Åsbit p07=P0^7;sbit p25=P2^5;sbit p26=P2^6;sbit p27=P2^7;sbit jia=P3^2;sbit jian=P3^3;sbit p10=P1^0;sbit p22 = P2^2;sbit p23 = P2^3;sbit p24 = P2^4;sbit p13 = P0^4;sbit p14 = P0^5;sbit p15 = P0^6;sbit p16 = P1^6;sbit p17 = P1^7;sbit p30=P3^0;sbit p31=P3^1;unsigned char wu[]=" I Love You!     ";unsigned char peng[]="000045090135180"; unsigned char jd; unsigned char jd0; unsigned char jd1; unsigned char jd2; unsigned char jd3;int DisplayData[4]={0,1,2,3};void Time0_Init(){  TMOD=0x01;    IE=0x82;//    TH0=0xfe;    TL0=0x33;    TR0=1;    }void Time0_Int()interrupt 1{  TH0=0xfe;    TL0=0x33;        if(count<jd+jd0)            pwm0=1;    else            pwm0=0;    if(count<jd+jd1)            pwm1=1;    else            pwm1=0;    if(count<jd+jd2)            pwm2=1;    else            pwm2=0;    if(count<jd+jd3)            pwm3=1;    else            pwm3=0;    count=(count+1);    count=count%7;    }/////////////keyscan//////////////void bottomscan(){  if(p10==0)    {      jd0=0;jd1=0;jd2=0;jd3=0;    }}void keyscan(){    int a,b,c;    a=p22;b=p23;c=p24;    jd=(a*1+b*2+c*4);}/////////handle/////////////////void handlescan(){  int m=0;  static int old0=0,old1=0,old2=0;    int new0,new1,new2;    int jd00=0,jd11=0,jd22=0,jd33=0;//everytime it become zero    new0=p13;new1=p14;new2=p15;     //jd0=jd;jd1=jd;jd2=jd;jd3=jd;    if(old0!=new0||old1!=new1||old2!=new2)//something has changed    {  if(p15==0&&p14==0&&p13==0) m=0;    if(p15==0&&p14==0&&p13==1) m=1;    if(p15==0&&p14==1&&p13==0) m=2;    if(p15==0&&p14==1&&p13==1) m=3;    if(p15==1&&p14==0&&p13==0) m=4;    if(p15==1&&p14==0&&p13==1) m=5;    if(p15==1&&p14==1&&p13==0) m=6;    if(p15==1&&p14==1&&p13==1) m=7;            switch (m)        {            case 0:{jd00=1;break;}            case 1:break;            case 2:{jd22=1;break;}            case 3:{jd11=1;break;}            case 4:break;            case 5:{jd33=1;break;}        }            }    old0=new0;old1=new1;old2=new2;    jd0+=jd00;jd1+=jd11;jd2+=jd22;jd3+=jd33;}void main(){    jd=0;     count=0;     Time0_Init();    p16=0;p17=0;p30=0;p31=0;     while(1)     {bottomscan();         handlescan();       keyscan();     } }

`
7.总结
本次风扇系统的设计实现了对电机单独控制和集体控制的效果。实际上在工程中或车间里,经常会应用到各式各样的电机,为了满足生产生活的要求,需要对电机进行实时的控制,而我正是模拟了这样的控制。
由于风扇的扇叶是使用的飞行器的机翼,在转速较高的情况下,可产生较高的升力。原本希望在旋翼在转动时可以带动机体,可是由于自身重力等原因,飞不起来,可是任然能产生较大的升力。
在实时操控的模块中,摇杆的信号是通过串口的数据检测并判断的,所以有较小的延时,不能达到真正的实时控制。如果做进一步的改进的话,用中断的控制方法更为快速。

原创粉丝点击