直流电机控制系统

在这里,和大家分享一下我用单片机做的一个直流电机控制系统。这是我在计算机学院的一个实训中做出来的,当时我是机械学院的,对嵌入式很感兴趣,就跨专业选了这个实训(教务网允许)。初衷嘛,我是想实现一个四旋翼飞行器,若能很好的控制4个高速电机的转速,就可以使飞行器飘起来。为此,我使用3D打印技术,制作了一个四旋翼的机架,将四个电机分别安装到4个翅膀上。下面就开始实施我的计划了!!(下面有成果图)
实现的效果是:电机的转速分为7个等级,对于4个电机,可以使用旋钮使整体调速,也可以用遥杆单独调速(在旋钮整体调速的基础上),并在显示屏上显示转速等级。
直流电机控制系统_第1张图片
目录
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.风扇控制系统的总体设计
直流电机控制系统_第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主函数的流程图
直流电机控制系统_第3张图片

4.2单片机1子函数1流程图
直流电机控制系统_第4张图片

4.3单片机1子函数2流程图
直流电机控制系统_第5张图片

4.4单片机2主函数设计
直流电机控制系统_第6张图片

4.5单片机2 pwm中断程序设计
直流电机控制系统_第7张图片

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

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

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

#include 
#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;//80
else if (D[0]>130&&D[0]<136) num=1;
else if (D[0]>=136) num=2;  
        if (D[3]<=110) suv=0;//80
else 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   
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(count1;
    else 
           pwm0=0;
    if(count1;
    else 
           pwm1=0;
    if(count1;
    else 
           pwm2=0;
    if(count1;
    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.总结
本次风扇系统的设计实现了对电机单独控制和集体控制的效果。实际上在工程中或车间里,经常会应用到各式各样的电机,为了满足生产生活的要求,需要对电机进行实时的控制,而我正是模拟了这样的控制。
由于风扇的扇叶是使用的飞行器的机翼,在转速较高的情况下,可产生较高的升力。原本希望在旋翼在转动时可以带动机体,可是由于自身重力等原因,飞不起来,可是任然能产生较大的升力。
在实时操控的模块中,摇杆的信号是通过串口的数据检测并判断的,所以有较小的延时,不能达到真正的实时控制。如果做进一步的改进的话,用中断的控制方法更为快速。

你可能感兴趣的:(嵌入式系统)