本帖最后由 1324968 于 2017-11-21 17:38 编辑
以下是代码,IIC通信
HMC5883L的控制指令是 0X3C 但是发出去,一直收不到回复。
然后我换了24C02测试IIC 控制命令换0xa0 能收到回复,说明IIC是OK的
但是不知道为什么HMC5883L就是不行。
和HMC5883L通信 收不到回复动作
和24C02通信能收到回复动作
#define SCL P1_0
#define SDA P1_1 //
#define SDA_OUT_PIN() P1MODL = _1010_1010b;//P1.3=MOTYO_OUT_Z,P1.2=MOTYO_OUT_F,P1.1=BLUE_S2,P1.0=BLUE_S1
#define SDA_IN_PIN() P1MODL = _1010_0010b;//P1.3=MOTYO_OUT_Z,P1.2=MOTYO_OUT_F,P1.1=BLUE_S2,P1.0=BLUE_S1
#define SCL_H SCL=1
#define SCL_L SCL=0
#define SDA_H SDA=1
#define SDA_L SDA=0
#define SDA_read P1_1
#define HMC5883L_Addr 0x3C
uchar BUF[8]; //接收数据缓存区
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] I2C delay
* @param None
* @retval None
*/
void I2C_delay(void)
{
uchar i=8;
while(i)
{
i--;
}
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] delay 5ms
* @param None
* @retval None
*/
void delay5ms(void)
{
int i=5000;
while(i)
{
i--;
}
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] delay n ms
* @param None
* @retval None
*/
void Delayms(unsigned int m)
{
unsigned int i;
for(; m != 0; m--)
for (i=0; i<100; i++);//50000
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] I2C start
* @param None
* @retval None
*/
void IIC_Start(void) // 起始位
{
SDA=1;
SCL=1;
I2C_delay(); // 保持4.7uS以上(TSU.STA)
SDA=0;
I2C_delay(); // 保持4uS以上(THD.STA)
SCL = 0; // 方便下一次时钟从低到高变化的操作。
}
void IIC_Stop(void) // 停止位
{
SDA=0;
SCL=1;
I2C_delay(); // 保持4.0uS以上(TSU.STO)
SDA=1;
I2C_delay(); // 保持4.7uS以上(TBUF)
}
void IIC_Ack(void) // 主机应答位
{
SDA=0;
I2C_delay(); // 保持0.2uS以上(TSU.DAT)
SCL=1;
I2C_delay(); // 保持4.0uS以上(THIGH)
SCL=0;
I2C_delay(); // 保持4.7uS以上(TLOW),此语句可以不要
}
void IIC_NoAck(void) // 主机反向应答位
{
SDA=1;
I2C_delay(); // 保持0.2uS以上(TSU.DAT)
SCL=1;
I2C_delay(); // 保持4.0uS以上(THIGH)
SCL=0;
I2C_delay();
}
bit IIC_GetACK() // 获取从机应答信号,返回为0时收到ACK,返回为1时没收到ACK
{
bit ErrorBit;
SDA = 1;
I2C_delay(); // 保持0.2uS以上(TSU.DAT)
SDA_IN_PIN();
SCL = 1;
I2C_delay(); // 保持4.0uS以上(THIGH)
ErrorBit=SDA;
SCL = 0;
I2C_delay(); // 保持4.7uS以上(TLOW),此语句可以不要
SDA_OUT_PIN();
return ErrorBit;
}
//*********************************************************************
// 功能描述:主设备向从设备发送个一字节
// 返回值: 0->成功 1->失败
//*********************************************************************/
unsigned char IIC_SendByte(unsigned char Data)
{
unsigned char i; // 位数控制
for (i=0;i<8;i++) // 写入时是用时钟上升沿同步数据
{
if (Data & 0x80)
SDA = 1;
else
SDA = 0;
I2C_delay(); // 保持0.2uS以上(TSU.DAT)
SCL = 1;
I2C_delay(); // 保持4.0uS以上(THIGH)
SCL = 0;
I2C_delay(); // 保持4.7uS以上(TLOW)
Data <<= 1;
}
return 1;
// return IIC_GetACK();
}
//*********************************************************************
// 功能描述:主设备向从设备读取一个字节
// 返回值: 读到的字节
// *********************************************************************/
unsigned char IIC_RecByte(void) // 接收单字节的数据,并返回该字节值
{
unsigned char i,rbyte=0;
SDA_IN_PIN();
SDA=1;
for(i=0;i<8;i++) // 读出时是用时钟下降沿同步数据
{
SCL=0;
I2C_delay(); // 保持4.7uS以上(TLOW)
SCL=1;
I2C_delay(); // 保持4.0uS以上(THIGH)
if(SDA) rbyte|=(0x80>>i);
}
SCL=0;
SDA_OUT_PIN();
return rbyte;
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] I2C single write
* @param None
* @retval None
*/
bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)
{
IIC_Start();
IIC_SendByte(SlaveAddress);
if(IIC_GetACK())
{
IIC_Stop();
return FALSE;
}
IIC_SendByte(REG_Address );
IIC_GetACK();
IIC_SendByte(REG_data);
IIC_GetACK();
IIC_Stop();
Delayms(5);
return TRUE;
}
/**
* @brief I2C single read
* @param None
* @retval None
*/
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{
unsigned char REG_data;
IIC_Start();
IIC_SendByte(SlaveAddress);
if(!IIC_GetACK()){IIC_Stop();return FALSE;}
IIC_SendByte((uchar) REG_Address);
IIC_GetACK();
IIC_Start();
IIC_SendByte(SlaveAddress+1);
IIC_GetACK();
REG_data= IIC_RecByte();
IIC_NoAck();
IIC_Stop();
return REG_data;
}
/**
* @brief hmc5883 func
* @param None
* @retval None
*/
void read_hmc5883l(void)
{
Single_Write(0x3C,0x00,0x14);
// Single_Write(HMC5883L_Addr,0x01,0x20);
// Single_Write(HMC5883L_Addr,0x02,0x00);
// Delayms(5);
// BUF[0]=Single_Read(HMC5883L_Addr,0x03); //X
// BUF[1]=Single_Read(HMC5883L_Addr,0x04);
// BUF[2]=Single_Read(HMC5883L_Addr,0x05); //Y
// BUF[3]=Single_Read(HMC5883L_Addr,0x06);
// BUF[4]=Single_Read(HMC5883L_Addr,0x07); //Z
// BUF[5]=Single_Read(HMC5883L_Addr,0x08);
}
|