当前位置:文档之家› C51串I2C总线共14页

C51串I2C总线共14页

C51串I2C总线共14页
C51串I2C总线共14页

I2C总线是Philips公司最先推出的一种双向数据传输总线,其仅使用两根连线便可以实现全双工同步数据传送。在I2C 总线中,一条为串行数据线(SDA),另一条为一条串行时钟线(SCL)。I2C总线占用引脚少,接口协议简单。目前多数公司均推出了I2C总线接口的各种器件,如存储器、A/D、D/A、键盘、LCD等,大大方便了用户的选择。

本章主要介绍了I2C总线的工作原理、寻址方式以及数据操作,并重点介绍了数据传输协议以及相应的C51子函数。最后通过具体的实例,介绍如何使用在没有I2C总线接口的单片机上读写具有I2C总线接口的E2PROM存储器。

1 I2C总线概述

I2C总线采用两线制,由数据线SDA和时钟线SCL构成。I2C 总线对数据通信进行了严格的定义。

1.1 I2C总线工作原理

典型的I2C总线系统结构,如图所示。I2C总线上可以挂接多个器件,其中每个器件必须都支持I2C总线通信协议。

1.2 I2C总线器件的寻址方式

由于所有器件都通过SCL和SDA连接在I2C总线上,因此,主器件在进行数据传输前需要通过寻址,选择需要通信的从器件。I2C总线上所有外围器件都需要有唯一的7位地址,由器件地址和引脚地址两部分组成。

器件地址是I2C器件固有的地址编码,器件出厂时就已经给

定,不可更改。

引脚地址是由I2C总线外围器件的地址引脚(A2,A1,A0)决定,根据其在电路中接电源正极、接地或悬空的不同,形

成不同的地址代码。

1.3 I2C总线数据操作

在I2C总线上,数据是伴随着时钟脉冲,一位一位地传送的,数据位由低到高传送,每位数据占一个时钟脉冲。I2C总线上的在时钟线SCL高电平期间,数据线SDA的状态就表示要传送的数据,高电平为数据1,低电平为数据0。在数据传送时,SDA上数据的改变在时钟线为低电平时完成,而SCL 为高电平时,SDA必须保持稳定,否则SDA上的变化会被当作起始或终止信号而致使数据传输停止。

1.写数据格式

2.读数据格式

2 I2C总线接口EEPROM存储器

目前,市场上I2C总线接口器件有多种,例如A/D转换器、

D/A转换器、时钟芯片和存储器等。这里以典型的I2C总线

接口的存储器为例进行介绍。

I2C总线接口EEPROM存储器是一种采用I2C总线接口的串行总线存储器,这类存储器具有体积小、引脚少、功耗低、工作电压范围宽等特点。目前,Atmel、MicroChip、National 等公司均提供各种型号的I2C总线接口的串行EEPROM存储器。在单片机系统中使用较多的EEPROM存储器是24系列串行EEPROM。其具有型号多、容量大、支持I2C总线协议、占用单片机I/O端口少,芯片扩展方便、读写简单等优点。

3 C51模拟 I2C总线协议

在实际应用中,往往遇到所使用的单片机没有I2C总线接口,例如典型的 51系列单片机。为了让此类单片机用于操作I2C 总线器件的能力,往往需要在程序模拟I2C总线数据传输协

议。

这里以典型的51系列单片机为例,假设其外接6MHz的晶振,采用P1.0作为时钟线SCL,P1.1作为数据线SDA。在C51语言的程序中,首先需要声明SCL和SDA所使用的引脚。其声

明如下所示:

sbit SCL=P1^0;

sbit SDA=P1^1;

3.1 延时子函数

这里给出一个典型的延时子函数。当单片机的工作频率比较高的时候,为了保证I2C总线的传输速率满足100kHz或者400kHz的限制,可以进行适当的延时处理。用户可以根据需要使用。延时子函数的程序示例如下:

void Delays(unsigned int

number) //延时子程序

{

unsigned char temp;

for(;number!=0;number--) //循环

{

for(temp=0;temp<100;temp++) //空循环

{

}

}

}

3.2 起始信号子函数

起始信号子函数用于开始I2C总线通信。其中,起始信号是在时钟线SCL为高电平期间,数据线SDA上高电平向低电平变化的下降沿信号。起始信号出现以后,才可以进行后续的I2C总线寻址或数据传输等。起始信号的时序,如图所示。

序。起始信号子函数示例如下:

void

StartI2C()

//起始信号子程序

{

SDA=1;

Delays(1);

//延时,用于满足传输速率要求

SCL=1;

Delays(1);

SDA=0;

Delays(1);

SCL=0;

Delays(1);

}

3.3 终止信号子函数

终止信号子函数用于终止I2C总线通信。其中,终止信号是在时钟线SCL为高电平期间,数据线SDA上低电平到高电平变化的上升沿信号。终止信号一出现,所有I2C总线操作都结束,并释放总线控制权。终止信号的时序,如图所示。在

终止信号子函数示例如下:

3.4 应答信号子函数

应答信号子函数用于表明I2C总线数据传输的结束。I2C总线数据传送时,一个字节数据传送完毕后都必须由主器件产生应答信号。主器件在第9个时钟位上释放数据总线SDA,使其处于高电平状态,此时从器件输出低电平拉低数据总线SDA为应答信号。应答信号的时序,如图所示。在程序中,可以直接为SDA和SCL赋值来实现应答信号的时序。应答信

号子函数示例如下:

void

AckI2C()

//发送应答位子程序

{

SDA=0;

Delays(1);

SCL=1;

Delays(1);

SCL=0;

Delays(1);

SDA=1;

Delays(1);

}

3.5 非应答信号子函数

非应答信号子函数用于数据传输出现异常而无法完成时。在一个字节数据传送完毕后,在第9个时钟位上从器件输出高电平为非应答信号。非应答信号的产生有两种情况。

当从器件正在进行其他处理而无法接收总线上的数据时,从器件不产生应答,此时从器件释放总线,将数据线SDA置为高电平。这样,主器件可产生一个停止信号来终止总线数据

传输。

当主器件接收来自从器件的数据时,接收到最后一个数据字节后,必须给从器件发送一个非应答信号,使从器件释放数据总线。这样,主器件才可以发送停止信号,从而终止数据

传送。

3.6 应答位检查子函数

应答位检查子函数用于主器件检测接收的是否为正常的应答信号,以便于判断数据接收是否正常。程序中定义了ErrorBit作为应答检查位,用于数据线SDA上的应答位检查结果,最后通过return语句返回该值。应答位检查子函数

示例如下:

bit

TestAckI2C()

//应答位检查子程序

{

bit ErrorBit;

SDA=1;

Delays(1);

SCL=1;

Delays(1);

ErrorBit=SDA;

//读入SDA上的应答状态

Delays(1);

SCL=0;

Delays(1);

return(ErrorBit);

//返回应答状态,0为应答信号,1为非

应答信号

}

3.7 单字节写子函数

单字节写子函数用于向从器件写入单个字节的数据。程序中,可以通过for循环语句,逐位将数据发送到I2C数据总

线上。该函数在使用之前,必须先使用起始信号子函数启动I2C总线数据传输。单字节写子函数的流程图,如图16.7所示。单字节写子函数示例如下:

bit Write8BitI2C(unsigned char

input) // input为待发送的数据

{

unsigned char temp;

for(temp=8;temp!=0;temp--)

//循环移位,逐位发送数据

{

SDA=(bit)(input&0x80);

//取数据的最高位

Delays(1);

SCL=1;

Delays(1);

SCL=0;

Delays(1);

input=input<<1;

//左移一位

}

return 1;

}

3.8 单字节读子函数

单字节读子函数用于从I2C数据总线读入单个字节的数据。程序中,可以通过for循环语句,逐位将数据读入。该函数在使用之前,同样需要先使用起始信号子函数启动I2C总线数据传输。单字节读子函数的流程图,如图所示。单字节读

子函数示例如下:

3.9 多字节写子函数

多字节写子函数用于主器件发送多个字节的数据。首先发送起始位,接着是寻址字节,然后是数据的所要存入单元的首地址,外围器件此时产生正确的应答后,主器件便将开始多个字节的数据传输。多字节写子函数的流程图,如图所示。

多字节写子函数示例如下:

3.10 多字节读子函数

多字节读子函数用于主器件从SDA线上读取多个字节的数据。在读多个字节的操作中,除了发送寻址字节外,还要发送器件的子地址。因此,在读多个字节操作前,要进行一个字节的写操作,然后重新开始读操作,将从器件内的字节数据读出。多字节写读函数的流程图,如图16.10所示。多字

节写读函数示例如下:

4 C51读写EEPROM实例

I2C总线接口器件以体积小,占用引脚少,接口简单,读写操作方便等优点而得到广泛的应用。目前Philips、Atmel、Maxim以及其他集成电路制造商推出了很多基于I2C总线的单片机和外围器件,如24系列E2PROM、串行实时时钟芯片DS1302、USB2.0芯片CY7C68013A等。

这里以普通的51系列单片机为例,通过实例介绍如何使用C51模拟I2C总线接口来读写I2C总线的EEPROM存储器。

4.1 电路设计

这里给出单片机AT89S51读写I2C总线接口的AT24C08存储器的电路原理图图,该电路图中所使用的元器件的参数及数

量,如表所示。

4.2 程序设计

这里采用C51语言在Keil μVison3集成开发环境中编写程

序。

本程序的功能是利用单片机的P1.0、P1.1作为I2C串行总线的SCL、SDA接口,向AT24C08写入10个字节的数据,然后再将写入的数据读出,并比较读写的数据是否完全一致。如果数据的读写一致,则点亮LED,表示写入正确;否则熄

灭LED报警。

4.3 仿真分析

为了加深对I2C串行总线协议的理解,可以在Keil μVison3

集成开发环境中对整个程序进行仿真。通过信号仿真,可以查看I2C总线中起始信号、终止信号以及数据读写的时序。

具体操作步骤如下:

5 小结

本章首先介绍了I2C串行总线的工作原理、寻址方式以及总线数据的读写操作等,并对常用的I2C串行总线接口的EEPROM存储器进行了介绍。接着,本章详细介绍了I2C串行总线的协议,以及采用C51语言模拟读写I2C串行总线的子函数。最后通过一个具体的实例,讲解了51系列单片机读写I2C总线外围器件的电路设计以及程序设计。I2C串行总线具有接口简单、引脚少、体积小等优点,在实际电路设计

中经常使用。

阅读(1554) | 评论(1) | 转发(0) |

上一篇:编译内核(Compile the Kernel)

下一篇:_IO,_IOR,_IOW和_IORW的含义

相关热门文章

?内存模拟块设备中mount /dev/r...

?刀具发展快,对【金刚石刀具磨...?传感器模拟考试答案

?合理使用U盘的6大妙方...?CATTI考试笔译综合能力模拟试...?linux 常见服务端口

?【ROOTFS搭建】busybox的httpd...?xmanager 2.0 for linux配置

?什么是shell

?linux socket的bug??

?curl: (56) Recv failure: Con...?CACTI 不能安装WINE,怎么办?...?kernel 报错l701.exel[16922]:...?C语言如何在一个整型左边补0...?python无法爬取阿里巴巴的数据...

给主人留下些什么吧!~~

gongxijie2014-01-16 11:46:51

你这个没写完啊,模拟之后和一般硬件实现的I2C性能对比如何呢,一般都会有性能的降低,有多大差距呢?希望以上资料对你有所帮助,附励志名言3条:

1、宁可辛苦一阵子,不要苦一辈子。

2、为成功找方法,不为失败找借口。

3、蔚蓝的天空虽然美丽,经常风云莫测的人却是起落无从。但他往往会成为风云人物,因为他经得起大风大浪的考验。

相关主题
文本预览
相关文档 最新文档