B甲03846小组全国电赛 自由摆论文.docx
《B甲03846小组全国电赛 自由摆论文.docx》由会员分享,可在线阅读,更多相关《B甲03846小组全国电赛 自由摆论文.docx(22页珍藏版)》请在冰豆网上搜索。
B甲03846小组全国电赛自由摆论文
编号:
B甲03846
基于自由摆的平板
控制系统(B题)
参赛队员:
王东祥周万军段敬博
专业:
光信息科学与技术
学校:
哈尔滨工业大学(威海)
指导老师:
基于自由摆的平板控制系统
关键词:
自由摆平板控制加速度传感器
IIC总线AT89S52步进电机L298驱动芯片MMA7445
目录
1方案论证与比较3
1.0电源模块3
1.1电机模块3
1.2检测模块3
1.3通讯模块4
1.4系统结构4
2理论分析和计算6
2.1平板测量方法6
2.2从机检测电路设计11
2.3程序设计12
3.电路和程序设计14
3.1电路图14
3.2程序14
4测试方案和结果22
5结论和总结23
参考资料23
1方案论证与比较
1.0电源模块
方案一:
使用蓄电池,
方案二:
使用220v转5V电源适配器.
我们选择的是22V转5V电源适配器.
1.1电机模块
方案一:
使用步进电机
方案二:
使用舵机.
比较以上两种方案,考虑到舵机不能转360度,所以我们选择步进电机,同时我们采用L298进行电机驱动,驱动加些外围电路.
1.2检测模块
方案一:
采用角速度传感器,能够很好的给出角度的数字信号.
方案二:
采用加速度传感器MMA7445,5V直流电压供电,内部能给出各个方向的加速度,加速度的形式是数模数据,但给出的是补码形式.
比较上述两种方案,显然角速度传感器的输出能很直接的给出角速度,能使得程序更加简单。
由于我们买到角速度传感器,而有加速度传感器,再加上我们对加速度传感器之前就有了解,在达到利用好自己身边的元器件的同时,也能达到同样的效果。
1.3通讯模块
方案一:
单片机采取SPI接口方式读取数值,检测其运动和方向.
方案二:
单片机采取IIC接口方式读取数值,IIC是一种二线制串行总线接口,工作在主/从模式。
二线通信信号分别为开漏SCL和SDA串行时钟和串行数据。
主器件为时钟源。
数据传输是双向的,其方向取决于读/写位的状态。
每个从器件拥有一个唯一的7或10位地址。
主器件通过一个起始位发起一次传输,通过一个停止位终止一次传输。
起始位之后为唯一的从器件地址,再后为读/写位。
I2C允许多个主器件工作在同一总线上。
多个主器件可以轻松同步其时钟,因此所有主器件均采用同一时钟进行传输。
多个主器件可以通过数据仲裁检测哪一个主器件正在使用总线,从而避免数据破坏。
由于I2C总线只有两条导线,因此新从器件只需接入总线即可,而无需附加逻辑。
比较上述两种方案,我们选择是IIC总线接口的方式读取数据.
1.4系统结构
在单摆架子的上面,利用AT89S52单片机作为控制器,将加速度传感器的所获得数据通过IIC总线的传输方式,并将此数据传输到L298驱动器上,L298将信息转化为角度,进而对电机的运动的运动方式进行控制.
最终方案为:
1.电源模块:
采用220V转5V电源适配器。
2.驱动模块:
采用28byj-48减速型步进电机和L298模块驱动电机..
3.
检测模块:
采用MMA7455加速度传感器模块
4.通讯模块:
采用的是IIC总线的读取方式。
2理论分析和计算
2.1平板测量方法
第一个要求:
我们对摆杆拉到60o时的周期进行测量,再由摆杆的周期再进行理论计算电机需要怎么转.
将加速度传感器安装在摆杆上,加速度传感器给出的X,Y,Z的加速度的数据的补码形式,通过程序的换算,我们将且用AX,AY,AZ作为通过程序处理后各个方向的加速度,再进行计算.
首先我们将摆杆拉到600,手动将平板调整到和摆杆垂直,此时通过叫传感器给出的加速度,算出角度θ
sinθ=Ax/g
(其中g为重力加速度.)
g=9.78049(1+0.0052884(Sinα)^2-0.0000059*(Sin2α)^2)-0.00000286h
α为纬度.
电机的偏转角
△θ=θ1-θ2
得出的角度就是电机所需要转的角度.
同时通过AY,由于AY在最下方的时候达到一个极值,所以只需要测试AY的增减情况来判断电机是否需要反转.
这样就达到了测量平板的位置以及它所需要转的角度.最终实现平板和水平面平行.
3.电路和程序设计
3.1电路图
3.2程序
步进电机绕圈程序
/**********************************************************
名称:
步进电机
编写:
shifang
日期:
2009.5
修改:
2011/9/1
内容:
4相步进电机常规驱动单方向运转
**********************************************************/
#include
sbitA1=P1^0;//定义步进电机连接端口
sbitB1=P1^1;
sbitC1=P1^2;
sbitD1=P1^3;
#defineCoil_A1{A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电
#defineCoil_B1{A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电
#defineCoil_C1{A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电
#defineCoil_D1{A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电
#defineCoil_AB1{A1=1;B1=1;C1=0;D1=0;}//AB相通电,其他相断电
#defineCoil_BC1{A1=0;B1=1;C1=1;D1=0;}//BC相通电,其他相断电
#defineCoil_CD1{A1=0;B1=0;C1=1;D1=1;}//CD相通电,其他相断电
#defineCoil_DA1{A1=1;B1=0;C1=0;D1=1;}//D相通电,其他相断电
#defineCoil_OFF{A1=0;B1=0;C1=0;D1=0;}//全部断电
unsignedintSpeed;
/*------------------------------------------------
uS延时函数,含有输入参数unsignedintt,无返回值
unsignedint是定义无符号字符变量,其值的范围是
0~65535这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5uS
------------------------------------------------*/
voidDelayUs2x(intt)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
voidDelayMs(intt)
{
while(t--)
{
//大致延时2mS
DelayUs2x(190);
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
voidmain()
{
unsignedinti=512;//旋转一周时间
Speed=1;
while
(1)//正向
{
Coil_A1//遇到Coil_A1用{A1=1;B1=0;C1=0;D1=0;}代替
DelayMs(Speed);//改变这个参数可以调整电机转速,
//数字越小力矩越小
Coil_AB1
DelayMs(Speed);
Coil_B1
DelayMs(Speed);
Coil_BC1
DelayMs(Speed);
Coil_C1
DelayMs(Speed);
Coil_CD1
DelayMs(Speed);
Coil_D1
DelayMs(Speed);
Coil_DA1
DelayMs(Speed);
}
自由摆保持平衡程序
/*******************************************************************/
名称:
自由摆保持平衡程序
编写:
duan
日期:
2011/9/2
内容:
三轴加速度传感器传感,使用步进电机保持平板平衡
/********************************************************************/
#include
#include//要用到_nop_();函数
#include
sbitA1=P1^0;//定义步进电机连接端口
sbitB1=P1^1;
sbitC1=P1^2;
sbitD1=P1^3;
#defineCoil_A1{A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电
#defineCoil_B1{A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电
#defineCoil_C1{A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电
#defineCoil_D1{A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电
#defineCoil_AB1{A1=1;B1=1;C1=0;D1=0;}//AB相通电,其他相断电
#defineCoil_BC1{A1=0;B1=1;C1=1;D1=0;}//BC相通电,其他相断电
#defineCoil_CD1{A1=0;B1=0;C1=1;D1=1;}//CD相通电,其他相断电
#defineCoil_DA1{A1=1;B1=0;C1=0;D1=1;}//D相通电,其他相断电
#defineCoil_OFF{A1=0;B1=0;C1=0;D1=0;}//全部断电
#defineucharunsignedchar
#defineuintunsignedint
#defineIIC_READ0x1D//定义读指令
#defineIIC_WRITE0x1D//定义写指令
sbitsda=P1^6;//I2C数据传送位
sbitscl=P1^7;
ucharack_sign;
unsignedintSpeed;
/******************************************************************/
/*各延时程序*/
/******************************************************************/
voidiic_delay()//5us延时
{
_nop_();
_nop_();
_nop_();
_nop_();
}
voiddelay_50us(uintt)
{
ucharj;
for(;t>0;t--)
for(j=19;j>0;j--);
}
voiddelay_50ms(uchart)
{
uintj;
for(;t>0;t--)
for(j=6245;j>0;j--);
}
/*------------------------------------------------
uS延时函数,含有输入参数unsignedintt,无返回值
unsignedint是定义无符号字符变量,其值的范围是
0~65535这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5uS
------------------------------------------------*/
voidDelayUs2x(intt)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
voidDelayMs(intt)
{
while(t--)
{
//大致延时2mS
DelayUs2x(190);
}
}
/********************************************************************/
/*I2C通信部分*/
/*******************************************************************/
voidiic_start()//函数功能:
I2C通信开始
{
sda=1;
iic_delay();
scl=1;
iic_delay();
sda=0;
iic_delay();
}
voidiic_stop()//函数功能:
I2C通信停止
{
sda=0;
iic_delay();
scl=1;
iic_delay();
sda=1;
iic_delay();
}
voidiic_ack()//函数功能:
I2C通信查应答位
{
sda=1;
scl=1;
iic_delay();
ack_sign=sda;
scl=0;
}
voidiic_write_byte(ucharwdata)//函数功能:
向I2C从机写入一个字节
{
uchari,temp,temp1;
temp1=wdata;
for(i=0;i<8;i++)
{
scl=0;
iic_delay();
temp=temp1;
temp=temp&0x80;
if(temp==0x80)
sda=1;
else
sda=0;
iic_delay();
scl=1;
iic_delay();
scl=0;
iic_delay();
temp1=temp1<<1;
}
}
chariic_read_byte(void)//函数功能:
从I2C从机中读出一个字节
{
ucharx;
chardata_data;
for(x=0;x<8;x++)
{
data_data=data_data<<1;
sda=1;
iic_delay();
scl=0;
iic_delay();
scl=1;
iic_delay();
if(sda==1)
data_data|=0x01;
//else
//data_data&=0xfe;
}
returndata_data;
}
voidiic_write(ucharbyte_add,ucharwdata)//函数功能:
按地址写入一字节数据
{
uchart;
t=(IIC_WRITE<<1);
iic_start();
iic_write_byte(t);
iic_ack();
iic_write_byte(byte_add);
iic_ack();
iic_write_byte(wdata);
iic_ack();
iic_stop();
}
chariic_read(ucharbyte_add)//函数功能:
按地址读出一字节数据
{
uchart;
charx;
t=(IIC_WRITE<<1);
iic_start();
iic_write_byte(t);
iic_ack();
iic_write_byte(byte_add);
iic_ack();
t=((IIC_READ<<1)|0x01);
iic_start();
iic_write_byte(t);
iic_ack();
x=iic_read_byte();
iic_ack();
iic_stop();
returnx;
}
/********************************************************************
辅助计算函数函数
********************************************************************/
doubleasinjs(charx)
{
doubleasjd,asjg;
doubles_result;
asjd=(double)x/9.7;
asjg=asin(asjd);
s_result=asjg/(3.1415926/180);
returns_result;
}
doublerun_time(doublea,doubleb)
{
doubletemp;
temp=(a-b)/5.625;
returntemp;
}
/*******************************************************************
主函数模块
********************************************************************/
voidmain()
{
doublejiaodu1;
doublejiaodu2;
charx;
doubletemp;
doublen;
doublei;
temp=iic_read(0x06);
while
(1)
{
if(temp==0)
{
}
else
{
x=iic_read(0x06);
jiaodu1=asinjs(x);
delay_50ms(50);
x=iic_read(0x06);
jiaodu2=asinjs(x);
n=run_time(jiaodu1,jiaodu2);
if(temp>0)
{
for(i=0;i{
Coil_A1//遇到Coil_A用{A1=1;B1=0;C1=0;D1=0;}代替
DelayMs(Speed);//改变这个参数可以调整电机转速,
//数字越小力矩越小
Coil_AB1
DelayMs(Speed);
Coil_B1
DelayMs(Speed);
Coil_BC1
DelayMs(Speed);
Coil_C1
DelayMs(Speed);
Coil_CD1
DelayMs(Speed);
Coil_D1
DelayMs(Speed);
Coil_DA1
DelayMs(Speed);
}
}
else
{
for(i=0;i{
Coil_DA1
DelayMs(Speed);
Coil_D1//遇到Coil_A1用{A1=1;B1=0;C1=0;D1=0;}代替
DelayMs(Speed);//改变这个参数可以调整电机转速,
//数字越小,转速越大,力矩越小
Coil_CD1
DelayMs(Speed);
Coil_C1
DelayMs(Speed);
Coil_BC1
DelayMs(Speed);
Coil_B1
DelayMs(Speed);
Coil_AB1
DelayMs(Speed);
Coil_A1
DelayMs(Speed);
}
}
}
temp=iic_read(0x06);
}
}
4测试方案和结果
次数
1
2
3
4
5
摆杆的周期T/s
2’23’’
1’56’’
2’30’’
2’43’’
2’32’’
次数
6
7
8
9
10
摆杆的周期T/s
3’12’’
2’12’’
2’01’’
2’17’’
2’20’’
去掉最大值和最小值求平均值:
T均=2’25’’
通过计算,对程序进行修改,修改延时SPEED,对电机的转动的速度进行控制.
测试结果分析
项目
功能
实现情况
备注
基础部分
电机和单摆一同转动
良好
只需要两个的周期相差不大即可
放置一个硬币
的情况
不好
仍然需要调试
放置八个硬币
未完成
发挥部分
未完成
未完成
未完成
未完成
5结论和总结
在本次设计的过程中,我们遇到了各种困难和许多没有预想到情况。
由于我们自身水平有限和时间紧张等因素,本作品还有许多未完成的部分,做好的部分还需要很大的改进.经过此次电子设计竞赛,我们在电路的设计、调试方面得到了很好锻炼,能力也有了很大的提高,同时也深刻的体会到:
实践是理论运用的最好检验,懂得了共同协作和团队精神的重要性,提高了我们分析问题、解决问题的能力。
参考