stm32---iic通信

来源:互联网 发布:医药政策法规数据库 编辑:程序博客网 时间:2024/05/29 15:53

先摘一摘网上的理解:

一. 技术性能:
工作速率有100K和400K两种;
支持多机通讯;
支持多主控模块,但同一时刻只允许有一个主控;      
由数据线SDA和时钟SCL构成的串行总线;
每个电路和模块都有唯一的地址;                    
每个器件可以使用独立电源

clip_image004


二. 基本工作原理:
以启动信号START来掌管总线,以停止信号STOP来释放总线;
每次通讯以START开始,以STOP结束;
启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R/W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;
当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;
每个数据字节在传送时都是高位(MSB)在前;

三.通信过程:
写通讯过程:
1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
2. 发送一个地址字节(包括7位地址码和一位R/W);
3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
4. 主控收到ACK后开始发送第一个数据字节;
5. 被控器收到数据字节后发送一个ACK表示继续传送数据,发送NACK表示传送数据结束;
6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;


读通讯过程:
1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
2. 发送一个地址字节(包括7位地址码和一位R/W);
3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
4. 主控收到ACK后释放数据总线,开始接收第一个数据字节;
5. 主控收到数据后发送ACK表示继续传送数据,发送NACK表示传送数据结束;
6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;



四. 总线信号时序分析
1. 总线空闲状态
SDA和SCL两条信号线都处于高电平,即总线上所有的器件都释放总线,两条信号线各自的上拉电阻把电平拉高;
2. 启动信号START
时钟信号SCL保持高电平,数据信号SDA的电平被拉低(即负跳变)。启动信号必须是跳变信号,而且在建立该信号前必修保证总线处于空闲状态;
3. 停止信号STOP
时钟信号SCL保持高电平,数据线被释放,使得SDA返回高电平(即正跳变),停止信号也必须是跳变信号。
4. 数据传送
SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为低电压),高电平表示1(此时的电压由元器件的VDD决定)。只有在SCL线为低电平期间,SDA上的电平允许变化。
5. 应答信号ACK
I2C总线的数据都是以字节(8位)的方式传送的,发送器件每发送一个字节之后,在时钟的第9个脉冲期间释放数据总线,由接收器发送一个ACK(把数据总线的电平拉低)来表示数据成功接收。
6. 无应答信号NACK
在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NACK,NACK有两种用途:
a. 一般表示接收器未成功接收数据字节;
b. 当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。

五. 寻址约定
地址的分配方法有两种:
1. 含CPU的智能器件,地址由软件初始化时定义,但不能与其它的器件有冲突;
2. 不含CPU的非智能器件,由厂家在器件内部固化,不可改变。

高7位为地址码,其分为两部分:
1. 高4位属于固定地址不可改变,由厂家固化的统一地址;
2. 低三位为引脚设定地址,可以由外部引脚来设定(并非所有器件都可以设定);

另,按照一哥们的告诉我的理解:

通信过程如下:

(1)通信过程的开始首先时钟线SCL在一个时钟周期的高电平期间内,如果此时数据线SDA有从高电平跳到低电平的负条边沿,则标志着通信过程的开始。

(2)地址数据的发送,通信过程开始后,即在这个开始的时钟周期后,随后的8个时钟周期内,开始正常采样数据线SDA上的数据。即时钟周期高电平时,数据线上的高低电平均有效,并被正确译为八位二进制数。通信开始的时钟周期后的这八个时钟周期采样的数据,各个从设备都会收到,然后与自己的地址比较。这就相当于一个握手信号。

(3)真正数据的发送,在上述某个从设备发现自己的地址匹配时,便在下个时钟的高电平来之前将数据线SDA的电平拉低置成低电平,即保证在下个时钟的高电平阶段,SDA的电平始终为低。这样,以后的数据再发送,其他设备都不会接受了,只有该从设备会采样接受。

(4)通信过程的结束。与通信的开始一样,在SCL为高电平的情况下,是数据线SDA由低电平跳至高电平,即有一个正条边沿。此时,标志通信结束。

例程:

/************************************
函数名:IIC_Wait_Ack
描述  :主机等待从机的应答
输入  :无
输出  :u8   0/1(0:应答成功,1:应答失败)
备注  :
***********************************/
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0; //应答计数器  
SDA_IN();               //SDA设置为输入  
IIC_SDA=1;            //SDA置高
delay_us(1);                         //可靠延时
IIC_SCL=1; //拉低SCL
delay_us(1);         //可靠延时
while(READ_SDA)//当:检测到SDA为高电平1时,循环计数
{
ucErrTime++;
if(ucErrTime>250)

//SDA高电平时间大于250时,应答失败,主机主动发送通信停止信号,停止此次通信,并且返回从机应答失败标志1
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0; //SDA高电平时间不大于250时,从机完成应答后,拉低SCL,并且返回从机应答成功标志位0   
return 0;  

/************************************
函数名:IIC_Ack
描述  :Ack应答
输入  :无
输出  :无
备注  :主机拉低SDA来应答从机 或 从机拉低SDA来应答主机
***********************************/
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/************************************
函数名:IIC_NAck
描述  :non ack应答
输入  :无
输出  :无
备注  :主机置高SDA来应答从机 或 从机置高SDA来应答主机
***********************************/    
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}

0 0
原创粉丝点击