- 打卡等级:初来乍到
- 打卡总天数:2
- 最近打卡:2025-06-27 00:27:11
已绑定手机
新手上路
- 积分
- 21
|
求救大佬,请支援下关于硬件I2C与HMC5883地磁传感器通讯问题,
目前使用软件I2C能够与HMC5883通讯上,但是换到硬件I2C就不行了。
要么读出的数据全是-1,要么读出的数据就是一个固定值,怎么转动传感器都没任何反应。
目前使用环境是STC8H8K64U, 淘宝买的gy271模块,24Mhz
// 硬件I2C初始化
void I2C_Init(void) {
P1M1 |= 0x30; // P1.4(SDA), P1.5(SCL)开漏
P1M0 |= 0x30;
P_SW2 = 0x80;
I2CCFG = 0xe0; //使能I2C主机模式
I2CMSST = 0x00;
}
// I2C总线等待
void i2c_Wait(void)
{
while (!(I2CMSST & 0x40));
I2CMSST &= ~0x40;
}
//发送START命令
void i2c_Start()
{
I2CMSCR = 0x01;
i2c_Wait();
}
void i2c_SendData(char dat)
{
I2CTXD = dat; //写数据到数据缓冲区
I2CMSCR = 0x02; //发送SEND命令
i2c_Wait();
i2c_SendACK(); //发送ACK信号
}
//发送读ACK命令
void i2c_RecvACK()
{
I2CMSCR = 0x03; //发送读ACK命令
i2c_Wait();
}
char i2c_RecvData()
{
I2CMSCR = 0x04; //发送RECV命令
i2c_Wait();
return I2CRXD;
}
void i2c_SendACK()
{
I2CMSST = 0x00; //设置ACK信号
I2CMSCR = 0x05; //发送ACK命令
i2c_Wait();
}
void i2c_SendNAK()
{
I2CMSST = 0x01; //设置NAK信号
I2CMSCR = 0x05; //发送ACK命令
i2c_Wait();
}
void i2c_Stop()
{
I2CMSCR = 0x06; //发送STOP命令
i2c_Wait();
}
//单字节写入
void i2c_Single_Write(u8 SlaveAddress, u8 REG_Address, u8 REG_data)
{
i2c_Start(); //起始信号
i2c_SendData(SlaveAddress); //发送设备地址+写信号
i2c_SendData(REG_Address); //写寄存器地址
i2c_SendData(REG_data); //写寄存器数据
i2c_Stop(); //发送停止信号
}
//单字节读取
u8 i2c_Single_Read(u8 SlaveAddress, u8 REG_Address)
{
uchar REG_data;
i2c_Start(); //起始信号
i2c_SendData(SlaveAddress); //发送设备地址+写信号
i2c_SendData(REG_Address); //写寄存器地址
i2c_Stop();
i2c_Start(); //起始信号
i2c_SendData(SlaveAddress + 1); //发送设备地址+读信号
REG_data = i2c_RecvData(); //读出寄存器数据
i2c_SendNAK(); //发送NAK信号
i2c_Stop(); //停止信号
return REG_data;
}
//初始化HMC5883
void HMC5883L_Init(void)
{
i2c_Single_Write(0x3C,0x00,0x70);
i2c_Single_Write(0x3C,0x01,0xA0);
i2c_Single_Write(0x3C,0x02,0x00);
}
u8 HMC5883L_Update(void)
{
u16 x,y;
u8 i,datas[6];
i2c_Start();
i2c_SendData(0x3C); // 设备地址 + 写
i2c_SendData(0x03); // 寄存器地址
i2c_Stop();
i2c_Start(); // 重新发送起始信号
i2c_SendData(0x3c+1); // 设备地址 + 读
for (i = 0; i < 5; i++) {
datas = i2c_RecvData(); // 读取数据
if(i==6) {
i2c_SendNAK(); // 最后一个字节发送NAK
} else {
i2c_SendACK(); // 其他字节发送ACK
}
}
i2c_Stop(); // 停止传输
x = (int16_t)((datas[0] << 8) | datas[1]);
y = (int16_t)((datas[4] << 8) | datas[5]);
printf("HMC5883_X:%d Y:%d \r\n",(int)x,(int)y);
if(x==0 && y==0){ return;}
m_Heading = (u8)((atan2((float)y,(float)x)*180.0/3.14159)+360)%360;
//I2C_Data_Received();
return m_Heading;
}
|
|