QMC5883L-IIC测试程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//******************************
//QMC5883L IIC测试程序
//使用单片机STC15W408AS
//QMC5883是一款国产三轴磁阻传感器
//其内部寄存器设置与霍尼韦尔公司生产的HMC5883
//不尽相同,不能直接套用HMC5883的测试程序,否
//则无法获得角度数据。

//下面给出的测试程序可以通过串口助手
//在PC机上直接读出QMC5883输出的角度数据。

//宜昌三峡电院电子科技创新协会
//******************************
#include "STC15F2K60S2.H"
#include "intrins.h"
#include "math.h"
#include "stdio.h"
#define Slave_Address 0x1a //HMC5883为0x3c
typedef unsigned int u16;
typedef unsigned char u8;
u8 BUF[8]=0;
sbit SCL=P1^2; //IIC时钟线
sbit SDA=P1^3; //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 = 0x50;
AUXR |= 0x01;
AUXR &= 0xFB;
T2L = 0xE8;
T2H = 0xFF;
AUXR |= 0x10;
ES = 1;
TI=1;
}
void Delay(u16 t)
{
u16 i,j;
for(i=t;i>0;i--)
for(j=121;j>0;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)
{
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; i<8; 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; i<8; i++) //8位计数器
{
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内部角度数据,地址范围0x00~0x05
//******************************************************
void Multiple_Read_QMC5883(void)
{
u8 i;
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]存储数据
QMC5883_SendACK(1); //最后一个数据需要回非应答NOACK }
else
{
QMC5883_SendACK(0); //应答ACK
}
}
QMC5883_Stop(); //停止信号
Delay(5);
}
//初始化QMC5883,注意与HMC5883的区别
void Init_QMC5883()
{
Single_Write_QMC5883(0x09,0x0d); //控制寄存器配置
Single_Write_QMC5883(0x0b,0x01); //设置清除时间寄存器
Single_Write_QMC5883(0x20,0x40); //
Single_Write_QMC5883(0x21,0x01); //
}
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=BUF[1] << 8 | BUF[0]; //Combine MSB and LSB of X Data output register 最高有效位Y=BUF[3] << 8 | BUF[2]; //Combine MSB and LSB of Y Data output register
Z=BUF[5] << 8 | BUF[4]; //Combine MSB and LSB of Z Data output register
if(X>0x7fff) X-=0xffff;
if(Y>0x7fff) Y-=0xffff;
if(Z>0x7fff) Z-=0xffff;
//printf("X=%iV\n",X); //输出int型数据
//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);
}
}。

相关文档
最新文档