上的地址进行比较, 如果发生匹配, 该器件人为被主器件寻址, 接收或发送由 R/W 位决定。 器件的地址由固定部分和可编程部分组成, 如PCF8583地址固定部分(A6~A1)为101000B, 有一位可编程位A0, 则系统中可有两片PCF8583, 它们通过A0编址的不同来区别。 我们系统中A0接低电平, 所以读PCF8583时第一字节为A1H, 写时则为A0H。
(5) 定时:
I2C总线上最小低电平为4.7μs, 最小高电平为4μs, 主器
件产生的时钟频率为0~100kHz。
§5.2 软件模拟 I2C的实现
飞利浦公司生产的具有I2C总线接口的外围芯片种类十分繁多,其.性能和操作要求也多种多样, 这里我们主要以PCF8583 为例介绍一下.如何用软件模拟的方法来实现没有I2C接口的主处理器和只靠I2C接口和外部联系的具有RAM 特性的外围器件之间的有效通讯, 且将它们统称为外部RAM器件。
根据I2C总线规约可知, 软件模拟I2C通讯的大体流程可划分如下:
(1) 向外部RAM里写入:
*1* 发开始信号; ( SCL为高时, SDA由高到低跳变) *2* 发从器件地址(7 个Bit)和R/W( 0为写入 )位; *3* 检测等待外部RAM器件的应答信号ACK; *4* 发送字地址( 即RAM 单元的地址);
*5* 检测等待外部RAM器件的应答信号ACK; *6* 发送数据
.1. 发送一个数据字节;
.2. 检测等待外部RAM器件的应答信号ACK; .3. 是最后一个字节吗?
是, 则转到*7*; 否则, 转到.1.
*7* 发送结束信号; (SCL为高时,SDA由低到高跳变)
(2) 从外部RAM里读出:
*1* 发开始信号; ( SCL为高时, SDA由高到低跳变) *2* 发从器件地址(7 个Bit)和R/W( 0为写入 )位; *3* 检测等待外部RAM器件的应答信号ACK; *4* 发送字地址( 即RAM 单元的地址);
*5* 检测等待外部RAM器件的应答信号ACK; *6* 发开始信号; ( SCL为高时, SDA由高到低跳变) *7* 发从器件地址(7 个Bit)和R/W( 1为读出 )位; *8* 检测等待外部RAM器件的应答信号ACK; *9* 发送数据
.1. 发送一个数据字节; .2. 是最后一个字节吗?
是, 则转到 .5. ; 否则,执行 .3.
.3. 主器件(如本例中的 8951)发应答信号ACK,即在一个时钟周期内SCL为高时拉低SDA电平; .4. 转 .1.
.5. 主器件不响应,
即在一个时钟周期内SCL为高时保持SDA为高电平;( 从器件检测到这个高电平的下一个时钟周期放弃SDA线, 以使主器件能产生结束信号)
.6. 转*10* ;
*10* 发送结束信号; (SCL为高时,SDA由低到高跳变) 有关的详细说明请参考附录的软件文档。
这里有很关键的一点就是要严格保证, 在一次传送开始后和结束前数据线SDA 在时钟线为高时不能发生变化( 因为I2C 规约将之定义为开始或结束信号), 否则将会导致传送的非常结束。 只要满足I2C规约的
时序定义, SCL的低电平时间可以根据需要适当延长。
软件在给以实现时, 可考虑使用一个定时/计数器来实现I2C对时序的要求。 这样软件可以在I2C通讯的同时执行其它的操作。其不足是软件编制较为复杂, 较易出错。 还可考虑全由软件来满足时序要求, 靠调整指令安排顺序来实现, 包括加入一些 NOP指令。这样的不足是要占处理器的全部时间, 很难再插入其它操作。而且还要考虑中断可能造成的影响。本系统是采用纯软件方法实现时序要求的, 对中断的处理是采用全屏蔽的方法, 在一次通讯开始就关闭所有的中断, 结束时将之重新打开。由于一次通讯耗时极短,实验证明对中断的响应基本上没有影响 (读/写一个字节耗时不到 0.2ms, 读/写完成后立即开中断。而电能脉冲中断最快也只有每隔250ms有一次, ?所以不会造成中断信号丢失 )。 另外一种处理方法是不屏蔽中断, 但进入中断后不马上进行中断处理, 而是先等待 SCL为低再开始中断处理, 并在中断处理过程中始终保持SCL为低即可。 这一方法适于在中断不宜屏蔽的系统中使用。
§5.3 出现的问题及其解决
在程序的调试过程中, 发现所编制的I2C通讯程序工作不正常,具体表现是
如果一次传送大批量数据, 则会有前几个数据正确, 而后面的读出错误或者读出几个字节后死机的可能, 但如果每次只读写一个字节则可保证正确。 经过对程序的反复检查, 发现可能问题出在指令的安排不能满足 I2C规约对时序的要求。于是, 程序调整了对SDA 和SCL操作的指令的时序, 把在SDA线上输出一位\或\的功能由一个子程序完成改变为直接语句输出, 使得该操作与启/停信号和ACK信号的时序取得一致,并减少了子程序调用的开销和可能因此带来的错误。并在写SCL线和写SDA线的指令之间加入了一条NOP指令, 以调整时序。重新编译之后, 问题果然得到解决。
最初的程序还有一个不令人满意的地方就是通讯速度太慢, 有些地方大量
数据传送时可以看到明显的滞留, 影响到显示的效果, 而且, 这还给掉电时
通过 I2C通讯保存数据带来一定的困难。在上面所谈到的时序问题解决后, 尽可能减少了通讯子程序中的空等待, 而是调整指令次序以配合定时要求。结果将传送一个字节所需要的时间从2ms左右减少到 0.2ms, 从而使通讯速度得到了很大提高, 也保证了通讯的质量。
第六章 键处理
作为智能仪器的单片机系统主要通过键盘和外部有联系, 当然这里所说的
键盘通常是几个按钮组成或一个4×4的小键盘。为了完成较为复杂的操作, 常常要定义一系列键盘指令来实现各种不同的功能, 这样就会出现同一键在不同状态下按下具有不同的意义, 要想编制出高质量的键盘监控程序就要有一个科学的方法来指导, 这就是所谓键分析法。 下面结合这次设计的实践来给以讨论。
§6.1 键之功能安排
系统采用了七个按钮, 分别挂接在P2.0~P2.6上,平时为高电平, 按下时为
低电平, 定义如下:
键名 键值 对应89C51引脚 ——————————————————————
(1) 编程态