基于MSP430的悬挂控制系统报告

更新时间:2024-05-03 09:12:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

自动化专业综合课程设计1

课程设计报告

系 别: 机电与自动化学院 专业班级: 自动化0902 学 号: 20091184078 学生姓名: 邹建伟 指导教师: 李川香

2012年 6 月 24日——2012年 7 月华中科技大学武昌分校

1

日)

(课程设计时间: 2

目录

1 课程设计目的 ................................................... 2 2 课程设计题目描述和要求..........................................2 3 课程设计报告内容................................................2 3.1.1 电机的选择 .................................................. 2 3.1.2 传感器的选择 ................................................ 3 3.1.3 直线算法的选择 .............................................. 3 3.1.4 画圆算法的选择 .............................................. 3 3.1.5 画笔的控制 .................................................. 3 3.1.6 方案的确定 .................................................. 4 3.2 系统软件介绍 ................................................. 4 3.2.1 软件流程图...................................................5 3.2.2 坐标点参数的计算 ............................................ 5 3.2.3 直线的计算 .................................................. 5 3.3 系统单元电路设计 ............................................. 6 3.3.1 红外传感器连接电路 .......................................... 6 3.3.2 步进电机驱动电路 ............................................ 6 3.3.3 画笔设计 .................................................... 7 3.4 系统软、硬调试过程 ............................................ 7 3.4.1 画直线功能测试 .............................................. 7 3.4.2 画圆功能测试 ................................................ 7 3.4.3 循迹功能测试 ............................................... 7 4 总结...........................................................8 参考文献 ..........................................................9

1

1 课程设计目的

以低功耗MSP430F1611单片机系统平台为控制核心,由步进电机控制模块、红外传感和人机交互3个功能部分组成。由MSP430F1611实现相应算法产生不同状态的PWM波,以控制电机的运动,从而实现对画笔的控制。系统可通过键盘任意设置坐标点参数;控制质量大于100g的物体在仰角不大于100°的80 cmx100 cm白板上做自行设定的运动,并在白板上画出运动轨迹;控制物体沿白板上按标出的任意黑色间断曲线运动。画笔坐标点及各运动状态实时显示在LCD上,人机界面友好。

2 课程设计题目描述和要求 一 任务

设计一电机控制系统,控制物体在倾斜(仰角≤100度)的板上运动。在一白色底板上固定两个滑轮,两只电机(固定在板上)通过穿过滑轮的吊绳控制一物体在板上运动,运动范围为80cm×100cm。物体的形状不限,质量大于100克。物体上固定有浅色画笔,以便运动时能在板上画出运动轨迹。板上标有间距为1cm的浅色坐标线(不同于画笔颜色),左下角为直角坐标原点。 二 要求

(1)控制系统能够通过键盘或其他方式任意设定坐标点参数;

(2)控制物体在80cm×100cm的范围内作自行设定的运动,运动轨迹长度不

小于100cm,物体在运动时能够在板上画出运动轨迹,限300秒内完成; (3)控制物体作圆心可任意设定、直径为50cm的圆周运动,限300秒内完成; (4)物体从左下角坐标原点出发,在150秒内到达设定的一个坐标点(两点间

直线距离不小于40cm)。

3 课程设计报告内容 3.1.1 电机的选择

方案一:使用直流电机驱动画笔。直流电机能实现连续运转,只要型号选择合适,其驱动能力足以使画笔在限定的时间内画出足够长的线。但直流电机运行时的惯性比较大,不同的运行方式进行切换时,延时较长,画出的图形不能满足题目要求。

2

方案二:选用步进电机。步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响;而且步进电机只有周期性的误差而无累积误差,因而用步进电机来控制位置比用直流电机简单,故采用此方案,使用两相四线式步进电机。 3.1.2 传感器的选择

方案一:可见发光二极管与光敏二极管组成的发射-接收电路。这种方案的缺点在于其他环境光源会对光敏二极管的工作产生很大干扰,一旦外界光照条件改变,就很可能造成误判和漏判:虽然采取超高亮发光管可以降低一定的干扰,但这又将增加额外的功耗。

方案二:采用反射式红外发射—接收器。由于采用红外管代替普通可见光管,可以降低环境光源干扰。一般光源红外线频段能量较弱,对红外传感器的干扰较小,且红外线波长大,近距离衰减小,因此用红外传感器探测近距离黑线更加可靠。因此采用此方法。 3.1.3 直线算法的选择

方案一:采用Bresenham画直线算法,用一段连续线段逼近直线。根据起点和终点计算出直线的斜率,在根据程序中设置的最小△x得出△y,结合起点得出下一点的位置(x’,y’),一次类推,就可画出一整条直线。但是Bresenham算法速度慢。

方案二:采用DDA画直线算法,求出坐标起点和终点距离差值,把距离进行N等分,再分别求出x方向和y方向的增量,此增量就是步进电机每次走的长度。

此方法速度快,精度高,故采用此方法。 3.1.4 画圆算法的选择

方案一:采用Bresenham画直线算法,先用类似Bresenham画直线算法画出1/8圆,并把每个点的坐标存起来,在根据对称性,调整坐标的顺序,就能画出剩下的圆。缺点是此方法画出的圆不是很圆,需要进行补偿。

方案二:采用查表法,先用matlab生成相应的圆坐标,再用查表法查出电机要走的每个点的坐标,这种方法简单可行,画出的圆也比较圆滑。因此采用此方法。

3.1.5 画笔的控制

3

我们使用直线舵机来控制画笔的伸缩,这样能更好的控制画笔,能够自由发挥,画出更多的图形。 3.1.6 方案的确定

图1 系统方案图

经过上述的比较,我们选择MSP430F1611单片机作为系统控制器;利用键盘设置点的坐标;使用LCD12864显示运动方式、设置的坐标值及计时的时间;采用L297_L298芯片混合式步进电机驱动器;使用直线舵机来控制画笔的伸缩。 3.2 系统软件介绍 3.2.1 软件流程图

开始液晶。中断初始化是否有键按下是否直线运动画圆运动循迹运动自由运动否是否有键按下是设定坐标确定运行完成返回 图2 软件流程图

4

3.2.2坐标点参数的计算

将画笔的位置定为整个物体的中心位置,设定物体位置的初值坐标为(X,Y),当前电机A的长度L1=

(X?15)2?(115?Y)2,当前电机B的长度

L2=(95?X)2?(115?Y)2,根据电机收放线,计算出电机长度的改变量change,再由电机转动一步所对应走线的长度(其值为0.077cm),求出电机走微小步时需要时钟脉冲的个数(即为步数)pulse=(int)(change/0.03+0.5);(四舍五入后取整)。 3.2.3直线的计算

从图7我们可以看到假设原点坐标X0,Y0,要达到的坐标点X1,Y1

Y(x1,y1)L的直线(x0,y0) 图3 直线算法图

x

那么到坐标点的距离L L=

(x1?x0)2?(y1?y0)2

L 0.5我们没有采用Y=KX+B的直线方程,而是把L的长度分为COUNT_L等分 即 COUNT_L=

我们计算出每一个增量INC_X,INC_Y INC_X=

X1?X0

COUNT_LY1?Y0

COUNT_LINC_Y=

我们假设一个变量i,i的范围从1----COUNT_L

5

所以每走一步的坐标值 XX =i*INC_X+X0 YY =i*INC_Y+Y0

3.3 系统单元电路设计 3.3.1 红外传感器连接电路

图 4 红外传感器连接电路

此电路简单可行,干扰小,检测效果好。 3.3.2 步进电机驱动电路

图5 步进电机驱动电路

用L297_L298芯片作为步进电机的驱动,其转速可调、抗干扰能力强、具有续

6

流保护和过电流保护、可控制两相步进电机,电机电压直流5V~30V(12V最佳)。 3.3.3 画笔设计

用八个传感器,形成一个八边形以细化物体运动方向,能更好的检测黑色曲线,不至于跑出黑线。

3.4 系统软、硬调试过程 3.4.1 画直线功能测试 序号 设置终点(cm) LCD显示 测量值(cm) 时间(S) 3.4.2 画圆功能测试 序号 设置圆心(cm) LCD显示 测量值(cm) 时间(S) 3.4.3 循迹功能测试

能按照预定坐标到达循迹点,画笔能根据检测到的黑线运动,并且误差很小,在断点的地方也能正常运动,耗时短。 3.4.4 自由运动功能测试

我们设计的图形是写信工两个字和画五角星,画笔能按照我们设计的轨迹收放、画图,画出的图形也比较完整。

7

1 (40,40) (40,40) 2 (60,30) (60,30) 3 (30,60) (30,60) (40,40.2) (59.8,29.7) (30,59.8) 13 1 (40,50) (40,50) 17 2 (40,30) (40,30) 18 3 (40,40) (40,40) (40.2,50.3) (39.8,28,7) (40,39.8) 47 43 45

4 总结

此次题目初拿到手中时感觉有些棘手,因为相较之前的循迹小车而言,悬挂系统所用到的步进电机以及算法都要难上一个档次。我们在做好驱动电路后便马上开始了调试工作,可是在直线行走时始终走不到目标地点。在检查程序无误后我们对两个电机进行单独检查,发现左边电机需要1000拍左右才能转一圈,而右边是正常的800。于是我们据此对程序进行了修改,将误差缩小到了5cm以内。但还是不能达到要求。再经过我们仔细检查,发现左边的电机转圈过多是由于细绳不在滑轮上而产生了较大摩擦力造成,发现这一点后,我们终于使滑块走出比较精确的直线,误差控制在1cm以内。

另外通过这次的制作,可以知道我们的硬件制作的工作量不大,作为一个写程序的人员,我认识到一个好的算法可以省去大量的硬件设备,同时,我也认识到了自己在编程方面还有着很多需要学习的地方,在今后的学习中,我会更加努力,争取在今年胡省赛中能取得一个好的成绩。

这次实验感谢李川香老师以及何为老师的指导,从实验中,无论在硬件设计还是软件编程,我们都收获了丰富的实践经验,为知识的应用与扩展打下了坚实基础。

8

参考文献

[1] 童诗白,华成英 .模拟电子基础.高等教育出版社.2012.

[2] 谢自美 .电子线路设计·实验·测试 .武汉:华中科技大学出版社.2012. [4] 沈建华,杨艳琴 .MSP430系列超低功耗单片机原理与实践 .北京:航空航天大学出版社.2012.

[5] 曹磊 .MSP430单片机C程序设计与实践. 北京:航空航天大学出版社.2012.

9

附录 系统完整程序 函数主程序:

#include \#include\

unsigned char table[8]={0X04 , 0x14 , 0x10 , 0x12 , 0x02 , 0x0a , 0x08 , 0x0c}; void init(void);

void draw_line1(float x0,float y0,float x1,float y1);

void draw(float x0,float y0,float x1,float y1);

void draw_cycle(float r,float x0,float y0); void motor_step(float lx,float ly); void left_1(unsigned int count); void left_0(unsigned int count); void right_1(unsigned int count); void right_0(unsigned int count); extern float zx,zy,ox,oy,qx,qy; float rx,lx; float

length_r=0.117,length_l=0.117,pai=3.14159; int dir_l,dir_r; int main( void ) {

// Stop watchdog timer to prevent time out reset

WDTCTL = WDTPW + WDTHOLD; init(); Init_Port1(); Init_Lcd_12864(); set_up();

Display_now_lcd12864();

draw_cycle( 10, ox, oy);//画圆,按键设定圆心与半径

//draw(qx,qy,zx,zy);//画线,按键设定起点与终点

//draw(25.0,50.0,40.0,10.0); //draw(40.0,10.0,10.0,40.0); //draw(10.0,40.0,40.0,40.0); //draw(40.0,40.0,10.0,10.0); }

void init(void)

10

{

char i=0;

BCSCTL1 &=~XT2OFF;// 开启 XT2 do {

IFG1 &= ~OFIFG;

for (i = 0xFF; i > 0; i--); }

while( (IFG1&OFIFG) ); //XT2异常

BCSCTL2=SELM_2+SELS; //MCLK = SMCLK = XT2 }

void draw_line1(float x0,float y0,float x1,float y1) {

float l0,l1,r0,r1,dl,dr,dl0,dr0;

l0=sqrt((x0+5)*(x0+5)+(107-y0)*(107-y0)); l1=sqrt((5+x1)*(5+x1)+(107-y1)*(107-y1));

r0=sqrt((85-x0)*(85-x0)+(107-y0)*(107-y0));

r1=sqrt((85-x1)*(85-x1)+(107-y1)*(107-y1)); dl=l1-l0; dr=r1-r0; if(dl>0) {

dir_l=1; //表示长度增加,为反转 dl0=(dl); } else {

dir_l=-1; //表示长度减小,为正转 dl0=-(dl); } if(dr>0) {

dir_r=1; //表示长度增加,为反转 dr0=dr; } else {

dir_r=-1; //表示长度减小,为正转

dr0=-(dr); }

motor_step(dl0,dr0); }

void motor_step(float lx,float rx) {

unsigned int step_l,step_r,first ,second,kv; unsigned int i,j;

LEFT_down(1); }

RIGHT_down(second); } } }

if((dir_l==1)&&(dir_r==-1)) {

if(step_l>=step_r) {

step_l=( int)(lx/length_l+(dir_l?0.5:-0.5));

step_r=( int)(rx/length_r+(dir_r?0.5:-0.5)); if(step_l>=step_r) {

first=step_r;

second=step_l%step_r; kv=step_l/step_r; } else {

first=step_l;

second=step_r%step_l; kv=step_r/step_l; }

if((dir_l==1)&&(dir_r==1)) {

if(step_l>=step_r) {

for(j=0;j<8;j++) {

for(i=0;i

RIGHT_down(1); LEFT_down(kv); }

LEFT_down(second); }} else {

for(j=0;j<10;j++) {

for(i=0;i

RIGHT_down(kv);

11

for(j=0;j<10;j++) {

for(i=0;i

LEFT_down(kv); RIGHT_up(1); }

LEFT_down(second); }} else {

for(j=0;j<10;j++) {

for(i=0;i

LEFT_down(1); RIGHT_up(kv); }

RIGHT_up(second); } }}

if((dir_l==-1)&&(dir_r==1)) {

if(step_l>=step_r) {

for(j=0;j<10;j++) {

for(i=0;i

LEFT_up(kv); RIGHT_down(1); }

LEFT_up(second); }} else

{

for(j=0;j<10;j++) {

for(i=0;i

LEFT_up(1); RIGHT_down(kv); }

RIGHT_down(second); } } }

if((dir_l==-1)&&(dir_r==-1)) {

if(step_l>=step_r) {

for(j=0;j<10;j++) {

for(i=0;i

LEFT_up(kv); RIGHT_up(1); }

LEFT_up(second); } } else {

for(j=0;j<10;j++) {

for(i=0;i

LEFT_up(1); RIGHT_up(kv); }

RIGHT_up(second); } } } }

void draw(float x0,float y0,float x1,float y1) {

float inc_x,inc_y,x0_0,y0_0,x2,y2; int i=20; inc_x=(x1-x0)/i;

12

inc_y=(y1-y0)/i; x0_0=x0; y0_0=y0; while(i--) {

x2=x0_0+inc_x; y2=y0_0+inc_y;

draw_line1( x0_0, y0_0, x2, y2);

Display_Hex2Dec_Lcd_12864(6,8,(uint)x2); Display_Hex2Dec_Lcd_12864(6,12,(uint)x2); x0_0=x2; y0_0=y2; } }

void draw_cycle(float r,float x0,float y0) { int i;

float now_x,now_y,next_x,next_y; now_x=x0; now_y=y0-r;

for(i=-90.0;i<=275.0;i+=5) {

if((i>=-90.0)&(i<0.0)) {

next_x=r*cos(i*pai/180.0)+x0; next_y=r*(sin(i*pai/180.0))+y0; }

if((i>=0.0)&(i<90.0)) {

next_x=r*(cos(i*pai/180.0))+x0; next_y=r*sin(i*pai/180.0)+y0; }

if((i>=90.0)&(i<180.0)) {

next_x=r*cos(i*pai/180.0)+x0; next_y=r*(sin(i*pai/180.0))+y0; }

if((i>=180.0)&(i<=275.0)) {

next_x=r*(cos(i*pai/180.0))+x0; next_y=r*sin(i*pai/180.0)+y0; }

draw_line1(now_x,now_y,next_x,next_y);

Display_Hex2Dec_Lcd_12864(6,8,(uint)next_x);

Display_Hex2Dec_Lcd_12864(6,12,(uint)next_y);

now_x=next_x; now_y=next_y; } }

/******************说明 p3口送两个电机的数据 p2使能驱动

测试左右电机收放线的情况 ********************/

#include \#include \

#define CPU_F ((double)8000000) #defindelay_nus(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0));

#definedelay_nms(x)__delay_cycles((long)(CPU_F*(double)x/1000.0));

unsigned int Lcount,Rcount,Bothcount; unsigned xa0,0x80,0x90}; unsigned x0a,0x08,0x09}; unsigned

2,0xaa,0x88,0x99};

13

char

Bothcontrolstep[8]={0x11,0x55,0x44,0x66,0x2

char

Lcontrolstep[8]={0x01,0x05,0x04,0x06,0x02,0

char

Rcontrolstep[8]={0x10,0x50,0x40,0x60,0x20,0

void LEFT_down(unsigned int count) //左边电机放线 {

unsigned int i; for(i=1;i<=count;i++) {

if(Lcount==7)Lcount=0; else Lcount++;

P3OUT|=Lcontrolstep[Lcount]; P3OUT&=Lcontrolstep[Lcount]|0Xf0; delay_nms(1); } }

void LEFT_up(unsigned int count) //左边电机收线 {

unsigned int i; for(i=1;i<=count;i++) {

if(Lcount==0)Lcount=7; else Lcount--;

P3OUT|=Lcontrolstep[Lcount];

P3OUT&=Lcontrolstep[Lcount]|0XF0; delay_nms(3); } }

void RIGHT_down(unsigned int count) //右边电机放线 {

unsigned int i; for(i=1;i<=count;i++) {

if(Rcount==7)Rcount=0; else Rcount++;

P3OUT|=Rcontrolstep[Rcount]; P3OUT&=Rcontrolstep[Rcount]|0X0F; delay_nms(3); } }

void RIGHT_up(unsigned int count) //右边电机收线

{

unsigned int i; for(i=1;i<=count;i++) {

if(Rcount==0)Rcount=7; else Rcount--;

P3OUT|=Rcontrolstep[Rcount]; P3OUT&=Rcontrolstep[Rcount]|0X0F; delay_nms(3); } }

void Together_down(unsigned int count) //左右边电机收线 {

unsigned int i; for(i=1;i<=count;i++) {

if(Bothcount==0)Bothcount=7; else Bothcount--;

P3OUT|=Bothcontrolstep[Bothcount];

P3OUT&=Bothcontrolstep[Bothcount]|0X00; delay_nms(1); } }

/*按键程序*/

#include\#include\/*

端口是P1.0-P1.5 */ /*

KEY6 --------------------P1.0 KEY5 --------------------P1.1 KEY4 --------------------P1.2 kEY3---------------------P1.3 KEY2 --------------------P1.4

KEY1--------------------P1.5 */

float ox,oy,zx,zy,qx,qy; int key_num,num_x,num_y; void set_up() {

while(P1IE); }

#pragma vector=PORT1_VECTOR __interrupt void Port_1() {

delays(); switch(P1IFG) {

case 0x01:

key_num++; key_show();break; case 0x02:

key_num--; key_num+=4; key_show();break; case 0x04:num_x=5;

key_show();break; case 0x08:num_y=5;

key_show();break; case 0x10:num_x=-5; num_y=-5; key_show();break; case 0x20:P1IE&=~0XFF;break; default: break; }

P1IFG&=~0XFF; }

void delays() {

uint i,j;

for(i=500;i>0;i--) for(j=1000;j>0;j--); }

void key_show() {

key_num=key_num%4; Clr_Screen_Lcd_12864();

14

Delay_ms(1);

if(key_num==0) // {

Display_yuanxinsheding_lcd12864(key_num);

Display_Hex2Dec_Lcd_12864(2,12,(uint)zy); }

if(key_num==2) {

Display_zhongdian_lcd_12864(key_num); ox+=num_x; oy+=num_y;

Display_Hex2Dec_Lcd_12864(0,8,(uint)ox);

Display_Hex2Dec_Lcd_12864(0,12,(uint)oy); }

if(key_num==1) {

Display_zhixiansheding_lcd12864(key_num); zx+=num_x; zy+=num_y;

Display_Hex2Dec_Lcd_12864(2,8,(uint)zx);

课程设计成绩:

qx+=num_x; qy=num_y;

Display_Hex2Dec_Lcd_12864(4,8,(uint)qx);

Display_Hex2Dec_Lcd_12864(4,12,(uint)qy); }

if(key_num==3) {

// Display_now_lcd12864(key_num); } num_x=0; num_y=0; }

15

项 目 业务考核成绩(70%) (百分制记分) 平时成绩(30%) (百分制记分) 综合总成绩 (百分制记分) 悬挂控制系统 注:教师按学生实际成绩(平时成绩和业务考核成绩)登记并录入教务MIS系统,由系统自动转化为“优秀(90~100分)、良好(80~89分)、中等(70~79分)、及格(60~69分)和不及格(60分以下)”五等。

指导教师评语:

指导教师(签名):

20 年 月 日

16

本文来源:https://www.bwwdw.com/article/kzjg.html

Top