10.1 IIC简介
10.1.1 IIC总线概述
I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。I2C总线通过上拉电阻接正电源。当总线空闲时,两根线均为高电平。连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。每个接到I2C总线上的器件都有唯一的地址。主机与其它器件间的数据传送可以是由主机发送数据到其它器件,这时主机即为发送器。由总线上接收数据的器件则为接收器。在多主机系统中,可能同时有几个主机企图启动总线传送数据。为了避免混乱,I2C总线要通过总线仲裁,以决定由哪一台主机控制总线。
10.1.2 IIC总线时序
(1)数据有效性
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
(2)开始时序与停止时序
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。连接到I2C总线上的器件,若具有I2C总线的硬件接口,则很容易检测到起始和终止信号。接收器件收到一个完整的数据字节后,有可能需要完成一些其它工作,如处理内部中断服务等,可能无法立刻接收下一个字节,这时接收器件可以将SCL线拉成低电平,从而使主机处于等待状态。直到接收器件准备好接收下一个字节时,再释放SCL线使之为高电平,从而使数据传送可以继续进行。
(3)字节传送与应答
每一个字节必须保证是8位长度。数据传送时,先传送最高位,每一个被传送的字节后面都必须跟随一位应答位。由于某种原因从机不对主机寻址信号应答时(如从机正在进行实时性的处理工作而无法接收总线上的数据),它必须将数据线置于高电平,而由主机产生一个终止信号以结束总线的数据传送。如果从机对主机进行了应答,但在数据传送一段时间后无法继续接收更多的数据时,从机可以通过对无法接收的第一个数据字节的“非应答”通知主机,主机则应发出终止信号以结束数据的继续传送。当主机接收数据时,它收到最后一个数据字节后,必须向从机发出一个结束传送的信号。这个信号是由对从机的“非应答”来实现的。然后,从机释放SDA线,允许主机产生终止信号。
10.2 AT24C02简介
10.2.1 简介
AT24CXX系列的存储芯片是串行E2PROM典型产品,AT24C系列E2PROM芯片地址的固定部分为1010,A2,A1,A0引脚接高、低电平后得到确定的3位编码。形成的7位编码即为该器件的地址码。
AT24CXX系列存储芯片上的XX代表存储的二进制位的个数,以最常见的AT24C02为例,该芯片的存储二进制位的个数为2K个,换算到实际的字节地址范围就是0~255,因为2048/8=256,存储容量就是256个字节。
AT24C02的引脚排列如下图所示。
引脚编号 |
英文缩写 |
引脚功能 |
1~3 |
A0~A2 |
地址选择端 |
4 |
GND |
数字地 |
5 |
SDA |
IIC数据端 |
6 |
SCL |
IIC时钟端 |
7 |
WP |
写保护,高电平有效 |
8 |
VDD |
电源(+1.8V~5.5V) |
10.2.2 通信协议
(1)器件地址
芯片型号 |
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
24C02/32/64 |
1 |
0 |
1 |
0 |
A2 |
A1 |
A0 |
R/W |
24C04 |
1 |
0 |
1 |
0 |
A2 |
A1 |
P0 |
R/W |
24C08 |
1 |
0 |
1 |
0 |
A2 |
P1 |
P0 |
R/W |
24C16 |
1 |
0 |
1 |
0 |
P2 |
P1 |
P0 |
R/W |
A0~A2:与硬件的A2~A0相对应,用于确定芯片的地址
P0~P2:用于选择芯片内部的页地址,AT24C系列页地址从0~255
(2)写入1个字节
(3)读取1个字节
10.3 例程分析
10.3.1 原理图
10.3.2 源代码
(1)IIC底层协议
(2)AT24C02读写时序
10.4完整代码
/********************************************************************************************************* 头 文 件 引 用*********************************************************************************************************/#include //导入51单片机头文件#include /********************************************************************************************************* 数 据 类 型 定 义*********************************************************************************************************/#define u8 unsigned char //定义无符号字符型数据(0~255)#define u16 unsigned int //定义无符号整型数据(0~65535)/********************************************************************************************************* 端 口 定 义*********************************************************************************************************/sbit SCL = P2^0 ; //时钟线sbit SDA = P2^1 ; //数据线/********************************************************Name :delay_usFunction :微秒级别延时函数Paramater : us:延时的ms数Return :None********************************************************/void delay_us( u16 us ){
while( us-- ) ;}/********************************************************Name :IIC_InitFunction :IIC总线初始化Paramater :NoneReturn :None********************************************************/void IIC_Init(){
SDA = 1 ; SCL = 1 ;}/********************************************************Name :IIC_StartFunction :开始时序Paramater :NoneReturn :None********************************************************/void IIC_Start(){
SDA = 1 ; //数据拉高 SCL = 1 ; //时钟拉高 delay_us( 80 ) ; SDA = 0 ; //数据拉低 delay_us( 80 ) ; SCL = 0 ; //时钟拉低}/********************************************************Name :IIC_StopFunction :停止时序Paramater :NoneReturn :None********************************************************/void IIC_Stop(){
SCL = 0 ; //时钟拉低 SDA = 0 ; //数据拉低 delay_us( 80 ) ; SCL = 1 ; //时钟拉高 SDA = 1 ; //数据拉高 delay_us( 80 ) ;}/********************************************************Name :IIC_AckFunction :应答时序Paramater :NoneReturn :None********************************************************/void IIC_Ack(){
u8 Time ; SDA = 1 ; //数据线拉高 delay_us( 80 ) ; SCL = 1 ; //时钟拉高 delay_us( 80 ) ; Time = 0 ; while( SDA ) //等待从机应答 {
Time ++ ; if( Time>250 ) break ; //超时退出 } SCL = 0 ; //时钟拉低}/********************************************************Name :IIC_Write_ByteFunction :发送1个字节Paramater : Byte:写入的字节Return :None********************************************************/void IIC_Write_Byte( u8 Byte ){
u8 i ; SCL = 0 ; //时钟拉低 for( i=0; i<8; i++ ) {
if( ( Byte&0x80 )==0x80 ) SDA = 1 ; else SDA = 0 ; Byte <<= 1 ; //数据向左位移 delay_us( 80 ) ; SCL = 1 ; //时钟拉高 delay_us( 80 ) ; SCL = 0 ; //时钟拉低 delay_us( 80 ) ; }}/********************************************************Name :IIC_Read_ByteFunction :读取1个字节Paramater :NoneReturn :读取的字节********************************************************/u8 IIC_Read_Byte( u8 Ack ){
u8 i, Byte; for( i=0; i<8; i++ ) {
SCL = 0 ; //时钟拉低 delay_us( 80 ) ; SCL = 1 ; //时钟拉高 Byte <<= 1 ; if( SDA ) Byte |= 0x01 ; delay_us( 80 ) ; } SCL = 0 ; SDA = 1 - Ack ; delay_us( 80 ) ; SCL = 1 ; delay_us( 80 ) ; SCL = 0 ; return Byte ;}/********************************************************Name :AT24CXX_Write_DataFunction :按地址写数据Paramater : Address:地址 Byte:数据Return :None********************************************************/void AT24CXX_Write_Data( u8 Address , u8 Byte ){
IIC_Start() ; //开始 IIC_Write_Byte( 0xA0 ) ; //确认地址 IIC_Ack() ; //应答 IIC_Write_Byte( Address ) ; //写入地址 IIC_Ack() ; //应答 IIC_Write_Byte( Byte ) ; //写入数据 IIC_Ack() ; //应答 IIC_Stop() ; //停止}/********************************************************Name :AT24CXX_Read_DataFunction :按地址读数据Paramater : Address:地址Return :读取的数据********************************************************/u8 AT24CXX_Read_Data( u8 Address ){
u8 Byte ; IIC_Start() ; //开始 IIC_Write_Byte( 0xA0 ) ; //确认地址 IIC_Ack() ; //应答 IIC_Write_Byte( Address ) ; //写入地址 IIC_Ack() ; //应答 IIC_Start() ; //开始 IIC_Write_Byte( 0xA1 ) ; //确认地址 IIC_Ack() ; //应答 Byte = IIC_Read_Byte( 0 ) ; //读取数据 IIC_Stop() ; //停止 return Byte ;}/********************************************************************************************************* 主 函 数*********************************************************************************************************/void main(){
IIC_Init() ; AT24CXX_Write_Data( 0, 0x23 ) ; //地址0的位置写入23 H P1 = AT24CXX_Read_Data( 0 ) ; //读取地址0的数据 while( 1 ) {
}}
今天的文章51单片机基本刷屏测试实验_51单片机开发基础10——IIC协议实验分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/82364.html