单片机下使用IIC

 

一、IIC总线有两根双向信号线,一根是数据线SDA,一根是时钟线SCL

 

 

 

每根接到IIC总线上的器件都有唯一的地址

 

二、IIC通信协议的函数写法

1、  起始信号

2、  终止信号

3、  写数据

4、  读数据

5、  发送应答信号

6、  发送非应答信号

7、  等待应答

8、  检测IIC总线设备

三、函数解析

1、  起始信号和终止信号

SCL为高电平期间,SDA线由高电平向低电平变化表示起始信号

SCL为高电平期间,SDA线由低电平向高电平变化表示终止信号

 

 

void i2c_Start(void)
{
    /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
    SDA = 1;
    SCL = 1;
    i2c_Delay();
    SDA = 0;
    i2c_Delay();
    SCL = 0;
    i2c_Delay();
}

void i2c_Stop(void)
{
    /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
    SDA = 0;
    SCL = 1;
    i2c_Delay();
    SDA = 1;
    i2c_Delay();
}

2、  应答和非应答

IIC总线规定,每传送一字节的数据后都要有一个应答信号以确定数据传送是否被对方接收。

 

应答信号由接收设备产生,在SCL为高电平期间,接收设备将SDA拉低为低电平,表示数据传输正确,产生应答。

unsigned char i2c_WaitAck(void)
{
     unsigned char re; //应答信号等于0则应答正确,等于1则没有应答
     SDA = 1;          //释放总线,能让对方拉低
     i2c_Delay();
     SCL = 1;          //此时刻开始,数据保持应答状态稳定
     i2c_Delay();
     re = SDA;         //0表示应答,1表示没有应答
     i2c_Delay(); 
     SCL = 0;
     i2c_Delay();

     return re;
}

3、  IIC数据的传送

数据位的有效性规定:IIC总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平时期,数据线上的高电平或低电平状态才允许变化。

 

 

 

void i2c_SendByte(unsigned char _ucByte)
{
     unsigned char i;     //其实信号开始后SCL是被拉低的
     for(i = 0; i < 8; i++)
     {
        if((_ucByte<<i) & 0x80)
            SDA = 1;
        else
            SDA = 0;
        SCL = 1; 
        i2c_Delay();
        SCL = 0;      //SCL等于0的时候写数据
        if(i == 7)    //最后一次时释放总线
        {
            SDA = 1;
        }
        i2c_Delay();
     }
}

unsigned char i2c_ReadByte(void)
{
     unsigned char i;
     unsigned char value = 0;
     for(i = 0; i < 8; i++)
     {
        value<<=1;    //循环左移,
        SCL = 1;  //稳定状态的时候读数据
        if(SDA == 1)
            value |= 0x01;//value++;  //最低位置0
    else
        value &= 0xfe;  //最低位置0
        SCL = 0;  //允许数据变化
        i2c_Delay();
     }

     return value;
}

4、产生一个应答信号和一个非应答信号

 

/*
*********************************************************************************************************
*   函 数 名: i2c_Ack
*   功能说明: CPU产生一个ACK信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
    SDA = 0;//响应
    i2c_Delay();
    SCL = 1;
    i2c_Delay();
    SCL = 0;
    i2c_Delay();   //在SCL为高电平期间SDA都为0即产生一个应答信号
    SDA = 1;       //释放总线
    i2c_Delay();
}

/*
*********************************************************************************************************
*   函 数 名: i2c_NAck
*   功能说明: CPU产生1个NACK信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
     SDA = 1;
     i2c_Delay();
     SCL = 1;
     i2c_Delay();
     SCL = 0;
     i2c_Delay();   //在SCL为高电平期间SDA都为1即产生一个非应答信号
}

5、延时函数

/*
*********************************************************************************************************
*   函 数 名: i2c_Delay
*   功能说明: I2C总线位延迟,最快400KHz
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
static void i2c_Delay(void)
{
    unsigned char i;

    /* 
        实际应用选择小于400KHz左右的速率即可
    */
    for (i = 0; i < 10; i++);
}

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/zhangerxiaoma/p/11511993.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值