基于I2C总线数据写入器的设计
1 引言
(Inter-Integrated Circuit)总线是一种用于连接微控制器及其外围设备的总线。总线最主要的优点是其简单和有效。由于接口直接在组件上,故其占用空间小,减少了电路板的空间和芯片引脚的数量,广泛用于智能化仪表。现在有的MCU已提供接口,但对于没有直接支持总线的MCU则需要用软件进行模拟。本文以AT89S52单片机为核心,与PC进行通信,实现具有总线的EEPROM AT24C04读写功能,构成一种数据写入器,用于仪器仪表等设备中表格、曲线和参数等的读写。所有程序用C语言完成。
2 单片机和PC两方的通信格式
本设计中的数据通信格式如下:第一字节为发给MCU的命令,第二字节保留。后16字节是所要写入的数据。但在开始操作时最先发送的仅为前2字节。命令有如下几种:写命令(CMD_WRITE)、读命令(CMD_READ)、操作结束命令(CMD_OVER)、状态检查命令(CMD_CHECKOK)。
两方的通信过程大致如下:PC发出前缀为CMD的命令,然后监听串口等待MCU返回的前缀为RSP的准备就绪的回应(写入时为 RSP_WRITEREADY;读出时为RSP_READREADY),若超时则给出错误提示;收到该回应后进行读写操作;结束时PC发出结束命令并等待 MCU的结束回应;若正确收到该回应则提示成功,否则提示操作完成但未收到回应。在写操作中,每发送18字节进行一次确认。另外,由于读芯片中是读出的所有内容,故此时PC不发结束命令而只等待结束回应。
在执行写操作时,PC都以CMD_WRITE为命令发送18字节的数据并等待MCU的RSP_WRITTEN。在执行读操作时,PC先接受MCU发来的以 RSP_READ为回应的18字节数据,然后再发送1个字节的命令CMD_READ。
3 I2C总线时序模拟
本设计使用的EEPROM为AT24C04,它可用串行总线。由于89S52不直接支持总线,因此只能使用IO口来模拟的总线时序。89S52可以进行位寻址,这给时序模拟带来了方便。
(1) 通信开始信号
根据的规程,通信开始信号是当SCL(串行时钟信号)处于高电平时在SDA(串行数据信号)上给出一个下跳沿,且下跳沿后,SCL还要维持高电平4μs。此过程可用如下代码模拟:
_SDA=1;
_SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_SDA=0; // 下跳沿
_nop_();
_nop_();
_nop_();
_nop_(); // 维持SCL为高电平4us
_SCL=0;
(2) 通信停止信号
通信停止信号是当SCL为高电平时在SDA上出现一个上跳沿,且SDA上跳前的低电平应维持4us以上。此过程模拟代码和开始信号类似,在此省略。
(3) 字节传送完毕确认信号
该信号是在SDA为低电平时SCL上出现一个正脉冲,此过程可用如下代码模拟:
_SDA=0;
_SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_SCL=0;
_SDA=1;
(4) 非确认信号
该信号便于控方传送停止信号,在SDA为高电平时,SCL上出现一个正脉冲,除此,模拟代码和字节传送完毕确认信号类似,不再赘述。
利用上述基本操作,并根据AT24C04的时序关系,可以写出对AT24C04进行读写的程序。由于AT24C04中的缓存是16字节,因此在读写时,均是以16字节为单位的。AT24C04总大小为512字节,其中又分了两页,在操作时还应同时指定要操作的页。
4 MCU方的通信
进入读、写函数后,MCU都要回应PC方发来的命令,以确认准备就绪,所以在读写程序中,并不立即对EEPROM操作。数据写读的流程图如图1和图2所示。其中RSP_WRITEREADY为对写入准备好的回应,RSP_READREADY为对读出准备好的回应,RSP_READ为成功读出一段数据的回应,RSP_FIN为操作完成的回应。
5 PC方的串行通信
PC方的串行通信使用类CSerialComm来完成。在PC上完成串行通信可用微软的MSComm通信控件,但这样就需要带上封装这个控件的库文件,否则程序不能独立运行。因此本设计采用以Win32 API写成的CSerialComm类来完成。
CSerialComm类继承自CIoController,封装了和串行通信相关的功能。主要成员函数功能如下:
Open:打开指定的端口。参数指定了所要打开的端口名称,为一个字符串。这个函数打开的串口是同步的。
SetState:设置串口的状态。参数是一个CSerialState类的指针。
SetTimeout:设置操作的超时时间,超过了这个时间,读写操作将返回。
CSerialComm类只提供基本的串口操作,而且不能发送窗口消息,不便于编写Windows的基于消息的程序,因此,从CSerialComm继承一个类CI2CWriter进一步封装对串口的操作,主要成员函数功能如下:
InitPort:调用了CSerialComm的Open函数来打开一个串口,并保留拥有这类对象的窗口指针,以便发送消息。
Notify:向窗口消息,以通知当前的读写状态。
BeginWrite,BeginRead,BeginVerify,BeginCheckMCU:分别为开始写、读、校验和检测MCU的状态。它们将产生相应的工作线程。
OpenFile:这个函数用于打开要写入到EEPROM中的文件。参数是所要写入的文件的路径名。由于AT24C04的容量是512字节,故该函数对文件的长度作了限制。
- 如何看懂时序图?(06-08)
- Freescale HCS12系列MCU的通用编程器设计(04-23)
- 2051对X25045的写入和读出汇编程序(10-12)
- ATmega16L-EEPROM写入读取实验(08-18)
- 拥有快速写入和超高集成性能的下一代数据存储解决方案(03-13)
- MSP430单片机串行写入BOOTSTRAP与加密熔断功能(12-10)