目录

一、单片机系统扩展
(一)单片机系统扩展的概念
8051单片机扩展外部存储器或I/O口采用总线分时复用方式
1、单片机系统扩展方式
单片机系统扩展方式一般有片内扩充、片外串行总线扩展和片外并行总线扩展。
片内扩充:重视单片机选型,根据不同的应用,选择不同性能的单片机芯片。
片外串行总线扩展:主要为了弥补片内资源不足,一般选择串口总线扩展。
片外并行总线扩展:通过单片机的三总线实现对外部并行器件的扩展连接。
2、单片机系统总线

(1)数据总线
数据总线用于在单片机与扩展的外部器件之间传输数据,是数据传输的通道,总线位数外8位。
(2)地址总线
地址总线用于单片机向外发出地址信号,选择要访问的外部扩展器件或存储单元,地址总线是单向总线,只能由单片机向外发出。
(3)控制总线
控制总线实际上市一组控制信号线,可以有单片机产生并发出,也可以有外部器件产生并传送给单片机,每个控制信号都是单向传送。
单片机扩展常用的控制信号如下:
ALE:地址锁存信号,用以实现对低8位地址的锁存。
PSEN:对片外程序存储器输出的取指令信号。
RD:对片外数据存储器或端口输出的读信号。
WR:对片外数据存储器或端口输出的写信号。
(二)单片机系统的的I/O端口扩展
输入/输出(I/O)端口是单片机与外部设备交换数据的桥梁。
1、I/O接口的分类
I/O接口分为串行I/O接口和并行I/O接口。
串行I/O接口采用逐行串行移位的方式传输数据,适用于速度要求不高的串行设备接口。
并行I/O接口采用并行方式传输数据,可以与外设高速传输数据。
2、I/O接口的功能
(1)数据传输速度匹配。
(2)输出数据锁存。
(3)输入数据三态缓冲。
(4)信号或电平变换。
3、I/O接口与端口的区别
I/O接口是CPU与外界的连接电路,是CPU与外界进行数据交换的通道,外设输入原始数据或状态信号,CPU输出运算结果或发出命令等都要通过I/O接口电路。
I/O端口是CPU与外设直接通信的地址,通常是把I/O接口电路中能够被CPU直接访问的寄存器或缓冲器为端口。
4、I/O端口编址
I/O端口编址有独立编址方式和统一编址方式。
5、单片机与外设间的数据传送方式
单片机与外设间的数据传送方式有同步、异步和中断三种方式。
(1)同步传送方式
采用同步传送方式,要求单片机与外设的速度相差不大,以实现同步无条件的数据传送。
(2)异步传送方式
由于单片机与外设的速度相差较大时,采用异步传送方式,以查询外设的状态进行有条件的传送数据。其通用性好。
(3)中断传送方式
中断传送方式是指利用单片机本身的中断功能实现数据传送。
二、串行总线的扩展应用
(一)IIC总线的基础
1、IIC总线的概述
IIC总线是飞利浦公司退出的芯片间串行数据传输总线,采用两线制实现全双工同步数据传送。

IIC总线有2根信号线,一根是数据线SDA,一根是时钟线SCL,且SDA和SCL均为双向信号线。
2、IIC总线的信号以及时序定义
(1)总线上数据的有效性
在IIC纵向上传输数据时,时钟线(SCL)为高电平期间,数据线(SDA)必须保持稳定是逻辑电平状态。其中只有在时钟信号为低电平期间,才允许数据线上的电平发生变化。
(2)数据传输的起始位和结束位。
IIC总线在传送数据过程中有三种类型信号,分别为起始信号、结束信号和应答信号。
起始信号:在时钟线(SCL)为高电平期间,数据线(SDA)出现有高电平向低电平跳变时,启动IIC总线,开始传送数据。 在起始信号之后,必须是器件的控制字节,即设备地址,其中高4位是对应器件件的类型识别符,紧接着3位是片选信号,最后1位是读写控制位,读操作为1,写操作为0。
结束信号:在时钟线(SCL)为高电平期间,数据线(SDA)出现有低电平向高电平跳变时,停止IIC总线,结束传送数据。
应答信号:当IIC总线传输数据时,每传送一字节数据后必须跟随等待一个应答信号,即接收器在接收在接收到一字节数据后,向传送器发出特定的低电平信号,表示已收数据。
3、 IIC总线协议
IIC总线协议规定,每次传送一个字节数据,都要有一个应答信号,以确定数据传送是否被对方收到。
三、IIC总线驱动程序设计
总线时序设计IIC接口的驱动成一般包括:起始信号、停止信号、产生应答、等待应答、发送数据和接收数据6个函数。
下面提供IIC总线确定程序(该程序为蓝桥杯官方提供的IIC总线驱动程序)
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线起始信号
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止信号
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
四、总结
在蓝桥杯单片机开发与设计大赛中,官方提供了IIC总线的底层驱动代码,但是参赛选手需要了解其IIC总线的原理和其底层驱动程序相关函数的功能,才能对其涉及到的PCF8591和24C02存储器编写对应的程序,进而实现相关的功能。