
QMC5883L-IIC测试程序.pdf
6页/*/QMC5883L IIC测试程序/使用单片机STC15W408AS/QMC5883 是一款国产三轴磁阻传感器/其内部寄存器设置与霍尼韦尔公司生产的HMC5883/不尽相同,不能直接套用HMC5883 的测试程序,否/则无法获得角度数据/下面给出的测试程序可以通过串口助手/在 PC 机上直接读出QMC5883 输出的角度数据/宜昌三峡电院电子科技创新协会/*#include STC15F2K60S2.H#include intrins.h#include math.h#include stdio.h#define Slave_Address 0 x1a/HMC5883 为 0 x3c typedef unsigned int u16;typedef unsigned char u8;u8 BUF8=0;sbit SCL=P12;/IIC 时钟线sbit SDA=P13;/IIC 数据线void Delay_5us();void Delay(u16 t);void InitUart();void QMC5883_Start();void QMC5883_Stop();void QMC5883_SendACK(bit ack);bit QMC5883_RecvACK();/void QMC5883_SendByte(u8 dat);/u8 QMC5883_RecvByte();/void Single_Write_QMC5883(u8 REG_Address,u8 REG_data);/u8 Single_Read_QMC5883(u8 REG_Address);void Multiple_Read_QMC5883(void);void Init_QMC5883();/STC15W408AS 无定时器1,只能用定时器2 作串口波特率发生器void InitUart()SCON=0 x50;AUXR|=0 x01;AUXR&=0 xFB;T2L=0 xE8;T2H=0 xFF;AUXR|=0 x10;ES=1;EA=1;TI=1;void Delay(u16 t)u16 i,j;for(i=t;i0;i-)for(j=121;j0;j-);void Delay_5us()u8 x;x=20;while(-x);/*起始信号*/void QMC5883_Start()SDA=1;/拉高数据线SCL=1;/拉高时钟线Delay_5us();/延时SDA=0;/产生下降沿Delay_5us();/延时SCL=0;/拉低时钟线/*停止信号*/void QMC5883_Stop()SDA=0;/拉低数据线SCL=1;/拉高时钟线Delay_5us();/延时SDA=1;/产生上升沿Delay_5us();/延时/*发送应答信号入口参数:ack(0:ACK 1:NAK)*/void QMC5883_SendACK(bit ack)SDA=ack;/写应答信号SCL=1;/拉高时钟线Delay_5us();/延时SCL=0;/拉低时钟线Delay_5us();/延时/*接收应答信号*/bit QMC5883_RecvACK()SCL=1;/拉高时钟线Delay_5us();/延时CY=SDA;/进位标志读应答信号SCL=0;/拉低时钟线Delay_5us();/延时return CY;/*向 IIC 总线发送一个字节数据*/void QMC5883_SendByte(u8 dat)u8 i;for(i=0;i8;i+)/8 位计数器 dat=1;/移出数据的最高位SDA=CY;/送数据口SCL=1;/拉高时钟线Delay_5us();/延时SCL=0;/拉低时钟线Delay_5us();/延时 QMC5883_RecvACK();/*从 IIC 总线接收一个字节数据*/u8 QMC5883_RecvByte()u8 i;u8 dat=0;SDA=1;/使能内部上拉,准备读取数据,for(i=0;i8;i+)/8 位计数器 dat=1;SCL=1;/拉高时钟线Delay_5us();/延时dat|=SDA;/读数据SCL=0;/拉低时钟线Delay_5us();/延时 return dat;/*写入单字节数据*void Single_Write_QMC5883(u8 REG_Address,u8 REG_data)QMC5883_Start();/起始信号QMC5883_SendByte(Slave_Address);/发送设备地址+写信号QMC5883_SendByte(REG_Address);/内部寄存器地址,请参考中文pdf QMC5883_SendByte(REG_data);/内部寄存器数据,请参考中文pdf QMC5883_Stop();/发送停止信号/*读取单字节数据*/u8 Single_Read_QMC5883(u8 REG_Address)/u8 REG_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();/停止信号/return REG_data;/*/连续读出QMC5883 内部角度数据,地址范围0 x000 x05/*void Multiple_Read_QMC5883(void)u8 i;QMC5883_Start();/起始信号QMC5883_SendByte(Slave_Address);/发送设备地址+写信号QMC5883_SendByte(0 x00);/发送存储单元地址,从0 x00 开始;HMC5883 从 0 x03 开始QMC5883_Start();/起始信号QMC5883_SendByte(Slave_Address+1);/发送设备地址+读信号for(i=0;i6;i+)/连续读取6 个地址数据,存储中BUF BUFi=QMC5883_RecvByte();/BUF0 存储数据if(i=5)QMC5883_SendACK(1);/最后一个数据需要回非应答NOACK else QMC5883_SendACK(0);/应答 ACK QMC5883_Stop();/停止信号Delay(5);/初始化 QMC5883,注意与HMC5883 的区别void Init_QMC5883()Single_Write_QMC5883(0 x09,0 x0d);/控制寄存器配置Single_Write_QMC5883(0 x0b,0 x01);/设置清除时间寄存器Single_Write_QMC5883(0 x20,0 x40);/Single_Write_QMC5883(0 x21,0 x01);/void main()/u16 i;int X=0,Y=0,Z=0;double Angle_XY=0,Angle_XZ=0,Angle_YZ=0;InitUart();Delay(200);/Init_Lcd();Init_QMC5883();Delay(300);while(1)Multiple_Read_QMC5883();/连续读取三轴角度数据,存储在BUF 中X=BUF1 8|BUF0;/Combine MSB and LSB of X Data output register 最高有效位Y=BUF3 8|BUF2;/Combine MSB and LSB of Y Data output register Z=BUF5 0 x7fff)X-=0 xffff;if(Y0 x7fff)Y-=0 xffff;if(Z0 x7fff)Z-=0 xffff;/printf(X=%iVn,X);/输出 int 型数据/Delay(2000);/printf(Y=%iVn,Y);/输出 int 型数据/Delay(2000);/printf(Z=%iVn,Z);/输出 int 型数据/Delay(2000);Angle_XY=atan2(double)Y,(double)X)*(180/3.14159265)+180;/计算 XY 平面角度/Angle_XY*=10;printf(XY=%fDn,Angle_XY);/输出 float 型数据Delay(1000);Angle_XZ=atan2(double)Z,(double)X)*(180/3.14159265)+180;/计算 XZ 平面角度/Angle_XZ*=10;printf(XZ=%fDn,Angle_XZ);/输出 float 型数据Delay(1000);Angle_YZ=atan2(double)Z,(double)Y)*(180/3.14159265)+180;/计算 YZ 平面角度/Angle_YZ*=10;printf(YZ=%fDn,Angle_YZ);/输出 float 型数据Delay(1000);。
