IIC通信协议分析

一、为什么要学iic
很多面试官喜欢问IIC通信协议怎么实现,当时我只有在开发板用过IIC来向存储芯片(WQ25128系列)存数据,觉得在设计中没有很大的作用,为什么相比起串口(USART)更喜欢问IIC,当听我说“之前学过一遍,已经总结在word里了,如果需要用到,再去看就行了”,结果面试官不是很满意我的回答。在百度帖吧,看别人也有问过这个问题,大多解释是面试官要看一下应试者的基础。面试前重新看一下背一下就行。同时有的人说IIC在实际应用在很多地方。
二、怎么理解IIC
2.1 概要
IIC(IIC,inter-Integrated circuit),两线式串行总线,用于MCU和外设间的通信。 IIC只需两根线:数据线SDA和时钟线SCL。以半双工方式实现MCU和外设之间数据传输,速度可达400kbps。
多主机I2C总线结构
注意SDA和SCL两根总线需要上拉,使总线处于空闲状态。
2.2 IIC协议
a.空闲状态
协议规定,SDA和SCL同时为高电平时,总线处于空闲状态。上拉电阻保证电平处于高电平。
起始信号和停止信号
起始信号:SCL为高电平时,SDA电平发生高到低的跳变
停止信号:SCL为高电平时,SDA电平发生低到高的跳变
在这里插入图片描述发送0xa0数据:有应答的,速度100khz
在这里插入图片描述周期10us:
在这里插入图片描述

b.应答信号
发送器每发送完一个字节(8个脉冲),在第9个脉冲间释放总线,接收器返回一个ACK信号,协议规定,低电平为有效应答,高电平为无效应答。
在这里插入图片描述
c.数据有效性
协议对有效数据进行了规定:即时钟信号为高电平期间,数据必须保持稳定,时钟信号低电平期间,数据线上的电平才允许变化。也就是说,数据在时钟信号到来前必须准备好,并保持到时钟信号的下降沿之后。
在这里插入图片描述

d.数据传输
I2C为同步传输,时钟控制数据位的传输,边沿触发。
驱动程序
直接引用实验中的代码。测试没问题。
起始信号

1.	//产生IIC起始信号
2.	void IIC_Start(void)
3.	{
4.	    SDA_OUT();     //sda线输出
5.	    IIC_SDA=1;        
6.	    IIC_SCL=1;
7.	    delay_us(4);
8.	    IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
9.	    delay_us(4);
10.	    IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
11.	} 

停止信号

1.	//产生IIC停止信号
2.	void IIC_Stop(void)
3.	{
4.	    SDA_OUT();//sda线输出
5.	    IIC_SCL=0;
6.	    IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
7.	    delay_us(4);
8.	    IIC_SCL=1; 
9.	    IIC_SDA=1;//发送I2C总线结束信号
10.	    delay_us(4);                                
11.	}

有效应答

1.	//产生ACK应答
2.	void IIC_Ack(void)
3.	{
4.	    IIC_SCL=0;
5.	    SDA_OUT();
6.	    IIC_SDA=0;
7.	    delay_us(2);
8.	    IIC_SCL=1;
9.	    delay_us(2);
10.	    IIC_SCL=0;
11.	}

无效应答

1.	//不产生ACK应答          
2.	void IIC_NAck(void)
3.	{
4.	    IIC_SCL=0;
5.	    SDA_OUT();
6.	    IIC_SDA=1;
7.	    delay_us(2);
8.	    IIC_SCL=1;
9.	    delay_us(2);
10.	    IIC_SCL=0;
11.	}  

发送单字节

1.	//IIC发送一个字节
2.	//返回从机有无应答
3.	//1,有应答
4.	//0,无应答           
5.	void IIC_Send_Byte(u8 txd)
6.	{                        
7.	    u8 t;   
8.	    SDA_OUT();      
9.	    IIC_SCL=0;//拉低时钟开始数据传输
10.	    for(t=0;t<8;t++)
11.	    {              
12.	        IIC_SDA=(txd&0x80)>>7;
13.	        txd<<=1;      
14.	        delay_us(2);   //对TEA5767这三个延时都是必须的
15.	        IIC_SCL=1;
16.	        delay_us(2); 
17.	        IIC_SCL=0;  
18.	        delay_us(2);
19.	    }    
20.	} 

接收单字节

1.	//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
2.	u8 IIC_Read_Byte(unsigned char ack)
3.	{
4.	    unsigned char i,receive=0;
5.	    SDA_IN();//SDA设置为输入
6.	    for(i=0;i<8;i++ )
7.	    {
8.	        IIC_SCL=0; 
9.	        delay_us(2);
10.	        IIC_SCL=1;
11.	        receive<<=1;
12.	        if(READ_SDA)receive++;   
13.	        delay_us(1); 
14.	    }                    
15.	    if (!ack)
16.	        IIC_NAck();//发送nACK
17.	    else
18.	        IIC_Ack(); //发送ACK   
19.	    return receive;
20.	}

三、怎么背IIC
上面的程序亲身验证过,可以用的(第二节非原创,摘录一个牛人,很久之前找到了,不知道原创的链接了)。
1.IIC由SCL和SDA组成。
2.根据IIC的时序要求,要实现六个功能子函数,包括启动函数,停止函数,应答函数,非应答函数,字节发送函数,字节接受函数。
3.再深入就是背时序了。启动,停止,应答,非应答是主动发送的过程相对来说比较简单,
启动就是先将SCL,SDA拉高,延时一下,然后将SDA拉低,延时一下;
停止也是先将SCL拉高,SDA拉低,延时一下,不过接下来将SDA拉高,延时一下;
应答是将SCL拉高,在拉高期间将SDA保持低电平,非应答则是将SDA拉高。
发送和接收字节都是从高位开始的,先将SCL拉高,延时一下,然后发送或者接收。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值