三轴加速度传感器MMA8452IIC测试程序.docx
《三轴加速度传感器MMA8452IIC测试程序.docx》由会员分享,可在线阅读,更多相关《三轴加速度传感器MMA8452IIC测试程序.docx(14页珍藏版)》请在冰豆网上搜索。
三轴加速度传感器MMA8452IIC测试程序
〃***************************************
//GY-45MMA8452IIC测试程序
//使用单片机PIC16F877A
//晶振:
4M
//显示:
Nokia5110
//编译坏境MPLAB
//时间:
2012.9.11吴迪
QQ:
362911737
〃****************************************
#include
#mcludeHSPLCHAR.hM
#include_CONFIG(Ox3b32);
#defineucharunsignedchar#defineumtunsignedint
^defineSDA.DIRTRISEI〃定义E口方向寄存器
^defineSDA_HIGH()SDA.DIR=1〃设置数据II为输入
^defineSDA_LOW()SDA.DIR=0〃设置数据口为输出
#define_nop_NOP()
^defineSlaveAddress0x38〃定义器件在UC总线中的从地址,根据SAO地址引脚不同修改
〃接收数据缓存区
〃显示变量
〃变量
//初始化MMA8452
tvpedefunsignedchaiBYTE;tvpedefunsignedshoitWORD:
uchaiBUF_drift[8];
BYTEBUF[8];
uchaige,shi,bai,qian,wan;
iiitdis_data;
mtxyz;
uchaiCY;
voiddelay(unsignedintk);
voidIniCMMA8452(void);voidconversion(umttemp_data);
//单个写入数据
〃单个读取内部寄
〃连续的读取
voidSmgle_Write_MMA8452(ucharREG_Addiess,ucharREG_data);uchaiSmgle_Read_MMA8452(uchaiREG.Address);
存器数据
voidMultiple_Read_MNIA8452(void);
内部寄存器数据
voidDelay5us();
voidDelay5ms();
voidMMA8452_Stait();
voidMMA8452_Stop();
voidMMA8452_SendACK(uchaiack);bitMMA8452_RecvACK();
voidMMA8452_SendByte(BYTEdat);
BYTEMMA8452-RecvByte();
voidMMA8452_ReadPage();
voidMMA8452_WntePage();
〃*********************************************************voidconversion(umttemp_data)
wan=temp_data/'l0000+16;temp_data=temp_data%10000;qian=temp_data/zl000+16;temp_data=temp_data%1000;baWemp^data/'l00+0x10;temp_data=temp_data%100;shi=temp_data/10-H)x10;
temp_data=temp_data%10;ge=temp_data+Ox10;
}
〃取余运算
严******************************,
voiddelay(unsignedintk){
unsignedinti,j;for(i=O;i{for(j=0j<110;j++);}}严*************************************延时5微秒(STC90C52RC@12M)不同的工作坏境,需要调整此函数,注意时钟过快时需要修改当改用1T的MCU时,请调整此延时函数voidDelay5us()NOP();NOP();NOP0;NOP();NOP0;〃NOP();NOP();NOP();//NOPQ;NOP();NOP();NOP0;}严*************************************延时5亳秒(STC90C52RC@12M)不同的工作坏境,需要调整此函数当改用1T的MCU时,请调整此延时函数**************************************/voidDelay5ms(){WORDn=560;wliile(n-);}严*************************************起始信号**************************************/voidMMA8452_Stait(){SDA_LOW();〃拉高数据线〃拉高时钟线〃延时〃产生下降沿〃延时//拉低时钟线SDA=1;SCL=1;Delav5us();SDA=0;Delav5us();SCL=0;}严*************************************停止信号**************************************/voidMMA8452_Stop(){SDA_LOW();〃拉低数据线〃拉高时钟线〃延时〃产生上升沿〃延时SDA=0;SCL=1;Delav5us();SDA=1;Delav5us();严*************************************发送应答信号入II参数:ack(O:ACK1:NAK)**************************************/voidMMA8452_SendACK(uchaiack){SDA_LOW();SDA=ack;SCL=1;Delav5us();SCL=0;Delav5us();}〃写应答信号〃拉高时钟线〃延时//拉低时钟线〃延时严*************************************接收应答信号**************************************/bitMMA8452_RmvACK(){SDA_HIGH();SCL=1;Delav5us();if(SDA=l)CY=1;else〃拉高时钟线〃延时〃读应答信号SCL=0;Delav5us();SDA_LOW();returnCY;}〃拉低时钟线〃延时严*************************************向IIC总线发送一个字节数据**************************************/voidMMA8452_SendByte(BYTEdat){BYTE1;SDA_LOW();for(1=0;i<8;i++)//8位计数器{if(dat&0x80)CY=1; elseCY=O;SDA=CY;〃送数据门SCL=1;〃拉高时钟线Delav5usQ;〃延时SCL=0;〃拉低时钟线Delav5usQ;〃延时dat«=1;〃移出数据的最高位}MMA8452_RecvACK();严*************************************从IIC总线接收一个字节数据**************************************/BYTEMMA8452_RecvByte(){BYTEi;BYTEdat=0;SDA_LOW0;//使能内部上拉,准备读取数据,//8位计数器〃拉高时钟线〃延时〃读数据〃拉低时钟线〃延时SDA=1;SDA_HIGH();for(1=0;i<8;i++){dat«=1;SCL=1;Delav5usQ;if(SDA=l)dat|=1;elsedat|=0;SCL=0;Delav5usQ;}SDA_LOW0;returndat;}〃******单字节写入*******************************************voidSmgle_Wnte_MMA8452(uchai-REG_Address,ucharREG_data){MMA8452_Stait();〃起始信号MMA8452_SendBvte(SlaveAddress);〃发送设备地址+写信号MMA8452_SendByte(REG-Addiess);〃内部寄存器地址MMA8452_SendByte(REG_data);〃内部寄存器数据MMA8452_StopO;〃发送停止信号}*****************************************//********单字节读取uchaiSiiigle_Read_NIMA8452(ucharREG_Address){uchaiREG_data;MMA8452_Stait();MMA8452_SendBvte(SlaveAddress);MMA8452_SendBvte(REG_Addiess);始MMA8452_Stan();MMA8452_SendBvte(SlaveAddress+l);REG_data=MMA8452_RecvByte();MMA8452_SendACK(1);MMA8452_Stop();returnREG_data;〃起始信号//发送设备地址+写信号〃发送存储单元地址,从0开〃起始信号〃发送设备地址+读信号〃读出寄存器数据〃停止信号〃*********************************************************//〃连续读出MMA8452内部加速度数据,地址范I判0x01-0x06//〃*********************************************************voidWnte_dnft_MNIA8452(iiiti.iiitj.iiitz)uchari;else〃停止信号MMA7455_StopO;Delav5nisQ;}*/voidcheck()//自检{inti=Oj=O,k=O.flagl=Lflag2=l,flag3=l;floattemp1,temp2,temp3;Smgle_Wnte_MNIA8452(0x2A,0x01);//Smgle_Wnte_MNIA8452(0x2B,0x02);//delav(lO);while(flag1||flag2||flag3){Multiple_Read.MMA84520;dis_data=BUF[O];if(dis_data>0x7f)dis_data=(((dis_data-1)AOxff)&0x7f);〃取反并屏掉符号位temp1=(float)dis_data/63;temp!*=100;dis_data=BUF[l];if(dis_data>0x7f)dis_data=(((dis_data-1)AOxff)&0x7f);〃取反并屏掉符号位temp2=(float)dis_data/63;temp2*=100;dis_data=BUF[2];if(dis_data>0x7f)dis_data=(((dis_data-1)A0xff)&0x7f);〃取反并屏掉符号位temp3=(float)dis_datjv63;temp3*=100;W[ite_dnft_MMA8452(iJ、k);if((temp2!=0)&&flag2)J++;elseflag2=0:if((temp3<98)&&flag3)k++;elseflag3=0:if((templ!=0)&&flagl)1++;elseflag1=0;delay(l);}〃******************初始化IOIIvoidinit_IO()ADCONl=0x06:TRISB=0X00;TRISA=0X00;//TRISE=OxfO;//PORTE=0;〃设置AII为普通10II〃设置AII为输出〃初始化MMA8452,根据需要请参考pdf进行修改************************voidInit_MMA8452(){Smgle_Wnte.MNIA8452(0x2A,0x01);//Smgle_Wnte_MNIA8452(0x2B,0x02);//LCD_clear();〃清屏LCD-write_char(2,2/C,);LCD_write_char(3,2/H,);LCD_wiitjchai(4、2,E);LCD-wiite_char(5,2/C,);LCD_wiite_char(6,2/K,);LCD_wiitjchai(7、2,14);LCD_wiitjcha【(&2,14);LCD-wnte_char(9.2J4);LCD_wnte_char(l0,2,14);LCD_wnte_char(11,2J4);LCD_write_char(12,2,14);LCD-write_char(03.P);LCD_WTitjcha【(3、3y);LCD_wiitjcha【(5、3,E);LCD_wiitjchai(&3/A1);LCD-wnte_char(10,3,T);LCD-write_char(1、3「U);LCD_write_chai(2,3/E*);LCD-write_char(43/S,);LCD^write^char(63.0);LCD_w[ite_chaT(7,3、W);LCD_WTite_chai(9q3,T);delay(500);check();〃*********************************************************〃******主程序********〃*********************************************************voidmain(){iiitsign.bit;unsignedinti;floattemp;delav(2);〃上电延时unto;SPHNTQ;delay(500);LCD.initQ;〃初始化LCD模块init_IO();Ink_MMA8452();LCD_clear();〃清屏幕wlule(l){Multiple_Read.MMA84520;//显示X轴〃初始化MMA8452〃循环〃连续读出数据,存储在EUF中dis_data=BUF[O];if(dis_data>0x7f){dis_data=Oxff^dis_data;sign_bit=l;}elsesign_bit=O;〃确定正负符号位temp=(float)dis_data/63;temp*=100;conversion(temp);〃计算数据和显示LCD_wnte_char(0.0,56);//XLCD_wiitjcha【(lO26);//〔'if(sign_bit==l)LCD_write_chai(2,0,13);//-elseLCD_write_chai(2,0,0);〃显示正负符号位LCD_wnte_char(3.0,bai);LCD_wnte_char(4.0,14);//・LCD-write_char(5Qshi);LCD-wnte_char(6.0,ge);LCD-wnte_char(7.0/G,);1显示Y轴dis_data=BUF[2];if(dis_data>0x7f){dis_data=Oxfi^dis_data;sign__bit=l;}elsesign__bit=O;〃确定正负符号位temp=(float)dis_data/63;temp*=100;conversion(temp);〃计算数据和显示LCD_wnte_char(0.1,57);//YLCD-write_char(14,26);//:if(sign_bit==l)LCD_write_chai(2,1,13);//-elseLCD_write_chai(2,1,0)//显示正负符号位LCD_wnte_char(3J,bai);LCD_wnte_char(4J,14);//.LCD_wnte_char(5,1,shi);LCD_wnte_char(6.1,ge);LCD_wnte_char(7,1,G);//显示z轴dis_data=BUF[4];if(dis_data>0x7f){dis_data=Oxfi^dis_data;sign_bit=l;}〃确定正负符号位elsesign_bit=0;temp=(float)dis_data/63;temp*=100;conversion(temp);〃计算数据和显示LCD_wiite_char(0,2,58);//ZLCD_wiite_chai(1226);//:if(sign_bit==l)LCD_wiite_chai(2213);〃・elseLCD_write_chai(2,2,0)^/显示正负符号位LCD_wnte_char(3、2,bai);LCD_wnte_char(4,2,14);//・LCD_wnte_char(5、2,shi);LCD_wii2_chai(62,ge);LCD_wiite_char(7,2/G,);for(i=0;i<30000;i++);〃延时}}
{
for(j=0j<110;j++);
严*************************************延时5微秒(STC90C52RC@12M)
不同的工作坏境,需要调整此函数,注意时钟过快时需要修改当改用1T的MCU时,请调整此延时函数
voidDelay5us()
NOP();NOP();NOP0;NOP();
NOP0;〃NOP();NOP();NOP();
//NOPQ;NOP();NOP();NOP0;}
严*************************************延时5亳秒(STC90C52RC@12M)不同的工作坏境,需要调整此函数当改用1T的MCU时,请调整此延时函数**************************************/
voidDelay5ms()
WORDn=560;wliile(n-);
严*************************************起始信号**************************************/
voidMMA8452_Stait(){
SDA_LOW();
〃拉高数据线
〃拉高时钟线
〃延时
〃产生下降沿
//拉低时钟线
SDA=1;
SCL=1;
Delav5us();
SDA=0;
SCL=0;
严*************************************停止信号**************************************/
voidMMA8452_Stop(){
〃拉低数据线
〃产生上升沿
严*************************************发送应答信号
入II参数:
ack(O:
ACK1:
NAK)
**************************************/
voidMMA8452_SendACK(uchaiack){
SDA=ack;
Delav5us();SCL=0;
Delav5us();}
〃写应答信号
严*************************************
接收应答信号
bitMMA8452_RmvACK(){
SDA_HIGH();
Delav5us();if(SDA=l)
CY=1;
else
〃读应答信号
SCL=0;Delav5us();SDA_LOW();returnCY;
〃拉低时钟线
向IIC总线发送一个字节数据
voidMMA8452_SendByte(BYTEdat)
BYTE1;
for(1=0;i<8;i++)//8位计数器
if(dat&0x80)
elseCY=O;
SDA=CY;
〃送数据门
Delav5usQ;
dat«=1;
〃移出数据的最高位
MMA8452_RecvACK();
严*************************************从IIC总线接收一个字节数据**************************************/
BYTEMMA8452_RecvByte(){
BYTEi;
BYTEdat=0;SDA_LOW0;
//使能内部上拉,准备读取数据,
//8位计数器
〃读数据
SDA=1;SDA_HIGH();for(1=0;i<8;i++){
dat«=1;SCL=1;Delav5usQ;if(SDA=l)
dat|=1;else
dat|=0;
SDA_LOW0;returndat;
〃******单字节写入
*******************************************
voidSmgle_Wnte_MMA8452(uchai-REG_Address,ucharREG_data){
MMA8452_Stait();〃起始信号
MMA8452_SendBvte(SlaveAddress);〃发送设备地址+写信号
MMA8452_SendByte(REG-Addiess);〃内部寄存器地址
MMA8452_SendByte(REG_data);〃内部寄存器数据
MMA8452_StopO;〃发送停止信号
*****************************************
//********单字节读取
uchaiSiiigle_Read_NIMA8452(ucharREG_Address){uchaiREG_data;
MMA8452_Stait();
MMA8452_SendBvte(SlaveAddress);
MMA8452_SendBvte(REG_Addiess);
始
MMA8452_Stan();
MMA8452_SendBvte(SlaveAddress+l);
REG_data=MMA8452_RecvByte();
MMA8452_SendACK
(1);
MMA8452_Stop();
returnREG_data;
〃起始信号
//发送设备地址+写信号
〃发送存储单元地址,从0开
〃发送设备地址+读信号
〃读出寄存器数据
〃停止信号
〃*********************************************************//
〃连续读出MMA8452内部加速度数据,地址范I判0x01-0x06
//〃*********************************************************
voidWnte_dnft_MNIA8452(iiiti.iiitj.iiitz)
uchari;
MMA7455_StopO;Delav5nisQ;
}*/
voidcheck()//自检
inti=Oj=O,k=O.flagl=Lflag2=l,flag3=l;
floattemp1,temp2,temp3;
Smgle_Wnte_MNIA8452(0x2A,0x01);//
Smgle_Wnte_MNIA8452(0x2B,0x02);//delav(lO);
while(flag1||flag2||flag3)
Multiple_Read.MMA84520;
dis_data=BUF[O];
if(dis_data>0x7f)
dis_data=(((dis_data-1)AOxff)&0x7f);〃取反并屏掉符号位
temp1=(float)dis_data/63;
temp!
*=100;
dis_data=BUF[l];
temp2=(float)dis_data/63;
temp2*=100;
dis_data=BUF[2];
dis_data=(((dis_data-1)A0xff)&0x7f);〃取反并屏掉符号位
temp3=(float)dis_datjv63;
temp3*=100;
W[ite_dnft_MMA8452(iJ、k);
if((temp2!
=0)&&flag2)
J++;
flag2=0:
if((temp3<98)&&flag3)
k++;
flag3=0:
if((templ!
=0)&&flagl)
1++;
flag1=0;
delay(l);
〃******************初始化IOIIvoidinit_IO()
ADCONl=0x06:
TRISB=0X00;
TRISA=0X00;
//TRISE=OxfO;
//PORTE=0;
〃设置AII为普通10II
〃设置AII为输出
〃初始化MMA8452,根据需要请参考pdf进行修改************************voidInit_MMA8452()
Smgle_Wnte.MNIA8452(0x2A,0x01);//
Smgle_Wnte_MNIA8452(0x2B,0x02);//
LCD_clear();〃清屏
LCD-write_char(2,2/C,);LCD_write_char(3,2/H,);LCD_wiitjchai(4、2,E);
LCD-wiite_char(5,2/C,);LCD_wiite_char(6,2/K,);
LCD_wiitjchai(7、2,14);LCD_wiitjcha【(&2,14);
LCD-wnte_char(9.2J4);LCD_wnte_char(l0,2,14);
LCD_wnte_char(11,2J4);LCD_write_char(12,2,14);
LCD-write_char(03.P);LCD_WTitjcha【(3、3y);LCD_wiitjcha【(5、3,E);LCD_wiitjchai(&3/A1);LCD-wnte_char(10,3,T);
LCD-write_char(1、3「U);LCD_write_chai(2,3/E*);
LCD-write_char(43/S,);
LCD^write^char(63.0);LCD_w[ite_chaT(7,3、W);
LCD_WTite_chai(9q3,T);
delay(500);
check();
〃*********************************************************〃******主程序********〃*********************************************************
voidmain()
iiitsign.bit;
unsignedinti;
floattemp;
delav
(2);〃上电延时
unto;
SPHNTQ;
LCD.initQ;〃初始化LCD模块
init_IO();
Ink_MMA8452();
LCD_clear();〃清屏幕wlule(l)
Multiple_Read.MMA84520;
//显示X轴
〃初始化MMA8452
〃循环
〃连续读出数据,存储在EUF中
dis_data=Oxff^dis_data;sign_bit=l;
sign_bit=O;〃确定正负符号位
temp=(float)dis_data/63;
temp*=100;
conversion(temp);〃计算数据和显示
LCD_wnte_char(0.0,56);//X
LCD_wiitjcha【(lO26);//〔'if(sign_bit==l)LCD_write_chai(2,0,13);//-
elseLCD_write_chai(2,0,0);〃显示正负符号位LCD_wnte_char(3.0,bai);
LCD_wnte_char(4.0,14);//・
LCD-write_char(5Qshi);
LCD-wnte_char(6.0,ge);
LCD-wnte_char(7.0/G,);
1显示Y轴
if(dis_data>0x7f){
dis_data=Oxfi^dis_data;
sign__bit=l;
sign__bit=O;〃确定正负符号位
temp=(float)dis_data/63;temp*=100;
LCD_wnte_char(0.1,57);//Y
LCD-write_char(14,26);//:
if(sign_bit==l)LCD_write_chai(2,1,13);//-elseLCD_write_chai(2,1,0)//显示正负符号位
LCD_wnte_char(3J,bai);LCD_wnte_char(4J,14);//.LCD_wnte_char(5,1,shi);LCD_wnte_char(6.1,ge);LCD_wnte_char(7,1,G);
//显示z轴
dis_data=BUF[4];
if(dis_data>0x7f){dis_data=Oxfi^dis_data;sign_bit=l;
〃确定正负符号位
sign_bit=0;
LCD_wiite_char(0,2,58);//Z
LCD_wiite_chai(1226);//:
if(sign_bit==l)LCD_wiite_chai(2213);〃・elseLCD_write_chai(2,2,0)^/显示正负符号位LCD_wnte_char(3、2,bai);
LCD_wnte_char(4,2,14);//・LCD_wnte_char(5、2,shi);
LCD_wii2_chai(62,ge);
LCD_wiite_char(7,2/G,);
for(i=0;i<30000;i++);〃延时
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1