本帖最后由 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);
- }
|