还剩23页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
2015年全国大学生电子设计竞赛风力摆控制系统(B题)2015年8月15日IV摘要风力摆控制系统是一电机驱动测控系统,本系统以STC89C52单片机为控制核心,由轴流风机进行驱动,MPU6050三维角度传感器进行检测,应用PID控制算法,轴流风机调速使摆臂在一定角度范围内做自由摆及圆周运动,同时可以通过显示模块显示风力摆所处状态的各种参数本系统结构简洁分明,达到了赛题所要求的基本功能关键词风力摆;STC89C52;轴流风机;PID;目录
一、系统方案论证与选择
11.系统方案
12.方案比较与论证11控制模块的选择与论证12电机驱动模块的论证与选择13角度检测模块的论证与选择14显示方案的论证与选择2
二、系统理论分析与计算
21.机械结构的设计
22.风力摆状态的检测与计算
23.风力摆运动状态的分析
34.驱动与控制算法31电机驱动32控制算法3
三、电路及程序设计
41.电路设计41风机驱动电路设计42显示模块
52.程序设计5
四、测试结果与分析
61.测试仪器
62.测试方案与结果61风力摆做自由摆动的测试62风力摆做幅度可控摆动的测试73静止状态恢复测试
73.测试结果分析7
五、总结7参考文献9附录A主要元器件清单10附录B电路原理图11附录C源程序12
一、系统方案论证与选择
1.系统方案本系统主要由单片机控制模块、电机驱动模块、角度检测模块、电源模块组成,键盘模块,显示模块组成
2.方案比较与论证1控制模块的选择与论证方案一采用MSP430单片机MSP430系列单片机采用精简指令集结构,具有丰富的寻址方式,以及强大的处理能力并且具有超低的功耗在运算速度方面,能在8MHz晶体的驱动下,实现125ns的指令周期但是所占的指令空间较大,资料也比较少方案二采用STC89C51单片机STC89C51单片机算术运算功能强,软件编程灵活、自由度大,可用软件编程实现各种算法和逻辑控制由于其功耗低、体积小、技术成熟和成本低等优点,各个领域应用广泛并且由于芯片引脚少,在硬件很容易实现综合上述两种方案,方案二较为简单,可以满足设计要求2电机驱动模块的论证与选择方案一采用自搭接的H桥电路选用大功率达林顿管或场效应管自制H桥电路,电路原理简单,具有高效,低功率等特点,但是性能不够稳定,电路调试复杂方案二采用L298N电机驱动模块L298N是一款单片集成的高电压、高电流、双路全桥式电机驱动最高工作电压可达46v,内含两个H桥的高电压大电流全桥式驱动器,采用标准逻辑电平信号控制电子开关的速度很快,稳定性也极强综合考虑,我们选择方案二3角度检测模块的论证与选择方案一采用MPU6050芯片MPU6050集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP,可用I2C接口连接一个第三方的数字传感器并且容易上手方案二采用WDS35D芯片WDS35D传感器其测量范围为0°~360°,输出电压范围与输入电压有关,输出精度为1mv,测量精度为
0.1度,线性度好,长期稳定行好,灵敏度高,可实现对角位移的精确测量结合我们自身综合考虑,我们选择方案一4显示方案的论证与选择方案一采用LED数码管显示LED显示具有硬件电路结构简单、调试方便、软件容易实现等优点,但是数码管只能显示简单的数字,显示信息量少,不能够满足此本设计的要求方案二采用1602字符液晶LCD液晶显示具有功耗低、显示内容丰富、清晰、且显示信息量大等优点而得到广泛应用综合以上两种方案选择,本设计选择方案
二二、系统理论分析与计算
1.机械结构的设计风力摆支架采用木条自行搭建,整体高100cm,臂杆长50cm,摆杆采用长65cm的碳维纤管,并通过万向节固定在臂杆上一端摆杆下端悬挂二个直流风机,并在其下端安装一个向下的激光笔碳维纤管具有强度高,质量轻,低密度等优点,广泛应用于航模,转轴等机械设备符合本设计的要求风力摆整体结构如图
2.1所示摆杆臂杆轴流风机图
2.1风力摆结构示意图
2.风力摆状态的检测与计算采用高精度的角度传感器MPU6050不断采集风力摆姿态角数据MPU6050集成了3轴MEMS陀螺仪,3轴MEMS加速器,以及一个可扩展的数字运动处理器DMPMPU6050和所有设备寄存器之间的通信采用400KHz的I2C接口实现高速通信内置的可编程卡尔曼滤波器,采用最优化自回归数据处理算法精确测量风力摆当前姿态角MPU6050对陀螺仪和加速计分别用了三个16位的ADC,将其测量的模拟量转化为可输出的数字量,通过DMP处理器读取测量数据然后通过串口输出
3.风力摆运动状态的分析风力摆采用4个36W的直流风机为动力驱动系统,角度检测模块采集风力摆姿态角然后将采集到的信息传送到单片机,单片机处理姿态角信息调节输出PWM的占空比,进而控制四个电机的工作状态,从而实现对风力摆的控制
4.驱动与控制算法1电机驱动对于普通的直流电机,其控制方法比较简单,只需给电机的两根控制线加适当的电压即可使电机转动起来,电压越高则电机转速越高对于直流电机的速度调节,可以采用改变电压的方法,也可采用PWM调速方法PWM调速就是使加在直流电机两端的电压为方波形式,加在电机两端的电压就在VLoad和0V之间不停的跳变,对应的电机电压波形如图
2.
4.1所示T1UoThOV图
2.2PWM调速原理图此时加在电机两端的平均电压Uo=Th/(Th+Tl)*VLoad,可以通过调整PWM的占空比来改变Th和Tl的比值这样就可以通过PWM调节加在电机两端的平均电压,从而改变电机的转速2控制算法风力摆的运动是连续运动,摆杆的变化也是连续的渐变过程,因此我们采用PID控制算法对直流电机为执行器件的系统中,基本采用增量试PID算法进行控制数字PID控制算法是以模拟PID调节器控制为基础的,由于单片机是一种采样控制,只能根据采样时刻的偏差计算控制量但是如果采样周期T取得足够小,采样数值计算方法逼近可相当准确,被控过程与连续控制十分接近离散化后的PID算式为式中K:比例系数,:偏差为零时的控制作用,积分时间,微分时间,T采样时间,以上公式称为位置式算法有它可推出增量式算法式中各系数由反复实践后确定,实验证明,这种控制方式可以加快系统阶跃响应、减小超调量,并具有较高的精度
三、电路及程序设计
1.电路设计整个系统分为系统模块、编码器模块、电机驱动模块、电机模块、电源模块、键盘模块、显示模块各模块的系统框图如图
3.1所示角度检测模块键盘模块风机模块显示模块电源模块控制模块控制模块图
3.1系统框图1风机驱动电路设计L298N是ST公司生产的一种高电压,大电流电机驱动芯片该芯片最高工作电压课高达45V输出电流大,瞬间峰值电流可达到3A,持续工作电流为2A,额定功率25W内含两个H桥的高电压大电流全桥式驱动器其电路图如图
3.
1.
1.所示图
3.
1.
1.电机驱动模块2显示模块图
3.12LCD液晶显示模块
2.程序设计本系统的软件部分主要有角度测量模块、驱动PWM模块、PID控制模块函数组成,当单片机上电后,进入初始化界面,根据不同的按键,单片机进入不同的工作方式,按照不同的要求工作角度检测传感器检测风力摆的姿态,输出电压信号,进而对直流风机控制,使风力摆做不同的摆动流程框图如图
3.2所示结束开始初始化调用键盘程序基本要求一基本要求二基本要求三基本要求四角度检测传感器风机驱动模块图
3.2程序框图
四、测试结果与分析
1.测试仪器测试仪器包括秒表,量角器,米尺,自制方向图纸
2.测试方案与结果1风力摆做自由摆动的测试从静止开始驱动风力摆,使其做类似自由摆运动,在15秒内使激光笔稳定地在自制方向图纸上画出一条长度不短于50cm的直线其线性度偏差不大于±
2.5cm,并具有较好的重复性测试结果如表1所示表1风力摆画长于50cm直线测试2风力摆做幅度可控摆动的测试从静止开始启动风力摆,使其15秒内完场幅度可控的摆动,长度偏差不大于±
2.5cm测试结果如表2所示表2风力摆做幅度可控的测试3静止状态恢复测试将风力摆拉起一定角度(30°~45°)放开,使其5秒内达到静止测试结果如表4所示
3.测试结果分析测试结果分析,系统总体上达到较好的性能,完成了赛题要求的部分功能但是在测试过程中,在直流风机自身的重力及较弱风力的影响下,对于部分基本功能没有能够很好的完成,直流风机驱动设计上存在部分缺陷,驱动力不足,使风力摆在部分基本功能上没有很好地完成要求如资金充足
五、总结风力摆是一种复杂、时变、非线性、自然不稳定的高阶系统,许多抽象的控制理念概论都可以通过风力摆直观的直观的表现出来本设计通过分析控制器的基本原理,结合风力摆系统实际参数,然后通过控制理论设计控制器采用PID控制算法对直流风机调速,进而控制风力摆的运动姿态,使其达到所需要的要求在本设计中遇到的最大问题就是驱动不足,之前考虑过多种方案,但由于时间紧,任务重,系统还有一些功能未能实现,比如摆杆做类似圆周运动若经改进,相信性能还会有进一步的提升本次四天三夜的竞赛极大的锻炼了我们各方面的能力,虽然在结果上没能达到预想中的程度,但总体上成功与挫折交替,困难与希望并存我们会继续努力争取更大的进去,在此路上走的更远参考文献
[1]谭浩强.C语言程序设计[M].北京:清华大学出版社.2012
[2]康华光主编.电子技术基础[M].华中理工大学电子学教研室.2010
[3]康华光、陈大钦主编.电子技术基础数字部份[M].高等教育出版社.2010
[4]郭天祥主编.51单片机C语言教程[M].电子工业出版社.2008
[5]王宜怀、吴瑾、蒋银珍编著.单片机原理与应用[M].电子工业出版社.2005
[6]蒋焕文,孙续.电子测量[M].3版.北京中国计量出版社,2008
[7]蔡惟铮.集成电子技术.北京高等教育出版社,2004
[8]李立功,等.现代电子测量计数[M].2版.北京国防工业出版社,2008
[9]辛晓宁 王晓旭.PWM调制的设计与实现[J].电子设计工程2013,2
(4):122~124
[10]高吉祥唐朝京.全国大学生电子设计竞赛培训系列教程(电子仪器仪表设计)[M].北京:电子工业出版社20079附录A主要元器件清单附录B电路原理图附录C源程序#includeREG
52.H#includemath.h//Keillibrary#includestdio.h//Keillibrary#includeINTRINS.Htypedefunsignedcharuchar;typedefunsignedshortushort;typedefunsignedintuint;//定义51单片机端口#defineDataPortP0//LCD1602数据端口sbitSCL=P1^0;//IIC时钟引脚定义sbitSDA=P1^1;//IIC数据引脚定义sbitLCM_RS=P3^3;//LCD1602命令端口sbitLCM_RW=P3^4;//LCD1602命令端口sbitLCM_EN=P3^5;//LCD1602命令端口sbitPWM1=P2^0;//1号电机sbitPWM2=P2^1;//2号电机//定义MPU6050内部地址#defineSMPLRT_DIV0x19//陀螺仪采样率,典型值0x07125Hz#defineCONFIG0x1A//低通滤波频率,典型值0x065Hz#defineGYRO_CONFIG0x1B//陀螺仪自检及测量范围,典型值0x18不自检,2000deg/s#defineACCEL_CONFIG0x1C//加速计自检、测量范围及高通滤波频率,典型值0x01不自检,2G,5Hz#defineACCEL_XOUT_H0x3B#defineACCEL_XOUT_L0x3C#defineACCEL_YOUT_H0x3D#defineACCEL_YOUT_L0x3E#defineACCEL_ZOUT_H0x3F#defineACCEL_ZOUT_L0x40#defineTEMP_OUT_H0x41#defineTEMP_OUT_L0x42#defineGYRO_XOUT_H0x43#defineGYRO_XOUT_L0x44#defineGYRO_YOUT_H0x45#defineGYRO_YOUT_L0x46#defineGYRO_ZOUT_H0x47#defineGYRO_ZOUT_L0x48#definePWR_MGMT_10x6B//电源管理,典型值0x00正常启用#defineWHO_AM_I0x75//IIC地址寄存器默认数值0x68,只读#defineSlaveAddress0xD0//IIC写入时的地址字节数据,+1为读取//定义类型及变量uchardis
[4];//显示数字-511至512的字符数组intdis_data;//变量unsignedcharcount;//intTemperatureTemp_hTemp_l;//温度及高低位数据//函数声明voiddelayunsignedintk;//延时//LCD相关函数voidInitLcd;//初始化lcd1602voidlcd_printfuchar*sinttemp_data;voidWriteDataLCMuchardataW;//LCD数据voidWriteCommandLCMucharCMDucharAttribc;//LCD指令voidDisplayOneCharucharXucharYucharDData;//显示一个字符voidDisplayListCharucharXucharYuchar*DDataL;//显示字符串//MPU6050操作函数voidInitMPU6050;//初始化MPU6050voidDelay5us;voidI2C_Start;voidI2C_Stop;voidI2C_SendACKbitack;bitI2C_RecvACK;voidI2C_SendByteuchardat;ucharI2C_RecvByte;voidI2C_ReadPage;voidI2C_WritePage;voiddisplay_ACCEL_x;voiddisplay_ACCEL_y;voiddisplay_ACCEL_z;ucharSingle_ReadI2CucharREG_Address;//读取I2C数据voidSingle_WriteI2CucharREG_AddressucharREG_data;//向I2C写入数据//整数转字符串voidlcd_printfuchar*sinttemp_data{iftemp_data0{temp_data=-temp_data;*s=-;}else*s=;*++s=temp_data/100+0x30;temp_data=temp_data%100;//取余运算*++s=temp_data/10+0x30;temp_data=temp_data%10;//取余运算*++s=temp_data+0x30;}//延时voiddelayunsignedintk{unsignedintij;fori=0;ik;i++{forj=0;j121;j++;}}//LCD1602初始化voidInitLcd{WriteCommandLCM0x381;WriteCommandLCM0x081;WriteCommandLCM0x011;WriteCommandLCM0x061;WriteCommandLCM0x0c1;DisplayOneChar00A;DisplayOneChar01G;}//LCD1602写允许voidWaitForEnablevoid{DataPort=0xff;LCM_RS=0;LCM_RW=1;_nop_;LCM_EN=1;_nop_;_nop_;whileDataPort0x80;LCM_EN=0;}//LCD1602写入命令voidWriteCommandLCMucharCMDucharAttribc{ifAttribcWaitForEnable;LCM_RS=0;LCM_RW=0;_nop_;DataPort=CMD;_nop_;LCM_EN=1;_nop_;_nop_;LCM_EN=0;}//****************************************//LCD1602写入数据//****************************************voidWriteDataLCMuchardataW{WaitForEnable;LCM_RS=1;LCM_RW=0;_nop_;DataPort=dataW;_nop_;LCM_EN=1;_nop_;_nop_;LCM_EN=0;}//****************************************//LCD1602写入一个字符//****************************************voidDisplayOneCharucharXucharYucharDData{Y=1;X=15;ifYX|=0x40;X|=0x80;WriteCommandLCMX0;WriteDataLCMDData;}//****************************************//LCD1602显示字符串//****************************************voidDisplayListCharucharXucharYuchar*DDataL{ucharListLength=0;Y=0x1;X=0xF;whileL--{DisplayOneCharXYDData[ListLength];ListLength++;X++;}}//**************************************//延时5微秒STC90C52RC@12M//不同的工作环境需要调整此函数//当改用1T的MCU时请调整此延时函数//**************************************voidDelay5us{_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;_nop_;}//**************************************//I2C起始信号//**************************************voidI2C_Start{SDA=1;//拉高数据线SCL=1;//拉高时钟线Delay5us;//延时SDA=0;//产生下降沿Delay5us;//延时SCL=0;//拉低时钟线}//**************************************//I2C停止信号//**************************************voidI2C_Stop{SDA=0;//拉低数据线SCL=1;//拉高时钟线Delay5us;//延时SDA=1;//产生上升沿Delay5us;//延时}//**************************************//I2C发送应答信号//入口参数:ack0:ACK1:NAK//**************************************voidI2C_SendACKbitack{SDA=ack;//写应答信号SCL=1;//拉高时钟线Delay5us;//延时SCL=0;//拉低时钟线Delay5us;//延时}//**************************************//I2C接收应答信号//**************************************bitI2C_RecvACK{SCL=1;//拉高时钟线Delay5us;//延时CY=SDA;//读应答信号SCL=0;//拉低时钟线Delay5us;//延时returnCY;}//**************************************//向I2C总线发送一个字节数据//**************************************voidI2C_SendByteuchardat{uchari;fori=0;i8;i++//8位计数器{dat=1;//移出数据的最高位SDA=CY;//送数据口SCL=1;//拉高时钟线Delay5us;//延时SCL=0;//拉低时钟线Delay5us;//延时}I2C_RecvACK;}//**************************************//从I2C总线接收一个字节数据//**************************************ucharI2C_RecvByte{uchari;uchardat=0;SDA=1;//使能内部上拉准备读取数据fori=0;i8;i++//8位计数器{dat=1;SCL=1;//拉高时钟线Delay5us;//延时dat|=SDA;//读数据SCL=0;//拉低时钟线Delay5us;//延时}returndat;}//**************************************//向I2C设备写入一个字节数据//**************************************voidSingle_WriteI2CucharREG_AddressucharREG_data{I2C_Start;//起始信号I2C_SendByteSlaveAddress;//发送设备地址+写信号I2C_SendByteREG_Address;//内部寄存器地址,I2C_SendByteREG_data;//内部寄存器数据,I2C_Stop;//发送停止信号}//**************************************//从I2C设备读取一个字节数据//**************************************ucharSingle_ReadI2CucharREG_Address{ucharREG_data;I2C_Start;//起始信号I2C_SendByteSlaveAddress;//发送设备地址+写信号I2C_SendByteREG_Address;//发送存储单元地址,从0开始I2C_Start;//起始信号I2C_SendByteSlaveAddress+1;//发送设备地址+读信号REG_data=I2C_RecvByte;//读出寄存器数据I2C_SendACK1;//接收应答信号I2C_Stop;//停止信号returnREG_data;}//**************************************//初始化MPU6050//**************************************voidInitMPU6050{Single_WriteI2CPWR_MGMT_10x00;//解除休眠状态Single_WriteI2CSMPLRT_DIV0x07;Single_WriteI2CCONFIG0x06;Single_WriteI2CGYRO_CONFIG0x18;Single_WriteI2CACCEL_CONFIG0x01;}//**************************************//合成数据//**************************************intGetDataucharREG_Address{charHL;H=Single_ReadI2CREG_Address;L=Single_ReadI2CREG_Address+1;returnH8+L;//合成数据}//**************************************//在1602上显示10位数据//**************************************voidDisplay10BitDataintvalueucharxuchary{value/=64;//转换为10位数据lcd_printfdisvalue;//转换数据显示DisplayListCharxydis4;//启始列,行,显示数组,显示长度}//显示XYZ角度shortget_anglefloatxfloatyfloatzuintdir//根据x轴,y轴,z轴方向的加速度求出角度{floattemp;floatres=0;switchdir{case0://与自然Z轴的角度temp=sqrtx*x+y*y/z;res=atantemp;break;case1://与自然x轴的角度temp=x/sqrtz*z+y*y;res=atantemp;break;case2://与自然y轴的角度temp=y/sqrtx*x+z*z;res=atantemp;break;}returnres*1800/
3.14;}//显示程序voiddisplay{Display10BitDataget_angleGetDataACCEL_XOUT_H/
16.4GetDataACCEL_YOUT_H/
16.4GetDataACCEL_ZOUT_H/
16.40*
6.42820;//显示X轴加速度Display10BitDataget_angleGetDataACCEL_XOUT_H/
16.4GetDataACCEL_YOUT_H/
16.4GetDataACCEL_ZOUT_H/
16.41*
6.42870;//显示Y轴加速度Display10BitDataget_angleGetDataACCEL_XOUT_H/
16.4GetDataACCEL_YOUT_H/
16.4GetDataACCEL_ZOUT_H/
16.42*
6.428120;//显示Z轴加速度Display10BitDataGetDataGYRO_XOUT_H21;//显示X轴角速度Display10BitDataGetDataGYRO_YOUT_H71;//显示Y轴角速度Display10BitDataGetDataGYRO_ZOUT_H121;//显示Z轴角速度}//PWM函数voidpwm1ucharx//X为占空比Y为函数使用时间{ucharab;fora=x;a0;a--PWM1=1;forb=100-x;b0;b--PWM1=0;}voidpwm2uchary//X为占空比Y为函数使用时间{ucharcd;forc=y;c0;c--PWM2=1;ford=100-y;d0;d--PWM2=0;}voidtinit{TMOD=0x01;TH0=65536-50000/256;//50msTL0=65536-50000%256;ET0=1;EA=1;TR0=1;}//模式//*********************************************************//主程序//*********************************************************voidmain{delay500;//上电延cv时InitLcd;//液晶初始化InitMPU6050;//初始化MPU6050delay150;tinit;while1{display;delay500;}}voidtimer0interrupt1{count=0;TH0=65536-50000/256;//50msTL0=65536-50000%256;count++;ifcount==100{count=0;pwm120;pwm220;}}测试次数完成所需时间(t)偏差结果第一次测试16s3cm失败第二次测试15s
2.3cm成功第三次测试13s2cm成功测试次数完成所需时间(t)偏差结果第一次测试13s21cm成功第二次测试15s
2.3cm成功第三次测试12s
2.4cm成功测试次数完成所需时间(t)结果第一次测试6s失败第二次测试5s成功第三次测试6s失败序号元器件名称型号规格数量1电阻50Ω个102电阻100Ω个103电阻100KΩ个104电阻200KΩ个105轴流风机个46角度传感器MPU6050片17碳维纤管65cm根18万向节连接杆直径=10mm个19激光笔个110单片机芯片STC89C52片111液晶显示屏1602个112电机驱动模块L298N个113单片机最小系统51系列个1。