单片机基础总结
1.1单片机的基本概念
单片机是一种典型的嵌入式计算机,它把微型计算机中的微处理器、存储器、I/O接口、定时器/计数器、通信接口、中断系统等模块集成到一块芯片上,因而常被称为单片微型计算机,简称单片机。
单片机的英文叫法在国内有两种:
MCU : Micro-Controller Unite 微控制器
SCM : Single Chip Microcomputer 单片机
一个通用计算机系统应包含的基本部件:


基于传统电子技术和单片机设计的电路有什么区别?


基于单片机和数字逻辑芯片的电子系统的区別
- 传统数字电路设计方法是根据系统功能要求,通过组合各种独立的集成电路芯片,构成系统。系统一旦设计好后,功能需要修改时,需要重新设计电路;
- 基于微处理器设计方法中,设计相对通用的硬件电路,通过软件编程实现系统的逻辑关系。软件编程不仅能实现非常强大逻辑功能(几乎任何逻辑),设计难度也有所降低,而且当系统功能需要小范围修改时,硬件可以不改动,只需重新编写程序即可,这大大节约了经济成本和人工成本。
1.2 单片机发展和应用领域
单片机发展及分类
-
单片机初始阶段(1971~1976):以4位单片机和刚出现的8位单片机为代表。
1974年,美国Fairchild公司研制出第一台8位单片机F8。
1975年,美国TI公司研制的4位单片机TMS-1000。
4位单片机目前依然存在,主要用于价格便宜,低功耗的设备中,如低档玩具,电子秤,家用电器等,主要生产国是日本。计算机的位数代表的含义?
计算机内部以及CPU与外部设备间通信时,一次同时处理的二进制数据的位数,位数越多,表示计算机处理数据的能力越强。

-
低性能8位单片机阶段 (1976~1978)
1978年以前各厂家生产的8位单片机,速度慢,集成度低,性能相对较低,称为低档8位单片机。例如Intel公司的MCS-48单片机。
-
高性能8位单片机阶段(1978~至今)
一些高性能的8位单片机,使单片机发展进入了新阶段。8位单片机因其功能强,
能够满足目前大多数应用要求,价格较低,种类最多。例如Intel公司的MCS-51单片机。
-
其他高性能单片机的发展(1982~至今)
随着应用需求对单片机性能的提升,出现了16位,32位等速度更快,性能更强的单片机。例如Intel公司的MCS-96系列,TI公司的MSP430系列等。
但是在仪表,测控等领域,16位,32位单片机只是在少数特殊场合才有使用,8位单片机,始终占据着单片机市场的主要份额。
单片机的应用领域
- 工业自动化检测、控制
- 智能仪器仪表
- 计算机外设和智能设备
- 家用电器和消费电子
常见51系列兼容单片机简介
- 美国Intel公司的MCS-51系列单片机
- 美国Atmel公司的89系列
- 荷兰NXP(恩智浦,原Philips)公司的LPC89系列,80C55X系列等
- 美国 Silicon Labs公司的C8051F系列
- 台湾Winbond华邦公司的W78C5X系列
单片机系统开发流程
- 方案设计、原理图设
- PCB印刷电路板设计
- 电路板制作
- 软件调试
1.3 有符号整数在计算机中的表示
有符号整数在计算机中有三种表示法:
有符号整数在计算机内的表示(以8位机为例)

原码


反码


补码



2.1 MCS51单片机的型号与组成
MCS-51系列单片机最早是美国Intel公司在1980年推出的,当时包含51和52 两个子系列型号。
51系列,主要有8031、8051、8751三种型号,它们的指令系统与芯片引脚完全兼容,仅是片内的程序存储器容量有所不同。
- 8031芯片不带任何ROM
- 8051芯片带4kB(OTP) PROM(一次性写入)
- 8751芯片带4kB EPROM(紫外线可擦除)。
52系列,有8032、8052、8752 三种机型。52子系列与51子系列相比大部分相同,不同之处在于:片内数据存储器增至256个字节;
- 8032芯片不带ROM,
- 8052芯片带8kB PROM,
- 路8752芯片带8kB EPROM;
MCS-51单片机型号命名规则

MCS-51系列单片机的结构原理
它由中央处理器(CPU)、定时器,并行口等八部分组成

MCS-51系列单片机的中央处理器(CPU)
1. 运算部件
运算部件以一个8位算术逻辑运算单元ALU为核心,包含累加器ACC、B寄存器、标志寄存器PSW等部件,能实现算术运算、逻辑运算、位运算、数据传输等处理。
51单片机的ALU还有一个位运算器,它可以对一位二进制数据进行置位、清零、求反、测试转移及位逻辑“与〞、“或〞等处理,这对于控制方面很有用。
累加器ACC(Accumulator简称为A)是CPU中使用最频繁的寄存器,ALU进行运算时,数据绝大多数时候都来自于累加器A,运算结果也通常送回累加器A。
寄存器B称为辅助寄存器,它是为乘法和除法指令而设置的。
标志寄存器PSW (Program Status Word) 是一个8位的寄存器,它用于保存指令执行结果的状态。
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
C | AC | F0 | RS0 | RS0 | OV | P |
RS1、 RSO ( Register Select):寄存器组选择位.
RS1 | RS0 | 工作寄存器组 |
---|---|---|
0 | 0 | 0组 (00H-07H) |
0 | 1 | 1组 (08H-OFH) |
1 | 0 | 2组 (10H-17H) |
1 | 1 | 3组 (18H-1FH) |
C(Carry) | 进位标志位 |
---|---|
AC(Auxilary Carry. | 辅助进位标志位 |
FO (Flag Zero | 用户标志位 |
Ov(Over flow) | 溢出标志位 |
P(Parity) | 奇偶标志位 |
2. 控制部件
控制部件是单片机的控制中心,它包括定时和控制电路、指令寄存器、指令译码器、程序计数器PC ( Por gram Counter)、堆栈指针SP(Stack Pointer)、数据指针DPTR(Data Pointer Register ) 等。
它先以振荡信号为基准产生CPU的时序,从ROM中取出指令到指令寄存器,然后在指令译码器中对指令进行译码,产生指令执行所需的各种控制信号,送到单片机内部的各功能部件,指挥各功能部件产生相应的操作,完成对应的功能。
2.2 MCS-51单片机的程序存储器结构
MCS-51单片机存储器结构与一般微机的存储器种类不同,分为:程序存储器ROM和数据存储器RAM。
程序存储器ROM
存放单片机工作时的程序,单片机上电工作时,程序指令指导单片机完成设定的功能,没有ROM存储器,单片机不能工作。
MCS51单片机专门设置一个16位的程序计数器(PC),用于指示下一时刻CPU将要所执行的程序在ROM空间中的地址位置,由于PC指针长度为16位,即51单片机的程序存储器空间大小为64kB,最大地址从0000-FFFFH
MCS-51单片机的程序存储器,从物理结构上分为:
- 片内程序存储器ROM(不同型号的容量不同)
- 片外程序存储器ROM(64kB地址空间,外部通过总线访问)

- 片外程序存储器ROM(64kB地址空间,外部通过总线访问)
程序存储器的编址与访问
在MCS-51系列中,不同型号机型的程序存储器
- 8031和8032内部没有ROM,
- 8051片内有4kBROM,8751内部有4kB EPROM(0000H-0FFFH)
- 8052片内有8kB ROM,8752内部有8kB EPROM(0000H-1FFFH).
程序存储器的7个特殊地址
MCS-51系列单片机复位后PC的内容为0000H,故单片机复位后将从0000H单元开始执行程序。程序存储器的0000H单元地址是系统程序的启动地址。这里一般放一条绝对转移指令。
中断源 | 入口地址 |
---|---|
外部中断0 | 0003H |
定时/计数器0 | 000BH |
外部中断1 | 0013H |
定时/计数器1 | 001BH |
串行口 | 0023H |
定时/计数器2(仅52子系列有) | 002BH |
6个中断源的地址之间仅隔8个单元,存放中断服务程序往往不够用,这是通常放一条绝对转移指令,转到真正的中断服务程序,真正的中断服务程序放到后面。
数据存储器RAM
数据存储器(RAM)存储单片机运行期间所需要的数据和临时生成的数据,需要能够快速读出和写入数据。此类存储器掉电后,存储的数据会丢失,不能永久保存。
由于数据存储器包含单片机工作时所需要的多种用途的存储器,各部分存储器特性不同,访问方式也不同。
从物理结构上分为片内数据存储器和片外数据存储器。
- 片内数据存储器RAM(片内连线访问,不同型号大小不同)
- 片外数据存储器RAM (64kB地址空间,外部通过16位地址总线访问)

片内数据存储器
-
工作寄存器组区
OOHI—1FH单元为工作寄存器组区,共32个字节。工作寄存器也称为通用寄存器,用于临时寄存8个信息。工作寄存器共有4组,称为、1、23组,每组用RO~R7表示
-
位寻址区
20F一2FE为位寻址区,共16字节,128位。这128位每位都可以按位方式使用,一位都有一个位地址,位地址范围为00H—7FH
-
一般RAM区
30H一7FH是一般RAM区,也称为用户RAM区,共80字节,对于52子系列,般RAM区从30H—FFH单元。另外,对于前两区中未用的单元也可作为用户RAM单元使用。
-
堆栈区与堆栈指针
堆栈是按先入后出、后入先出的原则进行管理的一段存储区域。MCS-51单片机中,堆栈是用片内数据存储器的一段区域,一般设在2FH以后的单元,使用时应避开工作寄存器、位寻址区。
MCS-51单片机的堆栈是向上生长型的,存入数据是从地址低端向高端延伸,取出数据是从地址高端向低端延伸。入栈和出栈数据是以字节为单位。
为实现堆栈的先入后出、后入先出的数据处理,专门设置了一个堆栈指针SP(Stack Pointer)。
- 入栈(Push)时,SP指针的内容先自动加1,再把数据存入到SP指针指向的单元;
- 出栈(Pop)时,先把sP指针指向的单元的数据取出,然后再把SP指针的内容自动城l。
向上生长型堆栈
-
特殊功能寄存器
特殊功能寄存器(SFR,Special Function Register)专门用于控制、管理片内算术逻辑部件、并行I/0口、串行口、定时/计数器、中断系统等功能模块的工作,用户在编程时可以给其设定值,但不能移作它用。分布在80H—FFH地址空间,与片内数据存储器统一编址,除PC外,51子系列有18个特殊功能寄存器,52子系列有21个特殊寄存器。
它们的分配情况如下:
CPU专用寄存器:累加器A(EOH),寄存器B(FOH),程序状态寄存器PSW(DOE),堆栈指针SP(81H),数据指针DPTR (82H1、 83H)
片外数据存储器
单片机片内RAM存储器不够使用时,单片机可以通过外部总线扩展的片外数据存储器获得更大的存储空间,由于外部地址总线宽度为16位,所以片外RAM扩展最多64KB,地址范围为0000H—0FFFFH。
2.3 MCS-51单片机外部引脚及总线接口
MCS-51系列单片机的引脚及功能说明

一、输入/输出引脚
-
P0口(3932脚):P0.0P0.7统称为P0口。在不接片外存储器与不扩展I/0口时,作为双向输入/输出口。在接有片外存储器或扩展I/0口时,P0口分时复用为低8位地址总线和双向数据总线。
-
P1口(18脚):P1.0P1.7统称为P1口,可作为双向I/O口使用。
-
P2口(2128脚):P2.0P2.7统称为P2口,一般可作为双向I/O口使用;在扩展片外存储器时,P2口用作高8位地址总线。
-
P3口(1017脚):P3.0P3.7统称为P3口。除作为准双向I/0口使用外,还可以将每一位用于第二功能。
P3口 第二功能 P3.0 RXD 串行口输入端 P3.1 TXD 串行口输出端 P3.2 INTO 外部中断0请求输入端,低电平有效 P3.3 INT1 外部中断1请求输入端,低电平有效 P3.4 T0定时/计数器0外部计数脉冲输入端 P3.5 T1定时/计数器0外部计数脉冲输入端 P3.6 WR 外部数据存储器写信号,低电平有效 P3.7 RD外部数据存储器读信号,低电平有效
二、控制线
- ALE(Adress Lock Enable (30脚):地址锁存信号输出端。
- PSEN(Peripherals Select Enable)(29脚):片外程序存储器读选通信号输出端。
- RST(Reset)(9脚):当单片机振荡器工作时,该引脚上出现持续10 ms以上的高电平,就可实现复位操作,使单片机回复到初始状态。
- EA (31脚):EA为片外程序存储器选用端。该引脚低电平时,选用片外程序存储器,高电平或悬空时选用片内程序存储器。
三、主电源引脚
- VCC(40脚):接+5V电源。
- GND(20脚):接地。
冯·诺依曼结构和哈佛结构
冯·诺依曼
该结构采用单存储空间,即程序指令和数据共用一个存储空间,使用单一的地址和数据总线,取指令和取操作数都是通过一条总线分时进行。
当进行高速运算时,不但不能同时进行取指令和取操作数,而且还会造成数据传输通道的瓶颈现象,其工作速度较慢。

哈佛结构
该结构采用双存储空间,程序存储器和数据存储器分开,有各自独立的程序总线和数据总线,可独立编址和独立访问,可对程序和数据进行独立传输,使取指令操作、指令执行操作、数据吞吐并行完成,大大地提高了数据处理能力和指令的执行速度,非常适合千实时的数字信号处理。
从物理空间来说,MCS-51系列单片机有4个相对独立的存储器寻址空间,分别是:
- 片内程序存储器ROM 片内数据存储器RAM
- 片外程序存储器ROM 片外数据存储器RAM

64kB的程序存储器和64kB的片外数据存储器地址空间都为0000H一OFFFFH,地址空间是重叠的,它们如何区分呢?
Mcs-51单片机是通过不同的信号来对片外数据存储器和程序存储器进行读、写的,片外数据存储器的读、写通过RD和WR信号来控制,而程序存储器的读通过PSEN信号控制,通过用不同的程序指令来实现。
2.4 MCS51单片机并行IO口工作原理
MCS-51系列单片机有4个8位的并行I/O接口:P0、P1、P2和P3口。它们既可以作输入,也可以作输出,既可按8位处理,也可按位方式使用。输出时具有锁存能力,输入时具有缓冲功能。
本课程将根据4个IO口功能的由简单到复杂的关系,按照P1、P3、P2、P0的顺序讲解各IO口的工作原理。
-
P1口
P1口是准双向口,它只能作通用I/O接口使用。
当P1口输出时,可以提供电流负载。P1口具有驱动4个TTL负载芯片。IO口读入之前,先输出1,再读入。
-
P3口
P3口的位结构如图,作为普通IO口工作时,与P1口原理相同。
P3口除了作为准双向通用I/O口使用外,它的每一根线还具有第二种功能。
P3口 第二功能 P3.0 RXD 串行口输入端 P3.1 TXD 串行口输出端 P3.2 INTO 外部中断0请求输入端,低电平有效 P3.3 INT1 外部中断1请求输入端,低电平有效 P3.4 T0定时/计数器0外部计数脉冲输入端 P3.5 T1定时/计数器0外部计数脉冲输入端 P3.6 WR 外部数据存储器写信号,低电平有效 P3.7 RD外部数据存储器读信号,低电平有效 P3口除了作为准双向通用I/0口使用外,它的每一根线还具有第二种功能。
当P3口作为第二功能时,锁存器的Q输出端必须为高电平。
-
P2口
P2口也是准双向口,它有两种用途:通用I/O接口和高8位地址线。它的1位的结构如图,与P1口相比,它只在输出驱动电路上比P1口多了一个模拟转換开关MUX和反相器3。
当CPU发出控制信号低电平“0”,使多路开关MUX倒向锁存器,P2口作为通用I/0口使用,与P1口类似。
当CPU发出控制信号高电平“1”,使多路开关MUX倒内部地址线,P2口作为高8位地址总线使用。
- P0口
P0口是一个三态双向口,可作为地址/数据分时复用口,也可作为通用的VO接口。
它包括一个输出锁存器、两个三态缓冲器、输出驱动电路和输出控制电路组成,它的一位结构如图:
当控制信号应为低电平“0”,P0口作为通用I/O口使用。
当控制信号为高电平“1”,PO口作为地址/数据分时复用总线用。
当P0口作通用I/O接口时,应注意以下两点:
- 在输出数据时,由于V2截止,输出级是漏极开路电路,要使“1”信号正常输出,必须外接上拉电阻。
- P0口作为通用I/0口输入使用时,在输入数据前,应先向PO口写“1”,此时锁存器的Q端为“0“,使输出级的两个场效应管V1、V2均截止,引脚处于悬浮状态,才可作高阻输入。
2.5 MCS51单片机的工作周期和时序
MCS-51系列单片机的外部引脚及片外总线
外接晶体引脚
XTALI、XTAL2(19、18脚):当使用单片机内部振荡电路时,这两个引脚用来外接石英晶体和微调电容。在单片机内部,它是一个反相放大器的输入端,这个放大器构成了片内振荡器。

当采用外部时钟时,对于HMOS单片机,XTAL1引脚接地,XTAL,2接片外振荡脉冲输入;
对于CHMOS单片机,XTAL2引1脚接地,XTALI接片外振荡脉冲输入。

MCS-51系列单片机的工作方式
复位方式
在时钟电路工作以后,当外部电路使得RST端出现2个机器周期以上的高电平,系统内部复位。复位有两种方式:上电自动复位和手动按钮复位。


MCS-51系列单片机的时序
机器周期:机器周期是单片机的基本操作周期,每个机器周期包含S1、S2、…S66个状态,每个状态包含2拍P1和P2,每一拍为一个时钟周期(振荡周期)。因此,个机器周期包含12个时钟周期。依次可表示为S1P1、 S1P2、 S2P1、 S2P2、 。。。、 S6P1、S6P2。
指令周期:计算机工作时不断的取指令和执行指令。计算机取一条指令至执行完该指令需要的时间称为指令周期,不同的指令,指令周期不同。
单片机的指令周期以机器周期为单位。MCS-51系列单片机中,大多数指令的指令周期由一个机器周期或两个机器周期组成,只有乘法、除法指令须要4机器周期指令。

3.1 单片机C51编程环境的建立
单片机C51编程环境的建立
Keil μ \mu μ Vision IDE界面

如何建立一个可运行的语言程序框架
- 安装编译软件(keil)
- 建立一个空项目(Project)
- 建立一个源文件模板(XX.c或 XX.asm),无可执行代码,但可顺利编译。
- 写入具体的可执行程序,调试运行。
当项目编译、连接成功后,就可以进入调试模式,仿真运行来观察结果,运行调试过程如下。
(1)先用Debug菜单下的Start/Stop Debug Session命令(快捷键Ctrl+F5) 进入调试模式,结果如图所示。

一个简单的例子,while(1)
是单片机特有的结尾。
#include<reg51.h>
void main(){
unsigned char i = 0;
ACC=i + 1;
while(1){
P1 = ACC;
}
}
3.2 单片机C51中新增变量类型
用c语言编写单片机应用程序与标准的c语言程序也有相应的区别:C语言编写单片机应用程序时,需根据单片机存储结构及内部资源定义相应的数据类型和变量,而标准的C语言程序一般不需要考虑这些问题。
C51包含的数据类型、变量存储模式、输入输出处理、函数等方面与标准的c语言有一定的区别。其它的语法规则、程序结构及程序设计方法等与标准的C语言程序设计相同。
C51与标准C语言的区别
C51程序与标准的C程序在以下几个方面不一样:
- C51中增加了几种针对MCS-51单片机特有的数据类型;
- C51中变量的存储模式与51单片机的存储器紧密相关,定义变量时需要明确指定存储器属性;
- 在函数的使用方面,C51中有专门的中断函数,并定义了专门的关键字和语法规则。
C51新增加的变量类型
1. 特殊功能寄存器型(sfr
,sfr16
)
51单片机片内有许多特殊功能寄存器,通过这些特殊功能寄存器可以控制单片机的定时器、计数器、串口、I/O及其它功能部件,每一个特殊功能寄存器在片内RAM中都对应于单元。
在C51中,允许用户对这些特殊功能寄存器进行访问,访问时须通过sfr或sf16类型说明符进行定义,定义时须指明它们所对应的片內RAM单元的地址。格式如下:sfr或sfr16 特殊功能寄存器名=地址:
特殊功能寄存器的定义
sfr PSW=0xd0;
sfr P1=0x90;
sfr16 DPTR=0x82:
为了方便用户,C51编译器把S1单片机的常用的特殊功能寄存器和特殊位进行了定义,放在一个“regsl。h”或 “regs2。b”的头文件中,用户使用时,只须用预处理命令#include <reg52.h>
把这个头文件包含到程序中即可。
2. 位变量
在c51中,允许用户通过位类型符定义位变量。位类型符有两个:bit和sbit,它们在内存中都只占一个二进制位。
bit位类型符用于定义一般的可位处理位变量。它的格式如下:bit 位变量名;
sbit型变量的定义举例
sbit OV=0xd2;
sbit CY=oxd7:
sfr P1=0x90;
sbit P1_0=P1^0:
C51变量定义时的存储模式设置
在C51中,变量在定义时需指出变量的数据类型和存储器类型。定义的格式如下:
数据类型说明符 [存储器类型] 变量名1 [=初值];
存储器类型 | 描述 |
---|---|
data | 直接寻址的片内RAM低128B,访问速度快 |
bdata | 片内RAM的可位寻址区(20H~2FH),允许字节和位混合访问 |
idata | 间接寻址访问的片内RAM,允许访问全部片内RAM |
pdata | 用Ri间接访问的片外RAM的低256B |
xdata | 用DPTR间接访问的片外RAM,允许访问全部64k片外RAM |
code | 程序存储器ROM64k空间 |
C51中变量的定义举例
char data varl; //在片内RAM低128B定义用直接寻址方式访问的字符型变量var1
int idata var2; //在片内RAM256B定义用间接寻址方式访问的整型变量var2
int code var5;1 //在ROM空间定义整型变量var5
unsigned char bdata var6;//在片内RAM位寻址区20H~2FH单元定义可字节处理和位处理的无符号字符型变量var6
3.3 单片机C51中断函数定义
函数的定义
函数是c语言的基本模块,C51与标准C语言类似,支撑关于C语言的基本语法。同时也针对单片机特有的属性,增加了一些与函数相关的关键字和语法,并对一些库函数的处理做了调整。
- 增加了中断函数的语法
- 对stdio.h中标准输入输出库函数进行了调整
中断函数的定义
中断函数是单片机的一个重要特性,要使用C51语言开发单片机程序,必须支持中断函数的定义。
-
interrupt m修饰符
interrupt m 是C51中定义某个函数为中断响应西数的修饰符,当函数定义时定义后面用了interrupt m,系统编译时把该西数转化为某个中断员的响应函数,并函数地址存放在程序存储器中的中断对应的位置。interrupt m修饰符中,m的取值为0~5,对应的中断情况如下:- 0-外部中断0
- 1-定时/计数器TO
- 2-外部中断1
- 3-定时/计数器T1
- 4-串行口中断
- 5-定时/计数器T2
中断源 入口地址 外部中断0 0003H 定时/计数器0 000BH 外部中断1 0013H 定时/计数器1 001BH 串行口 0023H 定时/计数器2(仅52子系列有) 002BH
#include "regsl.h"
void main(){
......
}
void Int0_isr() interrupt 0{
}
编写MCS-51中断函数注意如下:
- 中断函数不能进行参数传递,不能有返回值。
- 中断函数不能被其他西数直接调用。因为中断函数的返回是由RETI指令完成的,而普通西数的返回指令是RET。
- 如果在中断西数中调用了其它函数,则被调用函数所使用的寄存器必须与中断函数相同。
4.1 单片机并行IO口的使用
McS-51单片机的内部资源主要有并行1/0口、定时器/计数器、串行接口以及中断系统,MCS-51单片机的大部分功能就是通过对这些资源的利用来实现的。
- 并行I/O口实现8位数字量的输入输出;
- 定时器/计数器实现周期性动作或对外部事件计数:
- 串行接口实现单片机与其他设备的数据通信;
- 中断系统实现对外部事件的及时响应。
MCS-51单片机有4个8位的并行输入/输出接口:P0、P1、P2和P3口。这4个口既可以并行输入或输出8位数据,又可以按位方式使用,即每一位均能独立作为输入或输出接口用。
用C51语言编程时,对端口输出时,端口号在等号左端,读入时,端口号在等号右端。
PO = 0x80; //输出10000000电平到P0口
P1 = OxFF; //读入P1口电平前,先输出高电平
i= P1; //读入P1口电平保存到变量i
利用单片机的P0口接8个发光二极管,P1口接8个开关,编程实现,当开关动作时,对应的发光二极管亮或灭。

# include <reg51.h>
void main(void){
unsigned char i;
P1=0xFF;
for( ; ; ){
i=P1;
P0=i;
}
}

4.2 定时器计数器工作原理及工作方式
定时/计数器的主要特性
- 51系列中51子系列有两个16位的可编程定时/计数器:TO和T1,52子系列除了TO,T1,还多一个T2。
- 每个模块既可以对系统时钟计数(定时器),也可以对外部信号计数(计数器),通过编程设定来实现。
- 每个定时/计数器都有多种工作方式,不同的工作方式对应计数长度和初值装载方式不同。
定时/计数器T0、T1的结构

注意要点:
-
由于它是加法计数器,每来一个计数脉冲,加法器内容加1,当由全1加到全0时溢出,如果要计N个单位,则首先应向计数器置初值为X:
初值X = 最大计数值(满值)M - 计数值N
在不同的计数方式下,最大计数值(满值)不一样,一般来说,当定时器/计数器工作于R位计数方式时,它的最大计数值(满值)为2的R次幂。
-
当定时/计数器工作于计数方式时,对芯片引脚T0-P3.4(或T1-P3.5)上的输入脉冲计数。
计数过程:在每一个机器周期的S5P2时刻对T0或T1上电平采样一次,当上一个机器周期采样到高电平,下一个机器周期采样到低电平,则计数器在下一个机器周期的S3P2时刻加1计数一次。
定时/计数器的方式和控制寄存器
一、定时/计数器的方式寄存器TMOD
TMOD | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
(89H) | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
← | 定时器1 | → | ← | 定时器0 | → |
其中:M1、M0为工作方式选择位,用于对T0的四种工作方式,T1的三种工作方式进行选择,选择情况如下
M1 | M0 | 工作方式 | 方式说明 |
---|---|---|---|
0 | 0 | 0 | 13位定时/计数器 |
0 | 1 | 1 | 16位定时/计数器 |
1 | 0 | 2 | 8位自动重置定时/计数器 |
1 | 1 | 3 | 两个8位定时/计数器(只有T0有) |
C/T:定时或计数方式选择位,当C/T=1时工作于计数方式;当C/T=0时工作于定时方式。
GATE:门控位,用于控制定时/计数器的启动是否受外部中断请求信号 (INTO,INT1)的影响,INTx为高电平时才运行。
二、定时/计数器的控制寄存器TCON
TMOD | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
(88H) | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
TF1(TF0):定时/计数器T1(T0)的溢出你忑位,当定时/计数器T1计满时,由硬件使它置位。
TR1(TR0):定时/计数器T1(T0)的启动位,当TR1=1时启动;TR1=0时停止。
定时/计数器的工作方式
方式0

方式0是13位的定时/计数方式,因而最大计数值(满值)为2的13次幂,等于8192。如计数值为N,则置入的初值X为:
X=8192-N
如定时/计数器T0的计数值为1000,则初值为7192,转换成二进制数为
1110000011000B(1C18H),则TH0=11100000B(E0H ),TL0=00011000B(18H)。
方式1
方式1的结构与方式o结构相同,只是把13位变成16位,16位的加法计数器被全部用上。
由于是16位的定时/计数方式,因而最大计数值(满值)为2的16次幂,等于65536。如计数值为N,则置入的初值X为:
X=65536-N
如定时/计数器TO的计数值为1000,则初值为65536-1000=64536,转换成二进制数为1111110000011000B(FC18H),则TH0=11111100B(FCH),TL0=00011000B(18H)。
方式2

方式2下,16位的计数器只用了8位来计数,用TL0(或TL1)来进行计数,而TH10(或TH1)用于保存初值。当TL0(或TL1)计满时则溢出,一方面使TF0(或TF1)置位,另一方面溢出信号又会触发开关,将TH0(或TH1的值就自动装入TL0(或TL1)。
由于是8位的定时/计数方式,因而最大计数值(满值)为2的8次幂,等于256。如计数值为N,则置入的初值X为:
X=256-N
如定时/计数器T0的计数值为100,则初值为256-100=156,转换成二进制数为10011100B(9CH),则THO=TLO=10011100B。
方式3
方式3只有定时/计数器T0才有,当M1M0两位为11时,定时/计数器T0工作于方式3,方式3的结构如下图。
方式3下,定时/计数器T0被分为两个部分TL0和TH0,其中,TL0可作为定时/计数器使用,占用T0的全部控制位:GATE、C/T、TR0和TF0;而TH0固定只能作定时器使用,对机器周期进行计数,这时它占用定时/计数器T1的TR1位、TF1位和T1的中断资源。
4.3 单片机的定时器的控制接口
定时/计数器的初始化编程及应用
一、定时/计数器的编程
- 根据要求选择方式,确定方式控制字,写入TMOD寄存器。
- 根据要求计算定时/计数器的计数值,再求得计数初值,写入初值寄存器。
- 根据需要,开放定时/计数器中断选项。
- 设置定时/计数器控制寄存器TCON,启动定时器。
- 等待定时时间到,如用查询处理则编写查询程序判断溢出标志,溢出标志等于1。
如用中断方式处理,编写中断服务程序。
二、定时/计数器的应用举例
利用定时器产生周期性的动作的基本思想:产生周期性的定时,定时时间到做相
应的处理,例如产生周期性的方波,只须定时对输出端取反一次即可。
设系统时钟频率为12MHZ,用定时/计数器T0编程实现从P1.0输出周期为500us的方波。
分析:
从P1.0输出周期为500us的方波,只需P1.0每250ps取反一次则可。当系统时钟为12MHZ,定时器T0工作于方式2时,最大的定时时间为256us,满足250ps的定时要求。
方式控制字应设定为00000010B(02H)。
系统时钟为12MHZ,定时250us,计数值N为250,
初值X=256-250=6,
则TH0=TL0=06H。
硬件电路

采用查询方式处理的程序
#include <reg51.h> //包含特殊功能寄存器库
sbit P1_0=P1^0;
void main(){
char i;
TMOD=0x02;
TH0=0x06;TL0=0x06;
TR0=1;
for( ; ; ){
if (TF0){
TF0=0;
P1_0=! P1_0;
}//查询计数溢
}
}
采用中断处理方式的程序
#include <reg51.h> //
sbit P1_0=P1^0;
void main(){
TMOD=0x02;
TH0=0x06;TL0=0x06;
EA=1;
ET0=1;
TR0=1;
while(1);
}
void time0_int(void) interrupt 1 {
P1_0=!P1_0;
}//中断服务程序


如果定时时间大于65536us,这时用一个定时/计数器直接处理不能实现,这时可用两个定时/计数器共同处理或一个定时/计数器配合软件计数方式处理。
【例7-3】设系统时钟频率为12MHZ,编程实现从P1.1输出周期为1s的方波。
由于定时时间较长,一个定时/计数器不能直接实现,可用定时/计数器T0产生周
期性为10ms的定时,然后用一个寄存器R2对10ms计数50次或用定时/计数器T1对10ms计数50次实现。
系统时钟为12MHZ,定时/计数器TO定时10ms,计数值N为10000,只能选方式1,方式控制字为00000001B(01H),初值x:
X=65536-10000 =55536 =1101 1000 1111 0000B
则TH0=1101 1000B=D8H TL0=1111 0000B=F0H
用某变量i对计数器溢出中断次数进行软件计数
#include <reg51.h> //包含特殊功能寄存器库
sbit P1_1=P1^1;
char i;
void main(){
TMOD=0x01; TH0=0xD8;TL0=0xf0;
EA=1;ET0=1;
i=0;
TR0=1;
while(1);
}
void time0_int(void) interrupt 1 { //中断服务程序
TH0=0xD8;TL0=0xf0;
i++;
if (i= =50) {
P1_1=! P1_1;
i=0;
}
}
4.4 单片机串行通讯的概念和工作原理
串行接口
通讯的基本概念
根据信息传送的方向,通信分为:单工、半双工和全双工三种。

并行通信和串行通信

同步通信和异步通信
串行通信按信息的格式
串行异步通信
根据通信双方各自的时钟基准,按照约定好的速率传输串行数据。

串行异步通信
通信双方按照同一个时钟信号为基准,根据时钟信号传输串行数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5En6ql5z-1651387445840)(%E5%9B%BE/image-20220430195037285.png)]
未传送时线路处于空闲状态,空闲线路约定为高电平"1",传送时每一个字符前加一个低电平的起始位,然后是8位数据位,低位在前,高位在后,最后是停止位,停止位用高电平表示。格式如图:

由千一次只传送一个字符,因而一次传送的位数比较少,对发送时钟和接收时钟
的要求相对不高,线路简单,但传送速度较慢。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VooTcNuw-1651387445841)(%E5%9B%BE/image-20220430195238642.png)]
串行通信电平标准及硬件接口协议
MCS-51单片机是标准数字电路芯片,其输入输出引脚电平符合TTL电平规则(高电平逻辑3-5V,低电平逻辑0-1V),该电平标准有效传输距离较短(15米以内),不适于远距离通信信号传输。
为了提高串行通信可靠性,增大通信距离,人们定义了各种新的通信电平标准。后经美国电子工业协会(EIA)指定标准规范化,形成RS422,RS232,RS485三种异步串行通信电平标准和硬件接口协议。
RS232接口标准是一种用于短距离或带调制解调器(Modem)的串行通信接口标准,1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的。


4.5单片机的串行口工作方式及应用
串行口结构
MCS-51单片机串行口主要由发送数据寄存器、发送控制器、输出控制门、接收数据寄存器、接收控制器、输入移位寄存器等组成

串行口控制寄存器SCON
SCON | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
98H | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
SM0、 SM1:串行口工作方式选择位。
SM0 | SM1 | 方式 | 功能 | 波特率 |
---|---|---|---|---|
0 | 0 | 方式0 | 移位寄存器方式 | f o s c / 12 f_{osc}/12 fosc/12 |
0 | 1 | 方式1 | 8位异步通信方式 | 可变 |
1 | 0 | 方式2 | 9位异步通信方式 | f o s c / 32 f_{osc}/32 fosc/32和 f o s c / 64 f_{osc}/64 fosc/64 |
1 | 1 | 方式3 | 9位异步通信方式 | 可变 |
SM2:多机通信控制位。
REN:允许接收控制位。
TB8:发送的第9位数据
RB8:接收的第9位数据。
TI:发送中断标志位。
RI:接收中断标志位。
电源控制寄存器PCON
PCON | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
87H | SM0D |
当SMOD位为1,则串行口方式1、方式2、方式3的波特率加倍。
串行口的工作方式
方式0
方式o通常用来外接移位寄存器,用作扩展I/O口。方式0工作时波特率固定为:
f
o
s
c
/
12
f_{osc} /12
fosc/12。工作时,串行数据通过RXD输入和输出,同步时钟通过TXD输出。
发送过程
在TI=0时,当CPU执行一条向SBUF写数据的指令时,启动发送过程。从RXD依次发送出去,同步时钟从TXD送出。8位数据发送完后,发送中断标志TI置位,并向CPU申请中断。
接收过程
在RI=0的条件下,将REN置 “1”就启动一次接收过程。
在移位脉冲的控制下,RXD上的串行数据依次移入移位寄存器。当8位数据全部移入移位寄存器后,8位数据送入接收数据缓冲器SBUF中,同时,接收中断标志RI置位,向CPU申请中断。
利用方式0扩展并行I/O口
MCS-51单片机的串行口在方式0时,当外接一个串入并出的移位寄存器,就可以扩展并行输出口,当外接一个并入串出的移位寄存器时,就可以扩展并行输入口。
用8051单片机的串行口外接串入并出芯片CD4094扩展并行输出口控制一组发光二极管,从左至右延时轮流显示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qwXo8szS-1651387445841)(%E5%9B%BE/image-20220430201531453.png)]
4094是一块8位的串入并出的芯片,共16个引脚:
- D:串行数据输入端;
- CLK: 串行时钟信号输入端:
- Q0~Q7:8位数据并行输出端;
- STB: 锁存端;
- OE:数据输出允许端:

4094的工作过程一般如下:
- 使锁存端STB =0,在串行时钟信号CLK的作用下,数据从输入端D按一个时钟周期一位依次串行输入。
- 8位数据输入后,使控制端STB=1,输入的内容锁存到内部锁存器。
- 使数据输出允许端OE=1,锁存的数据送Q0~Q7行输出;
#include <reg51.h> //包含特殊功能寄存器库
sbit P1_0=P1^0;
void main(){
unsigned char i;
unsigned int j;
SCON=0x00; //串口初始化方式0
i=0x01;
for (; ;){
P1_0=0; //4094串入
SBUF=i; //51单片机串口发送
while (!TI) { ;} //等待发送
P1_0=1;TI=0; //4094并出显示
for (j=0;j<=254;j++){
;
}
i=i*2;
if (i==0x00)
i=0x01;
}
}
方式1
方式1为8位异步通信方式,在方式1下,一帧信息为10位:1位起始位(0),8位数据位(低位在前)和1位停止位(1)。
(1)发送过程
在TI=0时,向SBUF写数据,启动发送过程。数据由TXD引1脚送出,在发送时钟的作用下,先通过TXD端送出数据,当一帧数据发送完毕后,由硬件使发送中断标志TI置位。
(2)接收过程
当允许接收控制位REN被置1,启动接收控制器开始接收数据。在接收移位脉冲的控制下依次把所接收的数据移入移位寄存器,当8位数据及停止位全部移入后,进行响应操作。
TXD发送数据端,RXD为接收数据端。波特率可变,由定时/计数器T1的溢出率和电源控制寄存器PCON中的SMOD位决定。
波
特
率
=
2
S
M
O
D
∗
(
T
1
的
溢
出
率
)
/
32
波特率=2SMOD * (T1的溢出率)/32
波特率=2SMOD∗(T1的溢出率)/32
T
1
的
溢
出
率
=
波
特
率
×
32
/
2
S
M
O
D
T1的溢出率=波特率×32/2^{SMOD}
T1的溢出率=波特率×32/2SMOD
而T1工作于方式2的溢出率可表示为:
T 1 的 溢 出 率 = f o s c / ( 12 × ( 256 − 初 值 ) T1的溢出率=fosc/(12×(256-初值) T1的溢出率=fosc/(12×(256−初值)
所以:
T 1 的 初 值 = 256 − f o s c ∗ 2 S M O D / ( 12 ∗ 波 特 率 ∗ 32 ) T1的初值=256 - fosc * 2^{SMOD} /(12*波特率*32) T1的初值=256−fosc∗2SMOD/(12∗波特率∗32)
Fosc = 12MHz(12000000Hz)波特率=9600bps SMOD =0 T1的初值=252.744
Fosc = 11.0592MHz(11059200Hz) 波特率-9600bps SMOD =0 T1的初值=253
串行口的编程及应用
设计双机通信系统。要求:甲机P1口开关的状态通过串行口发送到乙机,乙机接收到后通过P2口的发光二极管显示。

甲、乙两机都选择方式1:8位异步通信方式,波特率为1200bps,甲机发送,乙机接收,因此甲机的串口控制字为40H,乙机的串口控制字为50H。
由于选择的是方式1,波特率由定时/计数器T1的溢出率和电源控制寄存器PCON中的SMOD位决定。则须对定时/计数器T1初始化。
设SMOD=0,甲、乙两机的振荡频率为12MHZ,由于波特率为1200。定时/计数器T1选择为
方式2,则初值为:
初
值
=
256
−
f
o
s
c
∗
2
S
M
O
D
/
(
12
∗
波
特
率
∗
32
)
=
256
−
12000000
/
(
12
∗
1200
∗
32
)
=
230
=
E
6
H
初值=256 - fosc *2^{SMOD} /(12 *波特率*32) =256-12000000/(12 *1200*32)=230=E6H
初值=256−fosc∗2SMOD/(12∗波特率∗32)=256−12000000/(12∗1200∗32)=230=E6H
根据要求定时/计数器T1的方式控制字为20H。
甲机发送方程序
#include <reg51.h>
void main(void) {
unsigned char i;
SCON=0x40;
TMOD=0x20;
TL1=0xE6;
TH1=0xE6;
TR1=1;
P1=0xFF;
while(1){ //发送
i=P1;
SBUF=i;
while (TI==0);
TI=0;
}
}
乙机接收方程序
#include <reg51.h>
void main(void)
{
unsigned char i;
SCON=0x50;
TMOD=0x20;
TL1=0xE6;
TH1=0xE6;
TR1=1;
EA=1;
ES=1;
while(1){ //发送
;
}
}
void funins(void) interrupt 4 { //接收
if(RI){
RI=0;
P2=SBUF;
}
}
4.6 MCS51单片机中断系统介绍
中断系统
中断的基本概念
当CPU正在处理某一件事A时,发生了另一件事件B,CPU暂时正在执行的程序,转去执行预先设定的处理事件B的程序;处理完毕后,再回到事件A被暂停的程序位置继续处理。这一过程,称之为中断。

- 中断源
- 中断的嵌套与优先级处理
- 中断的响应过程
一、中断源
1.外部中断 INT0和 INT1
外部引脚P3.2和P3.3输入,有两种触发方式:电平触发及跳变(边沿)触发。由特殊功能寄存器TCON来管理。
TCON | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
(88H) | TF1 | TR1 | TF0 | TR0 | 1E1 | IT1 | IE0 | IT0 |
IT0(IT1):外部中断触发方式设置位
被设置为0,则选择外部中断为电平触发方式;
被设置为1,则选择外部中断为边沿触发方式。
IE0(TE1):外部中断0(或1)的中断请求标志位。
光电式自动迎宾器
在门框两侧安装对射式光电传感器,当顾客进出时,其身体遮挡了光源发出红外光,传感器输出的高低电平,单片机检测到电平变化,进而播放不同的提示音。

在电平触发方式时,CPU在每个机器周期采样P3.2,若引脚为低电平,则IE0(E1)置1,向CPU请求中断;CPU响应后能够由硬件自动将IE0(或IE1清零。
在边沿触发方式时,若第一个机器周期采样到P3.2引脚为高电平,第二个机器周期采样为低电平时,由IE0(或IE1)置1,向CPU请求中断。
2. 定时/计数器T0和T1中断
当定时/计数器T0(或T1)溢出时,由硬件置TF0(或TF1)为“1”,向CPU发送中断请求,当CPU响应中断后,将由硬件自动清除TF0(或TF1)。
3.串行口中断
Mcs-51的串行口中断源对应两个中断标志位:串行口发送中断标志位T1和串行口接收中断标志位RI。无论哪个标志位置“1”,都请求串行口中断,到底是发送中断TI还是接收中断RI,只有在中断服务程序中通过指令查询来判断。
4.定时/计数器T2中断
只针对52系列单片机,当定时/计数器T2溢出时,向CPU发送中断请求。
二、中断允许控制
MCS-51单片机中没有专门的开中断和关中断指令,对各个中断源的允许和屏蔽是由内部的中断允许寄存器IE的各位来控制的。
IE | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
(A8H) | EA | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
EA(Enable ALL):中断允许总控位。
ET2, ET1,ETO:定时器/计数器T2,T1,TO的溢出中断允许位。
ES:串行口中断允许位。
EX1,EXO: 外部中断 INT1,INTO 的中断允许位。
系统对各中断源,默认给出优先权顺序

三、优先权控制
每个中断源有两级控制:高优先级和低优先级。通过由内部的中断优先级寄存器IP来设置。中断优先级寄存器IP(Interrupt Priority)的字节地址为B8H,可以进行位寻址。
IP | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
(B8H) | PT2 | PS | PT1 | PX1 | PT0 | PX0 |
PT2,PT1,PTO:定时器T2,T1,T0的中断优先级控制位。
PS:串行口的中断优先级控制位。
PX1,PX0:外部中断INT1,INTO的中断优先级控制位。
如果IP中某一位被置"1",表示对应中断源被设为高优先级;否则为低优先级。
对于中断优先权和中断嵌套,MCS-51单片机有以下三条
- 正在进行的中断过程不能被新的同级或低优先级的中断请求所中断,一直到该中断服务程序结束,返回了主程序后,CPU才响应新的中断请求。
- 正在进行的低优先级中断服务程序能被高优先级中断请求所中断,实现两级中断嵌套。
- CPU同时接收到几个中断请求时,首先响应优先级最高的中断请求。
各中断服务程序的入口地址
中断源 | 入口地址 |
---|---|
外部中断0 | 0003H |
定时/计数器0 | 000BH |
外部中断1 | 0013H |
定时/计数器1 | 001BH |
串行口 | 0023H |
定时/计数器2(仅52子系列有) | 002BH |
四、中断响应时间
中断响应时间是指CPU检测到中断请求信号到转入中断服务程序入口所需要的机器周期。51单片机响应中断的最短时间为3个机器周期。
5.1 MCS51单片机的最小系统
所谓最小系统,是指可独立工作的单片机,所需要的最小配置电路。MCS-51单片机根据片内有无程序存储器最小系统分两种情况。
8051/8751片内有4kB的ROM/EPROM,只需要外接晶体振荡器和复位电路就可构成最小系统。如图所示。

该最小系统的特点:
由于片外没有扩展存储器和外设,PO、P1、P2、P3都可以作为用户I/O口使用。
8031最小应用系统
8031片内无程序存储器片,在构成最小应用系统不仅要外接晶体振荡器和复位电路,还应外扩展程序存储器。


单片机外部总线扩展的基本思路

5.2单片机片外总线扩展存储器
MCS-51单片机的存储器扩展能力
片外程序存储器可扩展64kB,地址:0000H~FFFFH。
片外数据存储器可扩展64kB,地址:0000H~FFFFE。

存储器扩展的一般方法
不论何种存储器芯片,其引脚都呈三总线结构,与单片机连接都是三总线对接。
-
控制线
- 程序存储器:ROM芯片输出允许控制线 OE与单片机的PSEN信号线相连。
- 数据存储器:RAM芯片输出允许控制线oE和写控制线WE分别与单片机的读信号线RD和写信号线WR相连。
-
数据线:存储器芯片的数据线与单片机的数据总线
(PO。0~PO。7)按由低位到高位的顺序相接。 -
地址线:存储器芯片的地址线的数目由芯片的容量决定。
容量(Q)与地址线数目(ND)满足关系式: Q = 2 N Q=2^N Q=2N。 -
芯片选择引脚:每一个连接在公共总线上的芯片都有片选输入引脚(CS,一般为低电平有效),用于供CPU选择某个时刻使能该芯片被选中,占用总线。而当片选引脚电平无效时,芯片不被选中,芯片与总线连接引脚呈高阻隔离状态。
译码有两种方法:部分译码法和全译码法。
部分译码:存储器芯片的地址线与单片机系统的地址线顺次相接后,剩余的高位地址线仅用一部分参加译码,包括某根线直接接片选端(线选法)。

程序存储器扩展
单片程序存储器的扩展

A15直接连接CS端

多片程序存储器的扩展

第一片的地址空间为:

第二片的地址空间为:

全译码:存储器芯片的地址线与单片机系统的地址线顺次相接后,剩余的高位地址线全部参加译码。这种译码方法存储器芯片的地址空间是唯一确定的,但译码电路相对复杂。


由于采用全译码,每片2764的地址空间唯一,分别是:

5.3 单片机总线扩展并行IO口
输入/输出口扩展
简单I/O口扩展
通常通过数据缓冲器、锁存器来扩展简单I/O接口。例如:74LS373 74LS244、74LS273、 74LS245等芯片都可以作简单I/0扩展。


绝对地址的访问
C51编译器提供了一组宏定义来对51系列单片机的code、xdata空间进行绝对寻址.规定只能以无符号数方式访问,定义了宏定义,其函数原型如下:
#define CBYTE((unsigned char volatile*)0x50000L)
#define XBYTE((unsigned char volatile*)0x20000L)
#define CwORD((unsigned int volatile*)0x50000L)
#define XWORD((unsigned int volatile*)0x20000L)
这些函数原型放在absacch文件中。使用时须用预处理命令把该头文件包含到文件中,形式为:#include <absacc.h>
。
其中:
- CBYTE以字节形式对code区寻址,
- XBYTE以字节形式对xdata区寻址,
- CWORD以字形式对code区寻址,
- XWORD以字形式对xdata区寻址。访问形式如下:
宏名[地址]
宏名为CBYTE、 XBYTE、 CWORD 或XWORD。地址为存储单元的绝对地址。
绝对地址对存储单元的访问
#include <absacc.h> //将绝对地址头文件包含在文件中
#include <reg51.h> //将寄存器头文件包含在文件中
void main(void) {
unsigned char var1;
unsigned int var2;
var1=XBYTE[0x0005]; // 访问片外RAM的0005字节单元
var2=XWORD[0x0002]; // 访问片外RAM的0002字单元
}

图中,扩展的输入口接了K0K78个开关,扩展的输出口接了LOL78个发光二极管,如果要实现K0K7开关的状态通过LOL7发光二极管显示,
#include <reg51.h>
#include <absacc.h> // 定义绝对地址访问
#define uchar unsigned char
void main(void){
uchar i;
while(1){
i=XBYTE[0x7fff]; // 读74LS244扩展的输入口
XBYTE[0x7fff]=i; // 输出到74LS373扩展的输出口
}
}
5.4单片机外部总线扩展并口芯片8255
可编程I/O扩展(8255A)
8255A的结构与功能
8255A是一款可编程并行IO接口扩展芯片,通过单片机总线连接,可使单片机扩展出3个8位并行IO口。
扩展的并行IO口具有多种工作模式,可实现方向控制、询问、应答控制等多种功能,可用于单片机对各种不同速度要求的外部设备的IO口控制。

3个可编程的并行I/0端口:PA口、PB口和PC口
C S ‾ \overline{CS} CS | A1 | A0 | R D ‾ \overline{RD} RD | W R ‾ \overline{WR} WR | I/O操作 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 读A口寄存器内容到数据总线 |
0 | 0 | 1 | 0 | 1 | 读B口寄存器内容到数据总线 |
0 | 1 | 0 | 0 | 1 | 读C口寄存器内容到数据总线 |
0 | 0 | 0 | 1 | 0 | 数据总线上内容写到A口寄存器 |
0 | 0 | 1 | 1 | 0 | 数据总线上内容写到B口寄存器 |
0 | 1 | 0 | 1 | 0 | 数据总线上内容写到C口寄存器 |
0 | 1 | 1 | 1 | 0 | 数据总线上内容写到控制口寄存器 |
8255A的引脚信号

- D7~DO:三态双向数据线,与单片机的数据总线相连。
- C S ‾ \overline{CS} CS:片选信号线,低电平有效,用于选中8255公芯片。
- R D ‾ \overline{RD} RD:读信号线,低电平有效,用于控制从8255A端口读出信息。
- W R ‾ \overline{WR} WR:写信号线,低电平有效,用于控制向8255A端口写入信息。
- A1, A0:地址线,用来选择8255A的内部端口。
- PA7~PA0, PB7~PB0, PC7~PC0: A、 B、C口的8根I/O信号线,用于与外部设备连接。
- RESET:复位信号线。
- V c c V_{cc} Vcc:+5v电源线。GND:地信号线。
8255A的控制字
8255A有两个控制字:工作方式控制字和C口按位置位/复位控制字
-
工作方式控制字
-
C口按位置位/复位控制字
8255A的工作方式
- 方式0
- 具有两个8位端口(A、B和两个4位端口(C口的高4位和C口的低4位)。
- 任何一个端口都可以设定为输入或者输出。
- 每一个端口输出时锁存,而输入时不锁存。
- 方式1
- A口和B口作为数据I/O口,C口用作I/0的应答信号。
方式0输入/输出时没有专门的应答信号,通常用于无条件传送。
例如:下图是8255A工作于方式0的例子,其中A口输入,B口输出。
-
方式1输入(单向并行口读入数据通信,带查询/应答机制)
- S T B ‾ \overline{STB} STB:外设送给8255A的“输入选通〞信号
- IBF: 8255A送给外设的“输入缓冲器满〞信号
- INTR: 8255A发送给CPU的“中断请求〞信号
- INTE:8255A内部为控制中断而设置的“中断允许”信号
-
方式1输出(单向并行口输出数据通信,带查询/应答机制)
- O B F ‾ \overline{OBF} OBF:8255A送给外设的“输出缓冲器满〞信号
- A C K ‾ \overline{ACK} ACK:外设送给8255A的“应答”信号
- INTR: 255A送给CPU的“中断请求〞信号
- INTE:8255A内部为控制中断而设置的“中断允许〞信号
-
方式2(双向并行口数据通信,带查询/应答机制)
8255A与MCS-51单片机的接口
-
硬件接口
8255A的A口、B口、C口和控制口的地址分别是7F00H、 7F01H、 7F02H和7F03HI (高8位地址线未用的取1,低8位地址线未用的取0).
-
软件编程
A口接开关K0~K7,B口接发光二极管L0~L7,要求从A口读入开关状态通过B口显示出来。8255A的工作方式控制字为1000 0010B (82H)
#include <reg51.h> #include <absacc.h> //定义绝对地址访问 #define uchar unsigned char void main(void){ uchar i; XBYTE[0x7f03]=0x82; // 8255A初始化,B口方式0输入,A口方式0输出 while(1){ i = XBYTE[0x7f01]; //从B口输入 XBYTE[0x7f00] = i; //从A口输出 } }
5.5 LED数码管的工作原理及驱动方法
LED显示器的结构与原理
在单片机应用系统中通常使用的是7段式LED数码管显示器,如图所示。

LED数码管的内部结构
7段式LED数码管显示器,它有共阴极和共阳极两种。

LED数码管的字段码

- 显示字符0,共阴极字段码为0x3F,共阳极为0xC0
LED数码管字型码表
显示字符 | 共阴极字段码 | 共阳极字段码 | 显示字符 | 共阴极字段码 | 共阳极字段码 |
---|---|---|---|---|---|
0 | 3FH | C0H | C | 39H | C6H |
1 | 06H | F9H | D | 5EH | A1H |
2 | 5BH | A4H | E | 79H | 86H |
3 | 4FH | B0H | F | 71H | 8EH |
4 | 66H | 99H | P | 73H | 8CH |
5 | 6DH | 92H | U | 3EH | C1H |
6 | 7DH | 82H | T | 31H | CEH |
7 | 07H | F8H | Y | 6EH | 91H |
8 | 7FH | 80H | L | 38H | C7H |
9 | 6FH | 90H | 8.(全亮) | FFH | 00H |
A | 77H | 88H | “灭” | 00 | FFH |
B | 7CH | 83H | … | … | … |
LED数码管显示器的译码方式
硬件译码方式
硬件译码方式是指利用专门的硬件电路来实现显示字符到字段码的转换,如
MOTOTOLA公司生产的MC14495芯片,MC14495是共阴极一位十六进制数-字段码转换芯片,能够输出用四位二进制表示形式的一位十六进制数的七位字段码,不带小数点。

静态显示方式
数码管公共端接固定电平,各笔画段位与1/0引脚相连,程序直接控制I/0口显示字符。

动态显示是将多个数码管的每一位笔划段并接在一起,用八个I/O口控制,公共端通过不同的I/O口线控制。工作时,逐位选中数码管并显示各自字符,循环点亮,利用人眼的暂态效应,达到显示效果。








动态显示技术中难点在于:扫描移位的切换过程:
















5.6 LED数码管与单片机的接口
LED显示器与单片机的接口
硬件译码静态显示
在实际应用时,如果数码管个数较少,通常用硬件译码静态显示,在数码管个数较多时,则通常用软件译码动态显示。

软件译码动态显示
下图是一个8位软件译码动态显示的接口电路图。
P1口输出数据信号,PO口输出位选信号。数码管为共阴极,低电平选中。

#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar disbuffer[8]={0,1,2,3,4,5,6,7}; //定义显示缓冲区
uchar codevalue[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0~F的字段码表
uchar chipcode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; // 位选码表
void main(void) {
while(1){
display(); // 设显示函数
}
}
void display(void) {
uchar i,p,temp;
for (i=0;i<8;i++) {
P0=0xFF;
p=disbuffer[i]; //取当前显示的字符
temp=codevalue[p]; //取出显示数字对应字段码
P1=temp; //送出字段码
P0 =chipcode[i]; //送出位选码
delay(20); //延时
}
}
void delay(uint i) {
for (;i>0;i++); //延时函数
}
LED动态显示技术的扩展应用
LED点阵
LED点阵器件构造和多位数码管很相似。

LED点阵显示驱动原理完全一样。

LED手摇棒的实现
手摇棒可通过晃动单排LED灯,显示整幅图形。单片机检测手摇棒所在不同位置,控制LED灯显示不同列的图形。
LED旋转电子钟的设计
由于人手摇的频率不稳定,手摇棒显示LED图形的效果并不流畅。当使用小直流电机带动单列LED转动,显示的效果更流畅。
旋转电子钟相当于一个环形LED点阵。
6.1 ADC转换器工作原理
A/D转換器概述
现实世界中,各种物理量(温度、压力、流量、速度等) 通过传感器转换成电信号,通常都是模拟信号。而单片机作为数字电路芯片,只能处理数字电平信号。因此需要有器件实现模拟量到数字量之间的转换。
- AD器件是将模拟量转换为数字信号的芯片;
- DA器件则是将数字量转换为模拟量的芯片。
一、A/D转换器的类型及原理
现在有很多类型的A/D转换器芯片,各种A/D转换芯片根据转换原理可分为
计数型A/D转换器、逐次比较式、双重积分型、并行式A/D转换器等;
按转换方法可分为
直接A/D转换器 间接A/D转换器;
按其分辦率可分为 4、8、12、16位的A/D转换器芯片。
逐次逼近型A/D转换器
逐次逼近型A/D转换器是由一个比较器、D/A转换器、寄存器及控制电路组成部分。逐次逼近型是用一系列已知的电压权值,从高位到低位依次开始逐位试探比较。
5V参考电压,输入模拟电压为6.835937V,逐次比较过程为。
- D7:5V
- D6:2.5V
- D5:1.25V
- D4:0.625V
- D3:0.3125V
- D2:0.15625V
- D1:0.078125V
- D0:0.0390625V

3)双重积分型A/D转换器
双重积分型A/D将输入电压先变换成与其平均值成正比的时间间隔,然后再把此时间间隔转换成数字量,它属于间接型转换器。由于在转换过程中进行了两次积分,因此称为双重积分型。双重积分型A/D转换器
转换精度高,稳定性好,测量的是输入电压在一段时间的平均值,而不是输入电压的瞬间值,因此它的抗干扰能力强,但是转换速度慢,双重积分型A/D转换器在工业上应用也比较广泛。

二、A/D转换器的主要性能指标
- 分辦率:表示输出变化了变化一个相邻数码所需输入的模拟电压变化量。分辨率一般为满刻度电压与2^n之间的比值,所以位数越大,分辦率越高。
- 转换时间:ADC完成一次模数转换所需的时间,其倒数则定义为转换速率。
- 绝对误差与相对误差:绝对误差指AD转换器在任何数码对应实际电压与理想电压值之差的最大值,相对误差是绝对误差与满刻度电压值之比。
- 线性度:指AD器件实际的转换西数与理想直线的最大误差。

6.2 ADC0809与单片机的控制接口
ADC0809与MCS-51的接口
ADC0809逐次逼近型转换器
ADC0809是CMOS工艺单片型逐次逼近型A/D转换器,具有8路模拟量输入通道,有转换起停控制,模拟输入电压范围为0~+5V,转换时间为100 us。

ADC0809的引脚
ADC0809芯片有28个引脚,采用双列直插式封装(DIP28)。

ADDC | ADDB | ADDA | 选择通道 |
---|---|---|---|
0 | 0 | 0 | IN0 |
0 | 0 | 1 | IN1 |
0 | 1 | 0 | IN2 |
0 | 1 | 1 | IN3 |
1 | 0 | 0 | IN4 |
1 | 0 | 1 | IN5 |
1 | 1 | 0 | IN6 |
1 | 1 | 1 | IN7 |
其中:
- NO~IN7:8路模拟量输入端。
- DO~D7:8位数字量输出端。
- ADDA、 ADDB、 ADDC:3位地址输入线,用于选择8路模拟通道中的一路。
- ALE:地址锁存允许信号,输入,由低电平变高电平锁存。
- START:A/D转换启动信号,输入,由高电平变低电平启动。
- EOC:A/D转换结束信号,输出。当启动转换时,该引脚为低电平,当A/D转换结束时,该线脚输出高电平。
- OE:数据输出允许信号,输入,高电平有效。当转换结束后,如果从该引脚输入高电平,则打开输出三态门,输出锁存器的数据从DO~D7送出。
- CLK:时钟脉冲输入端。要求时钟频率不高于640kHZ。
- REF+、 REF-:基准电压输入端。
- vcc:电源,接+5v电源。
- GND:地。
ADC0809的工作流程809的引脚

- 输入3位地址,并使ALE=1,将地址存入地址锁存器中,经地址译码器译码从8路模拟通道中选通一路模拟量送到比较器。
- 送START一高脉冲,START的上升沿使逐次逼近寄存器复位,下降沿启动A/D转换,并使EOC信号为低电平。
- 当转换结束时,转换的结果送入到输出三态锁存器,并使EOC信号回到高电平,通知CPU已转换结束。
- 当CPU执行一读数据指令,使OE为高电平,则从输出端D0~D1读出数据。
ADC0809与MCS-51单片机的接口
下图是一个ADC0809与8051的一个接口电路图。


向地址满足A15=0的端口进行写操作时,即可产生ALE/START信号所需的上升沿,写操作结束后,即可产生下降沿。

向地址满足A15=0的端口进行读操作时,即可产生OE信号所需的上升沿。

启动AD转换时EOC为低电平,转换结束时变为高电平,其电平极性与INT0中断相反,即需要通过反相器将极性反向。
软件编程
设系统为一个8路模拟量输入的巡回检测系统,使用中断方式采样数据,把采样转换所得的数字量按序存于片内RAM中。采样完一遍后停止采集。
#include <reg51.h>
#include <absacc.h> //定义绝对地址访问
#define uchar unsigned char
uchar data x[8]; //定义8个单元的数组,存放结果
uchar xdata *ADadr; //定义指向通道的指针
uchar i=0;
void main(void) {
IT0 = 1; //初始化
EX0 = 1;
EA = 1;
i = 0;
ADadr = 0x7FF8; //指针指向通道0
*ADadr = i; //启动通道0转换
for (;;) {;} //等待中断
}
void int_adc(void) interrupt 0 { //中断函数
x[i] = *ADadr; //接收当前通道转换结果
i++;
ADadr++; //指向下一个通道
if (i < 8){
*ADadr = i; //8个通道未转换完,启动下一个通道返回
}else{
EA = 0;
EX0 = 0; //8个通道转换完,关中断返回
}
}
6.3 常见DAC转换器工作原理
D/A转换器的基本原理
D/A转换器是把输入的数字量转换为与之成正比的模拟量的器件。数字量不同位置值代表不同权重,输出模拟量是不同权重值的累加和。
如输入的数字量为D,
V
R
e
f
V_{Ref}
VRef为基准电压,输出的模拟量为
V
o
V_o
Vo,则有:
V
o
=
D
×
V
R
E
F
/
2
n
\mathrm{V}_{\mathrm{o}}=\mathrm{D} \times \mathrm{V}_{\mathrm{REF}} / 2^{n}
Vo=D×VREF/2n
D = d n − 1 2 n − 1 + d n − 2 2 n − 2 + … … + d 1 2 1 + d 0 2 0 \mathrm{D}=\mathrm{d}_{\mathrm{n}-1} 2^{\mathrm{n}-1}+\mathrm{d}_{\mathrm{n}-2} 2^{\mathrm{n}-2}+\ldots \ldots+\mathrm{d}_{1} 2^{1}+\mathrm{d}_{0} 2^{0} D=dn−12n−1+dn−22n−2+……+d121+d020
D/A转换器的性能指标
- 分辨率:DAC能够产生的最小的模拟信号变化量,一般用最小模拟变化量与满量程信号值之比表示。如:8位(1/256),12位(1/4096)。
- 精度:DAC输出实际模拟量与理论值间的误差,同样分为绝对精度和相对精度。
- 建立时间:从数字量输入发生变化开始,到输出端模拟量稳定后,所需的时间,它是衡量DAC转换速度的重要参数。
D/A转换的分类
- 按输入数字量的位数分:8位、10位、12位16位等;
- 按输入的数码分:二进制方式和BCD码方式;
- 按数字量的输入方式分:并行方式和串行方式;
- 按输出形式分:电流输出型和电压输出型,电压输出型
D/A转换一般由电阻解码网络、模拟电子开关、基准电压、运算放大器等组成。
按电阻解码网络的组成形式,D/A转换器分成有权电阻解码网络D/A转换器、工型电阻解码网络D/A转换器和开关树型电阻解码网络D/A转换器等。
T型电阻解码网络D/A转换器只用两种阻值的电阻,精度较高,容易集成化,在实际中使用最频繁。
反相比例放大器

根据运放虚断特性:
I
(
R
1
)
=
I
(
R
f
)
\mathrm{I}(\mathrm{R} 1)=\mathrm{I}\left(\mathrm{R}_{\mathrm{f}}\right)
I(R1)=I(Rf)
各支路的电流为:
I
n
−
1
=
V
R
E
F
2
R
I
n
−
1
=
V
R
E
F
2
2
R
⋯
⋯
I
n
−
1
=
V
R
E
F
2
n
−
1
R
I
n
−
1
=
V
R
E
F
2
n
R
I_{n-1}=\frac{V_{R E F}}{2 R} \quad I_{n-1}=\frac{V_{R E F}}{2^{2} R} \quad \cdots \cdots \quad I_{n-1}=\frac{V_{R E F}}{2^{n-1} R} \quad I_{n-1}=\frac{V_{R E F}}{2^{n} R}
In−1=2RVREFIn−1=22RVREF⋯⋯In−1=2n−1RVREFIn−1=2nRVREF
6.4 DAC0832与单片机的接口
MCS-51与8位DAC0832的接口
DAC0832是有美国半导体公司(NS)设计的一款8位T型电阻网络D/A转换器,并行数字量输入,电流输出型,建立时间为1us。
DAC0832与单片机的接口简单,易于控制,价格便宜且精度适中,在实际应用系统中被广泛使用。
DAC0832的内部结构图

DAC0832的引脚
DAC0832有20引脚,采用双列直插式封装。

- DIO~DI7:8位数字量输入端。
- ILE:数据允许控制输入线。
- C S ‾ \overline{CS} CS:片选信号。
- W R 1 ‾ \overline{WR1} WR1 W R 2 ‾ \overline{WR2} WR2 :写信号线1,2。
- X F E R ‾ \overline{XFER} XFER:数据传送控制信号输入线。
- IOUT1, IOUT2:模拟电流输出线1,2。
- R f b R_{fb} Rfb:片内反馈电阻引出线,用作外接的运放的反馈电阻。
- V R E R V_{RER} VRER:基准电压输入线。电压范围为-10V~+10v。
- VCC:工作电源输入端,可接+5v~+15V。
- AGND,DGND:模拟地,数字地。
DAC0832的工作方式
通过改变控制端ILE,WR1,WR2,CS和XREF的连接方式,DAC0832可以实现:直通方式、单缓冲和双缓冲三种工作方式,满足不同的应用要求。
-
直通方式:WRI、 WR2、CS、XREF接地,ILE接vCC。
8位输入寄存器和8位DAC寄存器都直接处于导通状态,8位数字量到达DI0~DI7,立即进行D/A转换,输出端得到转换的模拟量。
由于单片机数据总线的分时复用特性,此方式下单片机数据总线不能与D10-DI7直接连接,只能通过单片机独立10并行口(或直接数字芯片输出)与DAC0832连接。
-
单缓冲方式
通过引脚WRI、 WR2、CS、XREF使得两个锁存器的一个处于直通状态,另一个处于受控制状态,或者两个被控制同时导通。此方式下,单片机的数据总线可以与DAC832直接连接,CPU向DAC0832输入一次数据后,DAC就能输出模拟信号,是最常用的一种接口形式。
-
双缓冲方式:
引脚WR1、 WR2、CS、XREF使得两个锁存器的一个处于直通状态,另一个处于受控制状态,或者两个被控制同时导通,DAC0832就工作于双缓冲方式。一般在单片机同时控制多片DAC0832工作时采用。

DAC0832的应用举例
D/A转换器在实际中经常作为波形发生器使用,通过它可以产生各种各样的波形。
基本原理是:利用D/A转换器输出模拟量与输入数字量成正比这一特点,通过程序控制CPU向D/A转换器送出随时间呈一定规律变化的数字,则D/A转换器输出端就可以输出随时间按一定规律变化的波形。


#include <absacc.h> //定义绝对地址访问
#define uchar unsigned char
#define DAC0832 XBYTE[0x7FFF]
void main() {
uchar i;
while(1) {
for (i=0;i<0xff;i++){
DAC0832=i;
}
}
}