直流电机控制系统

 这篇文章写了好久了,现在看来,这篇文章还是有好多不足的地方,也是占用了一定的阅读量,现在工作的内容主要是涉及软件,好久都没有接触这些嵌入式之类的硬件了。直流电机的控制比较简单,关键还是通过c语言来进行某种频率的控制,达到控制转速的效果。其实传感器和电机之类的小硬件还是很好玩的,重要的是要多调试。还是非常怀念以前的这种调试代码的过程: 写c语言代码,把代码烧到开发版中, 然后按一下开关键,验证自己写代码的结果。虽然以前的大学生活一去不复返,然而看到自己当时写的文章,也是满满的回忆。。
 在这里,和大家分享一下我用单片机做的一个直流电机控制系统。这是我在计算机学院的一个实训中做出来的,当时我是机械学院的,对嵌入式很感兴趣,就跨专业选了这个实训(教务网允许)。初衷嘛,我是想实现一个四旋翼飞行器,若能很好的控制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;//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<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.总结
本次风扇系统的设计实现了对电机单独控制和集体控制的效果。实际上在工程中或车间里,经常会应用到各式各样的电机,为了满足生产生活的要求,需要对电机进行实时的控制,而我正是模拟了这样的控制。
由于风扇的扇叶是使用的飞行器的机翼,在转速较高的情况下,可产生较高的升力。原本希望在旋翼在转动时可以带动机体,可是由于自身重力等原因,飞不起来,可是任然能产生较大的升力。
在实时操控的模块中,摇杆的信号是通过串口的数据检测并判断的,所以有较小的延时,不能达到真正的实时控制。如果做进一步的改进的话,用中断的控制方法更为快速。

猜你喜欢

转载自blog.csdn.net/weixin_37682263/article/details/78545941