嵌入式式系统作业解读.docx
《嵌入式式系统作业解读.docx》由会员分享,可在线阅读,更多相关《嵌入式式系统作业解读.docx(23页珍藏版)》请在冰豆网上搜索。
![嵌入式式系统作业解读.docx](https://file1.bdocx.com/fileroot1/2022-11/25/44eed673-d7d9-462d-82c6-f120e099c685/44eed673-d7d9-462d-82c6-f120e099c6851.gif)
嵌入式式系统作业解读
目录
摘要1
第一章绪论2
第二章相关芯片介绍3
2.1TMS320F283353
2.2加速度传感器ADXL3454
2.3角速度传感器L3G42005
第三章DSP的I2C通讯原理6
3.1ADXL345的I2C接口6
3.2L3G4200的I2C接口8
3.3TMS320F28335的I2C接口9
第四章工作电路设计12
4.1电路设计12
4.2工作总结与展望14
第五章致谢15
附录16
摘要
经过一个学期的学习,对嵌入式系统从感性认识上升到了理性的认识,同时在毕老师耐心细致的讲解下,对嵌入式系统的开发与编程有了更深的了解。
恰逢此时课题组的无人机姿态测量要开发一块控制板,结合课堂所学知识,立足于课题组的要求,设计并开发了这款F28335系列的DSP,经过调试与实验,结果令人满意。
本文涉及到的电路和程序主要用于一款小型无人直升机控制系统。
应用TI公司的新型32位DSPTMS320F28335采集三轴加速度计ADXL345及三轴角速度传感器L3G4200的姿态数据,并将该数据用于无人直升机的姿态控制中,主要控制策略如下所述:
首先,由三轴加速度计ADXL345及三轴角速度传感器L3G4200组成的六轴姿态测量模块测得直升机在X、Y、Z三轴上的加速度以及绕着这三轴的角速度,这些姿态信息通过一条I2C总线上传给DSPF28335进行采集,在DSP中,飞控算法将这些姿态信息与输入的预期姿态值进行比较,应用经典PID控制算法进行姿态控制和调整,调整的结果是使得DSP输出占空比可调的PWM信号,该信号控制无人直升机主旋翼电机转速,主旋翼电机的转速与PWM信号的占空比成正相关,同时,主旋翼电机的转速不同,产生的升力不同,直升机的姿态也会随着升力变化而相应变化(具体的变化规律可参考有关直升机数学建模文献),因此,通过控制DSP输出的PWM信号的占空比,就可以达到控制无人直升机姿态的目的。
本文重点设计六轴姿态模块数据的采集部分,包括六轴姿态模块的电路设计以及信号采集程序设计
关键字:
嵌入式;DSP;姿态传感器
第一章绪论
本文涉及到的电路和程序主要用于作者所设计的一款小型无人直升机控制系统,其作用是应用TI公司的新型32位DSPTMS320F28335采集三轴加速度计ADXL345及三轴角速度传感器L3G4200的姿态数据,并将该数据用于无人直升机的姿态控制中,主要控制策略如下所述:
首先,由三轴加速度计ADXL345及三轴角速度传感器L3G4200组成的六轴姿态测量模块测得直升机在X、Y、Z三轴上的加速度以及绕着这三轴的角速度,这些姿态信息通过一条I2C总线上传给DSPF28335进行采集,在DSP中,飞控算法将这些姿态信息与输入的预期姿态值进行比较,应用经典PID控制算法进行姿态控制和调整,调整的结果是使得DSP输出占空比可调的PWM斩波信号,该信号控制无人直升机主旋翼电机转速,主旋翼电机的转速与PWM斩波信号的占空比成正相关,同时,主旋翼电机的转速不同,产生的升力不同,直升机的姿态也会随着升力变化而相应变化(具体的变化规律可参考有关直升机数学建模文献),因此,通过控制DSP输出的斩波信号的占空比,就可以达到控制无人直升机姿态的目的。
本文重点设计六轴姿态模块数据的采集部分,包括六轴姿态模块的电路设计以及信号采集程序设计。
第二章相关芯片介绍
设计中主要用到的芯片包括三种:
TI公司的TMS320F28335系列DSP,AD公司的三轴加速度计ADXL345,ST公司的三轴角速度传感器L3G4200。
下面对这三种主要芯片做简要介绍。
2.1TMS320F28335
TMS320F28335是TI公司生产的一款最新DSP,该DSP为32-位浮点型,主频率为150MHz,作者使用的是由南京研旭公司生产的F28335的核心板,该核心板主要配置包括:
片上存储器:
FLASH:
256K×16-位
SRAM:
34K×16-位
BootROM:
8K×16-位
OTPROM:
1K×16-位
其中FLASH、OTPROM和16K×16-位SRAM受密码保护,保护用户程序。
片上外设:
ePWM:
12路
HRPWM:
6路
QEP:
2通道
ADC:
2×8通道、12-位、80ns转换时间、0~3V量程
SCI异步串口:
3通道
McBSP同步串口:
2通道
SPI同步串口:
1通道
eCAN总线:
2通道
I2C总线:
1通道
DMA:
6通道
看门狗
外扩SRAM,最大容量为512Kx16位,基本配置为64Kx16位
外扩RTC实时时钟+512×8-位EEPROM
外扩4通道、12-位分辩率、10μs建立时间、±10V量程的DAC输出
…外扩符合USB2.0标准的高速客户端接口
2路SCI进行收发驱动,接口标准一路为RS232,另一路RS232/RS422/RS485可配置
1路eCAN进行收发驱动,符合CAN2.0协议
标准的JTAG接口,方便调试,标准化的扩展总线。
本设计中主要用到的是该开发板中的I2C总线,实现DSP与两个传感器之间的通讯。
2.2加速度传感器ADXL345
ADXL345是一款小而薄的超低功耗3轴加速度计,分辨率高(13位),测量范围达±16g。
数字输出数据为16位二进制补码格式,可通过SPI(3线或4线)或I2C数字接口访问。
其主要电气特性包括:
超低功耗:
VS=2.5V时(典型值),测量模式下低至23A,待机模式下为0.1μA
功耗随带宽自动按比例变化
用户可选的分辨率
10位固定分辨率
全分辨率,分辨率随g范围提高而提高,±16g时高达13位
(在所有g范围内保持4mg/LSB的比例系数)
电源电压范围:
2.0V至3.6V
I/O电压范围:
1.7V至VS
SPI(3线和4线)和I2C数字接口
灵活的中断模式,可映射到任一中断引脚
通过串行命令可选测量范围
通过串行命令可选带宽
宽温度范围(-40°C至+85℃)
抗冲击能力:
10,000g
本设计中主要通过I2C总线将ADXL345与DSPF28335连接。
2.3角速度传感器L3G4200
L3G4200是由ST公司生产的一种三轴角速度传感器,它包括一个感应单元和一个IC接口单元,该接口单元提供3线SPI及I2C通讯接口。
其主要电气特性包括:
三种可选满量程(250/500/2000°/s),
I2C/SPI数据接口。
16位角速度数据输出。
8位温度值输出。
可选的内部集成高通/低通滤波器。
内嵌的温度传感器。
支持2.4v至3.6v供电电压。
工作温度-45至80度。
第三章DSP的I2C通讯原理
3.1ADXL345的I2C接口
ADXL345的的主要功能模块包括一个三轴硅晶体传感器,一个AD转换模块,一组数字滤波器,一个32位的FIFO缓存模块以及串口通讯模块和电源管理模块。
以下是ADXL345的主要功能模块框图。
图一ADXL345主要功能模块
如下图所示,CS引脚拉高至VDDI/O,ADXL345处于I2C模式,需要简单2线式连接。
ADXL345符合《UM10204I2C总线规范和用户手册》03版(2007年6月19日,NXPSemiconductors提供)。
如果满足了表11和表12列出的总线参数,便能支持标准(100kHz)和快速(400kHz)数据传输模式。
如图40所示,支持单个或多个字节的读取/写入。
ALTADDRESS引脚处于高电平,器件的7位I2C地址是0x1D,随后为R/W位。
这转化为0x3A写入,0x3B读取。
通过ALTADDRESS引脚(引脚12)接地,可以选择备用I2C地址0x53(随后为R/W位)。
这转化为0xA6写入,0xA7读取。
对于任何不使用的引脚,没有内部上拉或下拉电阻,因此,CS引脚或ALTADDRESS引脚悬空或不连接时,任何已知状态或默认状态不存在。
使用I2C时,CS引脚必须连接至VDDI/O,ALTADDRESS引脚必须连接至任一VDDI/O或接地。
由于通信速度限制,使用400kHz的I2C最大输出数据速率为800Hz,与I2C通信速度按比例呈线性变化。
例如,使用100kHzI2C时,ODR最大限值为200Hz。
以高于推荐的最大值和最小值范围的输出数据速率运行,可能会对加速度数据产生不良影响,包括采样丢失或额外噪声。
如果有其他器件连接到同一I2C总线,这些器件的额定工作电压电平不能高于VDDI/O0.3V以上。
I2C正确操作需要外接上拉电阻RP。
图二ADXL345I2C总线搭建
图二是ADXL345进行I2C通讯的时序图。
图三ADXL345I2C总线时序
图四I2C总线要求
上面的图三是ADXL345的I2C通讯各时序要求,与后面将要提到的DSPI2C时序以及L3G4200的I2C时序相比较可以看出,这三者的I2C均属于标准接口,因此可以方便的在三者之间搭起I2C总线。
3.2L3G4200的I2C接口
L3G4200的内部主要模块包括一个AD转换模块,一个组滤波器,一个32位的FIFO缓存以及一个SPI、I2C复用的接口,以下是L3G4200de各功能模块框图。
图五L3G4200功能模块框图
该I2C器件只可作为从器件,其地址根据SDO引脚的接地与否变化,SDO接高电平时,该器件的7位I2C地址为1101001,当SDO接地时,该器件的7位I2C地址为1101000。
L3G4200内嵌的I2C满足以下通讯协议:
I2C总线上的主器件提供时钟脉冲序列,当L3G4200接收到主器件发送来START信号后,首相将自身地址与主器件发送的地址作比对,若相符,则L3G4200发送一个ACK信号以回应主器件,随后,L3G4200按照主器件发送的所要访问的访寄存器地址将该寄存器内数据发送到SDA引脚,供主器件查读。
主器件没读完一个寄存器地址,L3G4200自动将地址加1,做下一地址的数据读取。
SDA线上数据的高低电平跳变只能在时钟信号下降沿进行,在时钟信号为高时,SDA线上电平保持不变。
图四是L3G4200的I2C总线时序要求。
图六L3G4200时序要求
3.3TMS320F28335的I2C接口
TMS320F28335支持多主机的I2C总线通讯,该DSP既可以作为I2C主机使用,也可以作为从机使用。
在作为主机使用时,其I2C总线时钟频率有两个预分频的寄存器决定。
一个是IPSC,另一个是ICCL和ICCH。
TMS320F28335的I2C模块主要包括控制寄存器,数据寄存器,一个32位的FIFO缓存,主频预分频模块这几个部分,以下是其各功能模块的框图。
IPSC是对I2C模块的输入时钟(亦即DSP的主频)进行第一次分频,该分频的结果既是I2C模块的频率,一般情况下,同时考虑通讯速率以及通讯准确率,要求I2C模块频率应该介于7至15MHz之间。
I2C模块时钟频率与IPSC以及DSP主频率之间的关系可以由下式说明:
ModuleClockFrequency=I2CInputClockFrequency/(IPSC+1)
在本设计中,取IPSC为9,这样,I2C模块的时钟频率为10MHz(TMS320F28335的主频率为150MHz)。
ICCL与ICCH是对I2C模块式中再进行一次分频,这次分频确定的是I2C通讯时输出的时钟上升沿和下降沿的持续时间。
时钟高电平的持续时间由ICCH决定,低电平持续时间由ICCL决定。
高、低电平持续时间与ICCH、ICCL之间的关系由下式决定:
Ht=ModulePeriod*(ICCH+d);
Lt=ModulePeriod*(ICCL+d);
其中,d的取值由IPSC确定,当IPSC>1时,d=5。
同时,F28335的I2C不仅支持1—8位的数据格式,还支持自由数据格式,这样,就方便了DSP与各类不同标准数据结构器件之间的通讯。
下图是F28335与其他I2C器件搭建I2C总线的图示。
图七DSP28335与其他I2C之间搭建总线
第四章工作电路设计
4.1电路设计
由于ADXL345、L3G4200要与DSP进行I/O口电压匹配,因此,需要设计专门的外围电路,在本设计中,作者将ADXL345和L3G4200集成在一块板子上,外围电路一起设计,以下是这两者集成的电路各部分原理图。
图八电源部分原理图
图九ADXL345外围电路原理图
图十L3G4200外围电路
图十一引出管脚设置
图十二六轴模块全局电路原理图
图十中,引出管脚J1的1号引脚是整个模块的供电脚,上接3.3v电源,2号引脚是电源地,3号引脚为I2C通讯的时钟管脚,接F28335的I2C模块的SCL,4号引脚为I2C的数据引脚,接F28335的对应引脚。
5号引脚悬空。
J2管脚的1号引脚接电源,2号引脚为SPI通讯的数据输出脚,3号引脚为SPI通讯的数据输入脚,4号管脚是SPI通讯时的片选信号引脚,5号引脚为外部中断引脚,在设计中未用到。
实际应用中,将六轴模块的I2C相应引脚与DSP28335的相应I2C引脚连接,以DSP28335作为主机,以六轴模块作为从机,由DSP28335发送通讯同步时钟,对六轴模块作读写操作。
需要特别说明的是,ADXL345和L3G4200这两个传感器在I2C总线中的地址是可以由地址线的接地与否改变的。
具体为:
ADX345的SDO/ALTADDRESS引脚接地,I2C地址0x53(随后为R/W位)。
这转化为0xA6写入,0xA7读取。
读为高,写为低。
L3G4200的SDO接高电平,IIC地址为address1101001b(0x69,随后为R/W位)。
这转化为0xD2写入,0xD3读取。
读为高,写为低。
在设计中,为了方便编程,同时简化电路,作者将ADXL345和L3G4200的地址引脚都设置为接地,因此,程序中对ADXL345的访问地址为0x53,对L3G4200的访问为0x69。
附录里给出了DSP与六轴模块之间通讯的主要程序端,这里对主要程序端做以下简要说明。
第一步,先对DSP进行系统初始化,然后设定第33和34号引脚为I2C的I/O口(具体地说,33引脚对应SCLK同步时钟线,34引脚对应SDA数据线)。
第二步,对F28335的I2C模块进行设置,主要包括模块时钟频率设置,中断设置,主(从)器件设置,数据格式设置,FIFO设置等。
第三步,DSP通过I2C总线向六轴模块发送指令,既向六轴模块相应寄存器写入控制字。
第四步,DSP作为主器件,六轴模块的两个传感器ADXL345和L3G4200作为从器件,由DSP启动I2C通讯,读取六轴模块的数据。
4.2工作总结与展望
经过一系列调试与实验,目前本设计中提到的I2C总线已经成功应用到无人直升机的姿态数据采集上,采集效果良好,电路工作稳定,程序运行可靠,下一步我们将考虑把DSP芯片和ADXL345以及L3G4200集成到一块板子上,开发出无人直升机专用的,集姿态测量、姿态控制为一体的控制卡。
为研究者们提供专门封装好的惯性测量、数据处理与控制于一体的控制电路板,实现高度集成。
第五章致谢
毕宏彦老师是我在嵌入式电路设计与开发方面的启蒙老师,我如今在嵌入式开发领域所获得的没一点滴知识源自于毕老师的辛勤汗水。
所以在这里我要感谢毕宏彦老师耐心细致的讲授、孜孜不倦的教诲。
毕老师所传授给我们的不仅仅是关于嵌入式电路设计的相关知识,他老人家更传授给我们一种严谨认真的求学态度以及踏实负责的为人处事之原则。
这将是我们受用一生的宝贵财富。
在这里祝福他老人家:
桃李芬芳做栋梁,享誉业界体健康!
附录
以下是由DSP采集六轴模块的数据,主要程序语句如下
#include"DSP2833x_Device.h"//DSP2833xHeaderfileIncludeFile
#include"DSP2833x_Examples.h"//DSP2833xExamplesIncludeFile
voidI2CA_Init(void);
Uint16I2CA_WriteData(structI2CMSG*msg);
Uint16I2CA_ReadData(structI2CMSG*msg);
voidWriteData(structI2CMSG*msg,Uint16*MsgBuffer,Uint16MemoryAdd,Uint16NumOfBytes);
interruptvoidi2c_int1a_isr(void);
voidpass(void);
voidfail(void);
#defineI2C_SLAVE_ADDR0x53
#defineI2C_NUMBYTES1
#defineI2C_RNUMBYTES6
#defineI2C_L3G345_X_HIGH_ADDR0x33
#defineI2C_L3G345_X_LOW_ADDR0x32
intX;
intY;
intZ;
floatx;
floaty;
floatz;
structI2CMSGI2cMsgOut1={I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_ADDR,
I2C_NUMBYTES,
I2C_L3G345_X_HIGH_ADDR,
I2C_L3G345_X_LOW_ADDR};
structI2CMSGI2cMsgIn1={I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_ADDR,
I2C_RNUMBYTES,
I2C_L3G345_X_HIGH_ADDR,
I2C_L3G345_X_LOW_ADDR};
structI2CMSG*CurrentMsgPtr;//Usedininterrupts
Uint16PassCount;
Uint16FailCount;
voidmain(void)
{
Uint16i;
CurrentMsgPtr=&I2cMsgOut1;
InitSysCtrl();
InitI2CGpio();
InitPieCtrl();
IER=0x0000;
IFR=0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.I2CINT1A=&i2c_int1a_isr;
EDIS;
I2CA_Init();
PieCtrlRegs.PIEIER8.bit.INTx1=1;
IER|=M_INT8;
EINT;//writedata
if(I2cMsgOut1.MsgStatus==I2C_MSGSTAT_SEND_WITHSTOP)
{
i=0x0B;
WriteData(&I2cMsgOut1,&i,0x31,1);
DELAY_US(1000);
i=0x08;
WriteData(&I2cMsgOut1,&i,0x2C,1);
DELAY_US(1000);
i=0x08;
WriteData(&I2cMsgOut1,&i,0x2D,1);
DELAY_US(1000);
i=0x80;
WriteData(&I2cMsgOut1,&i,0x2E,1);
DELAY_US(1000);
i=0x00;
WriteData(&I2cMsgOut1,&i,0x1E,1);
DELAY_US(1000);
i=0x00;
WriteData(&I2cMsgOut1,&i,0x1F,1);
DELAY_US(1000);
i=0x05;
WriteData(&I2cMsgOut1,&i,0x20,1);
DELAY_US(1000);//readdata
for(;;)
{
//Checkoutgoingmessagestatus.Bypassreadsectionifstatusis
//notinactive.
if(I2cMsgOut1.MsgStatus==I2C_MSGSTAT_INACTIVE)
{
if(I2cMsgIn1.MsgStatus==I2C_MSGSTAT_SEND_NOSTOP)
{
while(I2CA_ReadData(&I2cMsgIn1)!
=I2C_SUCCESS)
{
t++;
if(t>=15)
{
brake;
}
}
//Updatecurrentmessagepointerandmessagestatus
CurrentMsgPtr=&I2cMsgIn1;
I2cMsgIn1.MsgStatus=I2C_MSGSTAT_SEND_NOSTOP_BUSY;
}
elseif(I2cMsgIn1.MsgStatus==I2C_MSGSTAT_RESTART)
{
DELAY_US(1000000);
X=(I2cMsgIn1.MsgBuffer[5]<<8)+I2cMsgIn1.MsgBuffer[4];
Y=(I2cMsgIn1.MsgBuffer[3]<<8)+I2cMsgIn1.MsgBuffer[2];
Z=(I2cMsgIn1.MsgBuffer[1]<<8)+I2cMsgIn1.MsgBuffer[0];
if(X<0)
{
X=-X;
}
else
{
X=X;
}
x=(float)X*3.9;//x轴加速度,单位mg
if(Y<0)
{
Y=-Y;
}
else
{
Y=Y;
}
y=(float)Y*3.9;//y轴加速度,单位mg
if(Z<0)
{
Z=-Z;
}
else
{
Z=Z;
}
z=(float)Z*3.9;//z轴加速度,单位mg
//Readdataportion
while(I2CA_ReadData(&I2cMsgIn1)!
=I2C_SUCCESS)
{
f++;
if(f>=7)
brake;
}
//Updatecurrentmessagepointerandmessagestatus
CurrentMsgPtr=&I2cMsgIn1;
I2cMsgIn1.MsgStatus=I2C_MSGSTAT_READ_BUSY;
//Updatenewdata
X=(I2cMsgIn1.MsgBuffer[5]<<8)+I2cMsgIn1.MsgBuffer