QMC5883LIIC测试程序.docx
《QMC5883LIIC测试程序.docx》由会员分享,可在线阅读,更多相关《QMC5883LIIC测试程序.docx(11页珍藏版)》请在冰豆网上搜索。
QMC5883LIIC测试程序
QMC5883L-IIC测试程序
//******************************
//QMC5883LIIC测试程序
//使用单片机STC15W408AS
//晶振频率:
11.0592M
//QMC5883是一款国产三轴磁阻传感器
//其内部寄存器设置与霍尼韦尔公司生产的HMC5883
//不尽相同,不能直接套用HMC5883的测试程序,否
//则无法获得角度数据。
//下面给出的测试程序可以通过串口助手
//在PC机上直接读出QMC5883输出的角度数据。
//宜昌三峡电院电子科技创新协会
//******************************
#include"STC15F2K60S2.H"
#include"intrins.h"
#include"math.h"
#include"stdio.h"
#defineSlave_Address0x1a//HMC5883为0x3c
typedefunsignedintu16;
typedefunsignedcharu8;
u8BUF[8]=0;
sbitSCL=P1^2;//IIC时钟线
sbitSDA=P1^3;//IIC数据线
voidDelay_5us();
voidDelay(u16t);
voidInitUart();
voidQMC5883_Start();
voidQMC5883_Stop();
voidQMC5883_SendACK(bitack);
bitQMC5883_RecvACK();//
voidQMC5883_SendByte(u8dat);//
u8QMC5883_RecvByte();//
voidSingle_Write_QMC5883(u8REG_Address,u8REG_data);
//u8Single_Read_QMC5883(u8REG_Address);
voidMultiple_Read_QMC5883(void);
voidInit_QMC5883();
//STC15W408AS无定时器1,只能用定时器2作串口波特率发生器
voidInitUart()
{
SCON=0x50;
AUXR|=0x01;
AUXR&=0xFB;
T2L=0xE8;
T2H=0xFF;
AUXR|=0x10;
ES=1;
EA=1;
TI=1;
}
voidDelay(u16t)
{
u16i,j;
for(i=t;i>0;i--)
for(j=121;j>0;j--);
}
voidDelay_5us()
{
u8x;
x=20;
while(--x);
}
/**************************************
起始信号
**************************************/
voidQMC5883_Start()
{
SDA=1;//拉高数据线
SCL=1;//拉高时钟线
Delay_5us();//延时
SDA=0;//产生下降沿
Delay_5us();//延时
SCL=0;//拉低时钟线
}
/**************************************
停止信号
**************************************/
voidQMC5883_Stop()
{
SDA=0;//拉低数据线
SCL=1;//拉高时钟线
Delay_5us();//延时
SDA=1;//产生上升沿
Delay_5us();//延时
}
/**************************************
发送应答信号
入口参数:
ack(0:
ACK1:
NAK)
**************************************/
voidQMC5883_SendACK(bitack)
{
SDA=ack;//写应答信号
SCL=1;//拉高时钟线
Delay_5us();//延时
SCL=0;//拉低时钟线
Delay_5us();//延时
}
/**************************************
接收应答信号
**************************************/
bitQMC5883_RecvACK()
{
SCL=1;//拉高时钟线
Delay_5us();//延时
CY=SDA;//进位标志读应答信号
SCL=0;//拉低时钟线
Delay_5us();//延时
returnCY;
}
/**************************************
向IIC总线发送一个字节数据
**************************************/
voidQMC5883_SendByte(u8dat)
{
u8i;
for(i=0;i<8;i++)//8位计数器
{
dat<<=1;//移出数据的最高位
SDA=CY;//送数据口
SCL=1;//拉高时钟线
Delay_5us();//延时
SCL=0;//拉低时钟线
Delay_5us();//延时
}
QMC5883_RecvACK();
}
/**************************************
从IIC总线接收一个字节数据
**************************************/
u8QMC5883_RecvByte()
{
u8i;
u8dat=0;
SDA=1;//使能内部上拉,准备读取数据,
for(i=0;i<8;i++)//8位计数器
{
dat<<=1;
SCL=1;//拉高时钟线
Delay_5us();//延时
dat|=SDA;//读数据
SCL=0;//拉低时钟线
Delay_5us();//延时
}
returndat;
}
//************************写入单字节数据***************************
voidSingle_Write_QMC5883(u8REG_Address,u8REG_data)
{
QMC5883_Start();//起始信号
QMC5883_SendByte(Slave_Address);//发送设备地址+写信号
QMC5883_SendByte(REG_Address);//内部寄存器地址,请参考中文pdf
QMC5883_SendByte(REG_data);//内部寄存器数据,请参考中文pdf
QMC5883_Stop();//发送停止信号
}
//************************读取单字节数据*************************
//u8Single_Read_QMC5883(u8REG_Address)
//{
//u8REG_data;
//QMC5883_Start();//起始信号
//QMC5883_SendByte(Slave_Address);//发送设备地址+写信号
//QMC5883_SendByte(REG_Address);//发送存储单元地址,从0开始
//QMC5883_Start();//起始信号
//QMC5883_SendByte(Slave_Address+1);//发送设备地址+读信号
//REG_data=QMC5883_RecvByte();//读出寄存器数据
//QMC5883_SendACK
(1);
//QMC5883_Stop();//停止信号
//returnREG_data;
//}
//******************************************************
//连续读出QMC5883内部角度数据,地址范围0x00~0x05
//******************************************************
voidMultiple_Read_QMC5883(void)
{
u8i;
QMC5883_Start();//起始信号
QMC5883_SendByte(Slave_Address);//发送设备地址+写信号
QMC5883_SendByte(0x00);//发送存储单元地址,从0x00开始;HMC5883从0x03开始
QMC5883_Start();//起始信号
QMC5883_SendByte(Slave_Address+1);//发送设备地址+读信号
for(i=0;i<6;i++)//连续读取6个地址数据,存储中BUF
{
BUF[i]=QMC5883_RecvByte();//BUF[0]存储数据
if(i==5)
{
QMC5883_SendACK
(1);//最后一个数据需要回非应答NOACK
}
else
{
QMC5883_SendACK(0);//应答ACK
}
}
QMC5883_Stop();//停止信号
Delay(5);
}
//初始化QMC5883,注意与HMC5883的区别
voidInit_QMC5883()
{
Single_Write_QMC5883(0x09,0x0d);//控制寄存器配置
Single_Write_QMC5883(0x0b,0x01);//设置清除时间寄存器
Single_Write_QMC5883(0x20,0x40);//
Single_Write_QMC5883(0x21,0x01);//
}
voidmain()
{
//u16i;
intX=0,Y=0,Z=0;
doubleAngle_XY=0,Angle_XZ=0,Angle_YZ=0;
InitUart();
Delay(200);
//Init_Lcd();
Init_QMC5883();
Delay(300);
while
(1)
{
Multiple_Read_QMC5883();//连续读取三轴角度数据,存储在BUF中
X=BUF[1]<<8|BUF[0];//CombineMSBandLSBofXDataoutputregister最高有效位
Y=BUF[3]<<8|BUF[2];//CombineMSBandLSBofYDataoutputregister
Z=BUF[5]<<8|BUF[4];//CombineMSBandLSBofZDataoutputregister
if(X>0x7fff)X-=0xffff;
if(Y>0x7fff)Y-=0xffff;
if(Z>0x7fff)Z-=0xffff;
//printf("X=%iV\n",X);//输出int型数据
//Delay(2000);
//printf("Y=%iV\n",Y);//输出int型数据
//Delay(2000);
//printf("Z=%iV\n",Z);//输出int型数据
//Delay(2000);
Angle_XY=atan2((double)Y,(double)X)*(180/3.14159265)+180;//计算XY平面角度
//Angle_XY*=10;
printf("XY=%fD\n",Angle_XY);//输出float型数据
Delay(1000);
Angle_XZ=atan2((double)Z,(double)X)*(180/3.14159265)+180;//计算XZ平面角度
//Angle_XZ*=10;
printf("XZ=%fD\n",Angle_XZ);//输出float型数据
Delay(1000);
Angle_YZ=atan2((double)Z,(double)Y)*(180/3.14159265)+180;//计算YZ平面角度
//Angle_YZ*=10;
printf("YZ=%fD\n",Angle_YZ);//输出float型数据
Delay(1000);
}
}