复习IIC协议---以AT24C02为例
1.总纲--复习IIC(inter integrated circuit)协议以及自己顺便读一下数据手册。
/*************************************************************************************/
1.1IIC协议的总结
1.2AT24C02的数据手册的阅读
1.3AT24C02关键部分的摘抄,以及IIC协议的引入及使用
1.4关键代码的编写,以及AT24C02的上层协议。
/*************************************************************************************/
1.1IIC协议
1.1.1、首先IIC协议分为物理层(四线结构)和协议层(主机,从机,时钟极性,时钟相位)。在多主机的系统中,如果有多个主机
只要求两条总线线路,一条是串行数据线SDA,一条是串行时钟线SCL, (IIC是半双工而不是全双工)
两根线经过上拉电阻上拉之VCC,所以总线在空闲的状态下都是高电平。
注意:IIC协议:在SCL的高电平周期内,SDA线上的数据必须保持稳定(因为在SCL为高电平时,SDA如果有跳变就会被认为起始信号或者终止信号),数据线SDA仅可以在时钟SCL为低电平时改变。这一点可以参考时序图看出。
1.1.2、起始信号:SCL为高时 SDA是由高电平向低电平变化。
1.1.3、终止信号:SCL为高时 SDA为由低电平向高电平变化。
1.1.4、应答信号:每当主机向从机发送8bit数据时第九个时钟周期,从机需要给出一个低电平表示应答,
1.1.4、发送寻址信号。
数据帧格式:
有应答与非应答,
分为地址信息 和 数据信息,地址8bit--- 7位表示从机地址 第8位表示读还是写。
数据则按照数据手册的时序图来编写。
具体编写代码时:
要注意是从高位到低位,还是从低位到高位传输数据。一样采用移位位与/位或的方式。
1.2AT24C02的数据手册的阅读
概括性知识:首先阅读一外设芯片的数据手册时,要大致这个芯片的作用是什么?然后要知道这款芯片对外的接口是什么?
(是标准的协议比如SPI、IIC或其他标准协议又或者是该芯片的自定义的时序图通信协议比如ds18B20单总线协议、LCD的驱动都是自定义的协议)。然后就是熟读该芯片的数据手册熟悉他的结构及寄存器,这样才能更了解该芯片的使用功能。
在这里先get一下重点:一般芯片的数据手册中比较重要(也是相通的地方)的地方:一般开头都是:概括,特性,封装
然后最重要的是 interface,然后就是按照他的上层协议得到相应的数据。
那么接下来介绍如何读24c02芯片的数据手册。
按照我们上边的分析来看,这是一个内存(flash)芯片,说白了就是存储数据,如何将数据写入存储,在需要的时候将数据读出使用。先把准一个大方向。
首先是特性,然后就是封装,引脚介绍, 当然我们通过其引脚判断 SDA、SCL、VCC、GND.我们就知道该芯片是通过IIC总线协议来通信的,具体我们可以先写IIC底层时序。(这次之前先要初始化GPIO,主要是SDA、SCL这两个引脚)这里把属于IIC的底层时序,写到这里(为了和AT24C02的上层时序写在一起)
启动、终止、应答、写一个字节、读一个字节,
1.2.1启动代码&&终止代码
在初始化gpio引脚后,将SCL和SDA拉高。让总线处于空闲状态。
1 void IIC_Start()
2 {
3 SCL=1;
4 SDA=1;
5 Delay();
6 SDA=0;
7 Delay();
8 SCL= 0; //这里将SCL线拉低,钳住SCL,已经准备好发送或接受数据。也就是说每次Start信号后,SCL是被拉低的。
9 }
10 void IIC_End()
11 {
12 SCL=0;
13 SDA=0;
14 Delay();
15 SCL=1;
16 Delay();
17 SDA=1;
18 Delay();
19 }
起始信号产生后总线处于被占用的状态,在终止信号产生后总线处于空闲状态。然后起始信号的终止信号都是由主机发出的。
1.2.2、IIC总线的数据传输
IIC数据传输:这里说的数据起始也包括地址数据和真正传输的数据,
然后发送一个字节的数据。
void Send_Byte(char data)
{
char a=0;
SCL=0; //先将SCL时钟线拉低
//MSB (the Most Significant Bit) 高位在前
for(a=0;a<8;a++)
{
SDA=(data&0x80)>>7
data=data<<1;
Delay();
SCL=1;
Delay();
SCL=0;
Delay(); //具体延时时间数据手册中的时序图中具体有写。
}
}
应答信号:即就是在等待从机是否将SDA拉低。但是如果没有等到该信号的到来,我们软件的设计需要足够灵活,不能死等下去导致系统死机,如果没有看门狗就会真正的挂掉的,所以设置一个变量我们只需要等待一定的时间认定这次数据不对,接着再读。
// 返回1的话 成功应答 返回0 没有应答。
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); // 将SDA 数据线设置为输入
SDA=1;delay_us(1);
SCL=1;delay_us(1);
while(READ_SDA) //判断 SDA数据线是否为低,也就是是否应答。
{
ucErrTime++;
if(ucErrTime>250) // 软件设置超时时间
{
IIC_Stop();
,return 1; } } SCL=0; return 0; }
读出一个字节的数据:根据IIC底层时序图。
char IIC_read_Byte()
{ char receive=0,a=0; SCL=0; //将SCL拉低,,在读数据之前,需要将io设置为输入模式
for(a=0;a<8;a++) { receive<<1; SCL=0; Delay(); SCL=1; Delay(); if(SDA) receive|=0X01; }
// 要添加应答信号,也就是说在第九个时钟周期,SDA是否为低电平。
// 具体看协议中是否规定了要求应答信号。如果有那么就要加上,如果无则不需要应答信号。
return receive;
}
数据手册中的接口协议(也就是基于IIC底层的上层的协议)
往AT24C02中的写入一个字节:(当然还有页写这里就以字节写为例)
往24c02中读出一个字节(当然还有页读这里以当前地址读为例):
从器件的地址 :
在起始信号后必须发一个从机的地址(7bit(地址信息)+1bit(R/W)( 写低电平有效 ))
E:\STM32\自己的总结回顾\各种总线知识汇总\iic-------文件夹中的iic、spi总线的ppt;
从AT24c02中一个地址中写入一个字节
//这是基于AT24C02数据手册也就是上边的数据帧格式(具体代码)
void Wirte_Byte(unsigned char addr,char date) //我们默认该内存芯片的只有 256 Byte {
IIC_Start(); // 起始信号 该函数结束时 SCL=0;
Send_Byte(0XA0); // 发送从机地址,该函数刚开始时,SCL=0; 产生8个时钟周期后, SCL=0了。
IIC_Wait_Ack(); // ack的时候,首先将SDA设置成输入模式,SCL=1(第九个时钟周期的高电平),接下来等SDA是否为低电平,不管SDA是否
//为低电平,最后等待一定时间后,SCL最终就会拉低,(第九个时钟周期结束)。
Send_Byte(addr);
IIC_Wait_Ack();
Send_Byte(date);
IIC_Wait_Ack(); // 与上边次开始两行是一样的。最后 SCL=0;
TTC_End(); // 在SCL线为高时,SDA线产生下降沿。
}