用stm32读取hmc58663l获取的3轴都是“-1”,不知道怎么回事
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "Lcd_Driver.h"
#include "hmc5883l.h"
#include "usart.h"
#include "sys.h"
#include "stdlib.h"
#include "math.h"
int x, y, z, X, Y, Z;
float Get_Current_Angle() {
u8 i;
u8 a[6];
float Curent_Angle;
i2c_Start(); //iic开始
i2c_SendByte(HMC5883L_Write_Address); //发送写地址 0x3c
i2c_WaitAck(); //等待应答
i2c_SendByte(0x03);//发送写的那个寄存器
i2c_WaitAck(); //等待应答
i2c_Start(); //iic第二次开始
i2c_SendByte(HMC5883L_Read_Address); //发送读地址 0x3d
i2c_WaitAck(); //等待应答
for (i = 0;i < 6;i++) //都6个字节
{
a[i] = i2c_ReadByte();
if (i == 5)
{
i2c_NAck(); //最后一字节应答
}
else
{
i2c_Ack();
}
}
i2c_Stop(); //停止iic
x = a[0];
x = x << 8;
x = x | a[1];
y = a[2];
y = y << 8;
y = y | a[3];
z = a[4];
z = z << 8;
z = z | a[5];
if (x > 32768)
{
x = -(0xFFFF - x + 1);
}
if (y > 32768)
{
y = -(0xFFFF - y + 1);
}
if (z > 32768)
{
z = -(0xFFFF - z + 1);
}
X = (s16)x; //x分量
Y = (s16)y; //y分量
Z = (s16)z; //z分量
printf("X:%d Y:%d Z:%d\r\n", X, Y, Z);
Curent_Angle = (atan2(Y, X) * (180 / 3.14159265) + 180); //实际水平角度
return Curent_Angle;
}
int main(void)
{
float ang;
SystemInit(); //System init.
delay_init(72);//Delay init.
Lcd_Init();
uart_init(115200);
HMC5883L_Init();
GPIO_ResetBits(GPIOA, GPIO_Pin_8);
GPIO_ResetBits(GPIOD, GPIO_Pin_2);
while (1)
{
delay_ms(4000);
ang = Get_Current_Angle();
printf("%f\r\n", ang);
}
}
hmc58663l.h头文件
#include "stm32f10x_i2c.h"
#include "misc.h"
#include "sys.h"
#include "stm32f10x_gpio.h"
#include "delay.h"
/**
* i2c
*/
#define HMC5883L_Write_Address 0x3C
#define HMC5883L_Read_Address 0x3D
#define SDA_IN() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=(u32)8<<4;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=(u32)3<<4;}
#define IIC_SCL PBout(8) //SCL
#define IIC_SDA PBout(9) //SDA
#define GPIO_SCL GPIO_Pin_8
#define GPIO_SDA GPIO_Pin_9
#define IIC_PERIPH GPIOB
#define READ_SDA PBin(9)
void i2c_Start(void);
void i2c_Stop(void);
void i2c_SendByte(u8 _ucByte);
u8 i2c_ReadByte(void);
u8 i2c_WaitAck(void);
void i2c_Ack(void);
void i2c_NAck(void);
void HMC5883L_Init(void);
hmc58663l.c
#include "hmc5883l.h"
void IIC_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //ê1?üGPIOBê±?ó
GPIO_InitStructure.GPIO_Pin = GPIO_SCL | GPIO_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //í?íìê?3?
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IIC_PERIPH, &GPIO_InitStructure);
GPIO_SetBits(IIC_PERIPH, GPIO_Pin_8 | GPIO_Pin_9); //PB6,PB7 ê?3???
}
void i2c_Start(void)
{
/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
SDA_OUT();
IIC_SDA = 1;
delay_us(10);
IIC_SCL = 1;
delay_us(10);
IIC_SDA = 0;
delay_us(10);
IIC_SCL = 0;
delay_us(10);
}
void i2c_Stop(void)
{
/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
SDA_OUT();
IIC_SDA = 0;
delay_us(10);
IIC_SCL = 1;
delay_us(10);
IIC_SDA = 1;
}
void i2c_SendByte(u8 _ucByte)
{
u8 i;
SDA_OUT();
/* 先发送字节的高位bit7 */
for (i = 0; i < 8; i++)
{
if (_ucByte & 0x80)
{
IIC_SDA = 1;
}
else
{
IIC_SDA = 0;
}
delay_us(10);
IIC_SCL = 1;
delay_us(10);
IIC_SCL = 0;
if (i == 7)
{
IIC_SDA = 1; // 释放总线
}
_ucByte <<= 1; /* 左移一个bit */
delay_us(10);
}
}
u8 i2c_ReadByte(void)
{
u8 i;
u8 value;
IIC_SDA = 1;
SDA_IN();
/* 读到第1个bit为数据的bit7 */
value = 0;
for (i = 0; i < 8; i++)
{
value <<= 1;
IIC_SCL = 1;
delay_us(10);
if (READ_SDA)
{
value++;
}
IIC_SCL = 0;
delay_us(10);
}
return value;
}
u8 i2c_WaitAck(void)
{
u8 re;
SDA_IN();
IIC_SDA = 1; /* CPU释放SDA总线 */
delay_us(10);
IIC_SCL = 1; /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
delay_us(10);
if (READ_SDA) /* CPU读取SDA口线状态 */
{
re = 1;
}
else
{
re = 0;
}
IIC_SCL = 0;
delay_us(10);
return re;
}
void i2c_Ack(void)
{
SDA_OUT();
IIC_SDA = 0; /* CPU驱动SDA = 0 */
delay_us(10);
IIC_SCL = 1; /* CPU产生1个时钟 */
delay_us(10);
IIC_SCL = 0;
delay_us(10);
IIC_SDA = 1; /* CPU释放SDA总线 */
}
void i2c_NAck(void)
{
SDA_OUT();
IIC_SDA = 1; /* CPU驱动SDA = 1 */
delay_us(10);
IIC_SCL = 1; /* CPU产生1个时钟 */
delay_us(10);
IIC_SCL = 0;
delay_us(10);
}
void HMC5883L_Init(void)
{
IIC_IO_Init();
//i2c_CheckDevice(HMC5883L_Write_Address);
i2c_Start();
i2c_SendByte(HMC5883L_Write_Address);
i2c_WaitAck();
i2c_SendByte(0x00);
i2c_WaitAck();
i2c_SendByte(0x70);
i2c_WaitAck();
i2c_SendByte(0x01);
i2c_WaitAck();
i2c_SendByte(0xe0);
i2c_WaitAck();
i2c_SendByte(0x02);
i2c_WaitAck();
i2c_SendByte(0x01);
i2c_Stop();
}
这个最好先使用读取下传感器的ID值是否正确,以此判断I2C通讯是否正常,再查看手册看下传感器寄存器功能配置是否配置到位。 一步步解决问题,应该很快就可以迎刃而解了