1、 2011年全国大学生电子设计竞赛 基于自由摆的平板控制系统(B题) 2011年9月3日 15 摘 要 本系统以STC12C5410AD单片机为处理器,通过控制平板时刻与摆杆相垂直以实现硬币与平板保持相对稳定(即硬币不从平板滑落)的状态。而对电位器不同电阻值所分得的电压值进行处理,通过处理得到摆杆与竖直方向的角度,从而让步进电机能准确控制平板,以达到平板上的激光始终照射到一条直线的状态。 关键词:STC12C5410AD 电位器传感装置 角度检测
2、 目录 一、方案论证与比较 3 1.硬件机械结构 3 2.角度检测 3 3.平板控制 6 二、硬件系统的设计与实现 8 1.系统的总框图 8 2.电位器检测电路 9 3.模数转换电路 9 4.电机驱动电路 10 5.平板的控制实施步骤及编程思想 10 三、程序设计 11 1、数据的测试 11 2、程序的设计与实现 11 一、方案论证与比较 本系统在设计的过程中可主要针对硬件机械结构、角度检测和平板控制3个模块进行设计,然后再将3个模块进行有效组合。 1.硬件机械结构 对于硬件的机械结
3、构,我们本着在配合角度检测和平板控制的前提下尽量简化机械结构的理念,就近取材,简单设计。因机械结构、角度检测和平板控制3个模块之间相互融合,所以在接下来的角度检测和平板控制的方案中也会涉及到硬件机械结构的讨论。 2.角度检测 方案一:加速度传感器检测法 通过3轴加速度传感器检测数据,计算摆杆与竖直方向的角度。如图1-1所示,在摆杆上放置一块3轴加速度传感器,当摆杆在进行自由摆的过程中,测试出摆杆空间三维坐标系中三个坐标轴方向的加速度分别为、、和,因此可得在某一时刻,在某一平面内摆动的摆杆的加速度a为:。 而在某一确定平面内,当加速度a确定 时便可确定a与竖自方向的夹角便可 确定
4、如图1-2所示,由可知, 图1-1 加速度检测装置模拟图 。同一个对应摆杆在一确定平 面内对应竖直方向分别向左右偏置的两个位置。 若我们定义左边为正方向,则左右两个位置对 应的角度分别为和。在确定的某一位置 也对应着摆杆的上升和下降两种状态。 图1-2 合加速度与重力加速度的关系 方案二:红外对管检测法 通过红外对管检测数据,计算摆杆与竖直方向的角度。如图1-3在摆杆的转轴处设计一个圆盘,圆盘固定在支架上。在圆盘边缘均匀的放置多个红外对管,摆杆在自由摆动的过程中会按一定顺序遮挡
5、住分布在圆盘上的红外对管,这时的通过单片机检测红外对管的输出电平,电平的值高低变化经过单片机的处理后进而用以控制步进电机转动的角度。 图1-3 图题? 图1-3 红外对管检测法装置模拟图 方案三:电位器检测法 如图1-4,将电位器的旋转轴当作摆杆的转轴,摆杆转动时电位器的电阻发生变化,于是在电位器接入电路部分的变化电阻两端可得到一组与角度值具有线性关系的电压值。而有简要分析可知,任何一个角度都有一个电阻值与之对应,而电压值与电阻值成正比,于是可知摆杆角度与滑动变阻两端的电压值也有一一对应的关系。
6、 图1-4 电位器检测法装置模拟图 以上三个方案中,方案一是通过3轴加速度传感器(也有人不准确的称呼为角度传感器)检测法是许多人最容易想到的,这样可以通过加速度传感器和单片机处理处摆杆偏转的角度,然后再用步进电机对补办进行补偿使得平板始终保持在水平方向。这个方案,精确度较高,容易想到。但是,这个方案传感器使用较为复杂,程序设计较为困难,难以实现,且传感器价格较高;方案二利用光电传感器,检测摆杆位置,操作简单,程序相对容易,但因传感器不能紧密排列在圆盘上,故测量误差比较大,且电路结构较为复杂;方案三,利用摆杆转动带动电位器旋转轴的转动,可以用物理量直接放映出角
7、度的大小,然后对得到的物理量进行A/D转换,利用得到的数字信号来控制步进电机的转动,且机械结构简化,利用率高,程序容易实现。 通过以上对比,我们容易发现方案三因在检测角度方法直接,机械结构简化且巧妙,程序简单,易于操作等各方面的突出的优势,我们选择方案三。 3.平板控制 平板的控制主要涉及到控制电机的选择和平板在运动过程中应该保持的最理想的状态。 (1)电机的选取 控制电机应该选用步进电机,因为直流电机的转速虽能控制,但时间长度难以高精度控制,而这样的误差会导致实际电机旋转角度与理想值之间存在较大差距;而步进电机无法旋转360度故不符合要求。而步进电机可以精确的控制电机的旋转角度,且
8、能完成360度旋转。 (2)平板在自由摆过程中的状态(基本要求的第二三问) 方案一:保持自由摆过程中平板与水平面的平行 由角度检测模块提供的数字信号经过单片机处理后可控制步进电机的旋转使得平板时刻与水平面平行,许多人理所当然的以为这样就可以有效的防止硬币从平板上滑落。 下面我们在平板保持平行状态时分别对硬币和平板进行受力分析,如图1-5 所示。 G x y y x 图1-5 平板保持水平时硬币和平板的受力分析图 左图为硬币受力分析图,其中为平板对硬币的支持力,G为硬币自身的重力,f为硬币受到的摩擦力。题目中要求平板必须为表面光滑的
9、硬质平面,所以此时的摩擦力会非常小,可以近似看作硬币在平板所在平面方向(即水平方向)的合外力约等于零,此时硬币在水平方向加速度等于零。 右图为平板受力分析图,其中为平板自身重力,表示硬币对平板产生的摩擦力,表示在摆杆摆动过程中步进电机的转轴对平板产生的扭力与支持力的合力。在水平方向的合力,因平板表面为光滑硬质平板,则水平方向加速度为,又 因硬币在水平方向角速度为零,故在平板时刻保持水平状态时硬币是非常容易从平板上滑落的。 方案二:保持自由摆过程中平板与摆杆的垂直 当我们非常冷静地思考问题时,其实不难发现,当平板时刻与摆杆保持垂直时,硬币才最不容易从平板上滑落,此时,控制电机根本不需要转
10、动。 图1-6 平板与摆杆保持垂直时硬币和摆杆的受力分析图 如图1-6所示,做图表示为任意时刻(假设此时摆杆与竖直方向角度为)对硬币的受力分析图,在平板方向上,硬币的合力。因平板为光滑硬质平面,f非常小,故硬币在平板方向加速度约为 ≈ 右图是与左图相同时刻,平板的受力分析图。平板在其自身所在方向上的合力为,同样在忽略摩擦力的情况下,平板在自身平面方向上加速度为 ≈ 此时,硬币和平板在运动方向上的加速度是相同的,又因最初硬币和平板有相同的初速度(初速度为零),故可以近似认为在整个摆动过程中硬币和平板的运动状态是完全相同的。因而,当平板时刻保持与摆杆垂直时,硬币最容易保持与平板无相
11、对运动。 当然,在实验过程中,摩擦力总是存在的,但即使在摩擦力存在的前提下,我们仍能得到方案二是容易保持硬币稳定在平板上的方法,又因其操作简单,摆杆摆动过程中控制电机基本无需任何调整,所以在实现基本要求的第二三问时,我们采用方案二。 二、硬件系统的设计与实现 1.系统的总框图 电压输出 电源 电位器检测 模数转换 单片机检测控制 步进电机转动 平板转动 图2-1 系统总框图 如图2-1所示,摆杆摆动过程中,摆杆带动转轴的转动,而电位器的接入检测电路的电阻值会发生变化,进而检测电路得到的电压值会随之发生变化。而这个变
12、化的电压值是个模拟量,经过模数转换之后传送给单片机进行处理,进而用单片机输出信号控制步进电机的转动。 2.电位器检测电路 接接STC单片机模模数转换引脚 随着摆杆的左右摆动,相当于滑动变阻 器滑片上下滑动,因为在滑片与地之间产生 一个变化的电压值,将这个模拟量的电压值 接入STC单片机的模数转换引脚。 图2-2 电位器检测电路图 3.模数转换电路 STC单片机内置有模数转换功能引脚,因此将电位器检测所得的模拟电压值直接接入单片机模数转换引脚,即可实现模拟量到数字
13、量的转换,如图2-3所示。 图2-3 模数转换电路 4.电机驱动电路 图2-4是驱动电路原理图,驱动芯片旋转的是L298,这时一块双全桥步进电机专用驱动芯片,内含4信道逻辑驱动电路,可驱动46V,2A以下的步进电机,并可直接通过电源来调节输出电压。此芯片直接由单片机的IO端口来提供模拟时序信号。 图2-4 驱动电路原理图
14、 5.平板的控制实施步骤及编程思想 在平板控制方案的选择中,我们已经论证过,保持平板的与摆杆的垂直比保持平板与水平面的平行更容易保持硬币保持与平板的相对稳定的状态。于是在平板控制的过程中,我们首先将摆杆推至一定 角度,这时调节平板的角度使之与水平面平 行,以将硬币平稳的放在平板中心,这是初 始状态,这时平板与摆杆之间的夹角小于 90度(如图2-6所示)我们需要做的就是在 保持步进电机正常工作的状态下使步进电机 尽快由初始状态旋转至平板与摆杆垂直,在 之后的过程中保持平板与摆杆的垂直。 图2-6 平板与摆杆初始状态示意图 三、程序设计 1、数据的测试
15、在处理数据的过程中,我们首先 测量了不同的角度对应的电位器输出 的电压值,二者的关系表如表3-1所示。 表3-1 由电压和角度的关系图可以看出,电压和角度的测量值十分接近现行关系,因此我们可以近似看作一条直线。 图3-1 电压角度关系图 2、程序的设计与实现 (1)基本要求第一问 设计思想:单摆的4个周期的时间是可以测量出来的,而每个周期的时间是基本相等的,所以将单摆四个周期的时间的1/4用来控制步进电机旋转360度。 (2)基本要求第二三问 当摆杆被拉至
16、一定角度准备释放时,平板初始状态为了放置硬币要求平板与水平面平行,之后回复平板与摆杆的垂直。 程序如下: for(a=0;a<6;a++) { sum=sum+(uint)ad[a]; } sum=sum/6; biaozhun=sum;; if(!func1) { delay1ms(); delay1ms(); post_turn(220,2); while(1); } if(!func2) { ad[0]=ReadAD(0); delay1ms();delay1ms();delay1ms(); ad[1]=Re
17、adAD(0); delay1ms();delay1ms();delay1ms(); ad[2]=ReadAD(0); delay1ms();delay1ms();delay1ms(); ad[4]=ReadAD(0); delay1ms();delay1ms();delay1ms(); ad[5]=ReadAD(0); sum=0; for(n=0;n<6;n++) { ad[n]=ReadAD(0); delay1ms(); sum=sum+(uint)ad[n]; } sum=sum/6;
18、 junzhi=(uchar)sum;
while(((junzhi-5)>zhong)||(junzhi+5)
19、ad[5]-ad[4])>=1)&&((ad[5]-ad[0])>=10))||(((ad[0]-ad[1])>=1)&&((ad[1]-ad[2])>=1)&&((ad[2]-ad[3])>=1)&&((ad[3]-ad[4])>=1)&&((ad[4]-ad[5])>=1)&&((ad[0]-ad[5])>8))) //说明拉上一个倾斜角度的位置? { if(((ad[1]-ad[0])>=1)&&((ad[2]-ad[1])>1)&&((ad[3]-ad[2])>1)&&((ad[4]-ad[3])>1)&&((ad[5]-ad[4])>1)&&((ad[5]-ad[0])
20、>10))//判断为左拉 { sum=0; for(u=0;u<6;u++) { ad[u]=ReadAD(0); delay1ms();delay1ms();delay1ms();delay1ms(); delay1ms();delay1ms(); sum=sum+(uint)ad[u]; } sum=sum/6; tempp=(junzhi-zhong); redat=qiujiaodu(tempp); junzhi1=junzhi; for(v=0;v<6;v++) { ad[v]=ReadAD(0); d
21、elay1ms();delay1ms();delay1ms(); delay1ms();delay1ms();delay1ms(); } sum=0; for(q=0;q<6;q++) { sum=sum+(uint)ad[q]; } sum=sum/6; junzhi=(uchar)sum;fla=1; while((junzhi1-junzhi)<3)//拉到顶点 { if(fla) { post_turn((uint)((bushu(redat)/4)),1); natturn((bushu(redat)%4)); rebu
22、shu1=(bushu(redat));
fla=0;
}
for(y=0;y<6;y++)
{
ad[y]=ReadAD(0);
delay1ms();delay1ms();delay1ms();
delay1ms();delay1ms();delay1ms();
}
while(ad[5] 23、delay1ms();delay1ms();delay1ms();
}
rebushu=bushu(qiujiaodu((ad[5]-zhong)));
post_turn((uint)((rebushu1-rebushu)/4),0);
postturn((rebushu%4));
rebushu1=rebushu;
while(ad[5]==zhong)
{
//post_turn(bushu((qiujiaodu((ad[5]-zhong)))/4));
//postturn(bushu((qiujiaodu((ad[5]-zhong)))%4));
24、 for(f=0;f<6;f++)
{
tempp=ReadAD(0);
ad[f]=tempp;
delay1ms();delay1ms();delay1ms();
delay1ms();delay1ms();delay1ms();
}
while(1);
}
}
}
}
uchar qiujiaodu(uchar ii)
{
uchar div1,div0,dat;
div0=180/255;
div1=((div0%255)*10)/255;
dat= 25、div0*ii)+((div1*ii)/10));
return dat;
}
uchar bushu(uchar k)
{
uint canshu;
uint canshu1;
uint div;
uchar kk;
canshu=320/540;
canshu1=((320%540)*10)/540;
div=(((((canshu%540)*10)%540)*10)/540)+1;
kk=(uchar)((k*100)/((canshu*100)+(canshu1*100)+(div*100)));
return kk;
}






