IIC总线的总结与问题(IIC输出是开漏输出 硬件IIC要求从设备有应答能力 IC在多字节的读取的时候必须要正确的给出应答)

IIC输出是开漏输出,所以在SCL和SDA两个引脚上必须接上上拉电阻

IIC总线需要在发送了地址之后必须发送

模拟发送数据函数如下:

void iic_sendid(uint8_t id,IIC_DIRECTION direction){
    uint8_t m;
    uint8_t j;
    id<<=1;
    for(j=0;j<7;j++)
    {
        m=id;
        GPIO_Pin_Clear(iic_SCLK);
        m=m&0x80;
        if(m==0x80)
        {        
            GPIO_Pin_Set(iic_SDA);
        }
        else
        {
            GPIO_Pin_Clear(iic_SDA);
        }
        id=id<<1;
        GPIO_Pin_Set(iic_SCLK);
    }
    GPIO_Pin_Clear(iic_SCLK);
    if(direction==iic_write) GPIO_Pin_Clear(iic_SDA);
    else GPIO_Pin_Set(iic_SDA);
    GPIO_Pin_Set(iic_SCLK);
    
    GPIO_Pin_Clear(iic_SCLK);   //应答
    GPIO_Pin_Set(iic_SDA);   //可以查看有没有应答
    GPIO_Pin_Set(iic_SCLK);
    GPIO_Pin_Clear(iic_SCLK); //注意这里必须要再次清除掉SCLK  否则的话设备就会认为还没有到响应结束,那么就造成了当再次开始时第一个时钟就会被认为是应答结束时钟
}

注意上面的注释,很关键


/*
IIC开始函数 时序开始 产生停止位
*/
void start(void)
{
    GPIO_Pin_Set(iic_SDA);
    GPIO_Pin_Set(iic_SCLK);
    GPIO_Pin_Clear(iic_SDA);
    GPIO_Pin_Clear(iic_SCLK);
}
/*
IIC停止函数 产生停止位
*/
void stop(void)
{
    GPIO_Pin_Clear(iic_SCLK);
    GPIO_Pin_Clear(iic_SDA);
    GPIO_Pin_Set(iic_SCLK);
    GPIO_Pin_Set(iic_SDA);
}

注意开始函数和停止函数的顺序,很关键

硬件IIC要求从设备必须有应答能力

如果从设备没有应答能力,也可以说硬件IIC必须要有负载设备,那么IIC硬件将会在传输完第一个直接(设备地址)后断开传输:


IIC在多字节的读取的时候必须要正确的给出应答

IIC在多字节的读取也就是主机作为数据的接收端,这时候从设备要判断发送的数据时候正确,所以主机在完全接收到一个字节之后必须要给予正确的应答,比如KX022的手册要求的时序如下:

当在接收到一个data(第一个DATA)后如果主机不给应答,那么通讯很有可能会出现错误,造成的现象有可能是在接下来的传输里,从机一直拉低SDA数据线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值