对IIC通信协议的粗略探究

重点:如何依照 ”Datasheet“ 写 IIC 通信函数

问题

问题1:读写元件的地址不一样,为啥传入参数一样,为啥都是写入地址。

答:xd 加1了

问题2:寄存器里都是补码形式,为什么代码不转换

答:没转换,单片机代码不需要,直接从寄存器中读出来就可以,读出来就是带符号位的数据,需要

if(x>0x7fff)x-=0xffff;

问题3:温度寄存器里的温度值如何转为摄氏度

答:

 

问题4:如何确定等待函数I2C_delay()的时长?

等待时长大于列表中最大值即可。

I2C术语

9种术语

S : (起始信号)SCL高,SDA从高到低

AD :从机地址

W :一位一位写

R :一位一位读

ACK :应答信号 SDA为低,当SCL在第九个周期为高的时候

NACK :不应答信号 SDA在第九个周期依旧为高

RA :ITG3200内部寄存器地址

DATA :发送或接收数据

P :当SCL为高时,SDA从低到高

写字节函数

Single_Write(器件地址,寄存器地址,数值);

bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)           //void
{
    if(!I2C_Start())return FALSE;//发送start
    I2C_SendByte(SlaveAddress);   //发送器件地址(写)
    if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}//等待应答
    I2C_SendByte(REG_Address );   //发送寄存器地址      
    I2C_WaitAck();                //等待应答
    I2C_SendByte(REG_data);       //发送寄存器数据
    I2C_WaitAck();                //等待应答
    I2C_Stop();                   //发送停止信号
    delay5ms();                  
    return TRUE;
}

读字节函数

 Single_Read(器件地址,寄存器地址);

unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{   
    unsigned char REG_data;         
    if(!I2C_Start())return FALSE;                                       //发送开始信号
    I2C_SendByte(SlaveAddress);                                         //发送从机地址(写)
    //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);
    if(!I2C_WaitAck()){I2C_Stop();test=1; return FALSE;}                //等待应答
    I2C_SendByte((u8) REG_Address);                                     //发送寄存器地址
    I2C_WaitAck();                                                      //等待应答
    I2C_Start();                                                        //发送开始信号
    I2C_SendByte(SlaveAddress+1);                                       //发送从机地址(读)
    I2C_WaitAck();                                                      //等待应答信号
    REG_data= I2C_RadeByte();                                           //读数据
    I2C_NoAck();                                                        //发送不应答信号
    I2C_Stop();                                                         //发送停止信号
    return REG_data;
}       

1.这个开始信号(标上标1)要么是一个重新开始信号,要么是一个停止信号

2.阴影区域代表了设备正在聆听。

S : (起始信号)SCL高,SDA从高到低

bool I2C_Start(void)
{
    SDA_H;                             //SDA
    SCL_H;
    I2C_delay();
    if(!SDA_read)return FALSE;        //SDA是否为1
    SDA_L;
    I2C_delay();
    if(SDA_read) return FALSE;        //SDA
    SDA_L;
    I2C_delay();
    return TRUE;
}

ACK :当SCL在第九个周期为高的时候,应答信号 SDA为低。

/*******************************************************************************
* Function Name  : I2C_Ack
* Description    : Master Send Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_Ack(void)
{   
    SCL_L;
    I2C_delay();
    SDA_L;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SCL_L;
    I2C_delay();
}   

NACK :不应答信号 SDA在第九个周期依旧为高

 

/*******************************************************************************
* Function Name  : I2C_NoAck
* Description    : Master Send No Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_NoAck(void)
{   
    SCL_L;
    I2C_delay();
    SDA_H;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SCL_L;
    I2C_delay();
} 

WA :等待应答

/*******************************************************************************
* Function Name  : I2C_WaitAck
* Description    : Master Reserive Slave Acknowledge Single
* Input          : None
* Output         : None
* Return         : Wheather  Reserive Slave Acknowledge Single
****************************************************************************** */
bool I2C_WaitAck(void)   //·µ»ØΪ:=1ÓÐACK,=0ÎÞACK
{
    SCL_L;
    I2C_delay();
    SDA_H;          
    I2C_delay();
    SCL_H;
    I2C_delay();
    if(SDA_read)
    {
      SCL_L;
      I2C_delay();
      return FALSE;
    }
    SCL_L;
    I2C_delay();
    return TRUE;
}

P :停止信号,当SCL为高时,SDA从低到高

/*******************************************************************************
* Function Name  : I2C_Stop
* Description    : Master Stop Simulation IIC Communication
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_Stop(void)
{
    SCL_L;
    I2C_delay();
    SDA_L;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SDA_H;
    I2C_delay();
} 

仅仅是在数据传送中……

img

发送一字节

/*******************************************************************************
* Function Name  : I2C_SendByte
* Description    : Master Send a Byte to Slave
* Input          : Will Send Date
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_SendByte(u8 SendByte)          //发送一个字节
{
    u8 i=8;
    while(i--)
    {
        SCL_L;                           //SCL低
        I2C_delay();                     //延时不足1us
      if(SendByte&0x80)                  //若首位为1,则SDA高,否则SDA为低
        SDA_H;                           
      else 
        SDA_L;   
        SendByte<<=1;                    //左移1位
        I2C_delay();                     //延时不足1us
        SCL_H;                          //SCL拉高
        I2C_delay();                     //延时不足1us
    }                                 //一位数据发送结束
    SCL_L;                               //最后再将时钟线拉低
}  

接收一字节

/*******************************************************************************
* Function Name  : I2C_RadeByte
* Description    : Master Reserive a Byte From Slave
* Input          : None
* Output         : None
* Return         : Date From Slave 
  ****************************************************************************** */
  unsigned char I2C_RadeByte(void)          //读取一个字节
  { 
    u8 i=8;
    u8 ReceiveByte=0;
​
    SDA_H;              
    while(i--)
    {
      ReceiveByte<<=1;      
      SCL_L;
      I2C_delay();
    SCL_H;
      I2C_delay();  
      if(SDA_read)
      {
        ReceiveByte|=0x01;
      }
    }
    SCL_L;
    return ReceiveByte;
  } 
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值