51单片机结构
端口
在复位状态下,所有的sfr为0,所有的p端口为1
- p0端口: 39-52脚。可以作为通用数据io端口或者地址数据复用总线。作为通用io端口时,有8个ttl的负载,在和外部负载连接时需要外接一个上拉电阻。作为地址数据复用总线时,首先输出外部存储器的低八位地址,然后变成数据总线进行数据输入输出。
当作为io端口时,控制=0,因此上面的三极管输出始终为0,因此需要一个上拉电阻提供信号,当下面三极管为0时,由上拉电阻提供电压,引脚值为1。当下面三极管为1时,电路直接从上拉电阻到接地,引脚值为0,这被称为漏极开路
作为地址数据端口时,控制=1,因此mux连接上面的地址数据io。当地址或数据为1时,上面的三极管输出1,当地址或数据为0时,下面的三极管有效,对外输出为0.- 输入时需要先写1: 输入也就是读引脚,如果原来锁存器是0那么下面的三极管不连通,这样会有上拉电阻的干扰导致结果一定是1。因此先需要向锁存器输入1.
mov a, #0ffh;
mov p0, a; 向端口p0写1,共有8个输入端口
ov a, p0;从p0口输入数据到a- 读引脚和读锁存器是不同的通道,凡是读-修改-写(读锁存器中的值,然后写回锁存器)的操作,cpu都是读锁存器中的值。
- 为了提高电路可靠性,端口引脚和三极管之间需要加一个隔离电路或电阻。
- 输入时需要先写1: 输入也就是读引脚,如果原来锁存器是0那么下面的三极管不连通,这样会有上拉电阻的干扰导致结果一定是1。因此先需要向锁存器输入1.
- p1端口: 1-8脚,单纯的i/o端口。,因为有内部上拉电阻所以不用再外接上拉电阻。
- p2端口: 21-28脚,p2可以作为通用数据io和高八位地址总线口
- p3端口: 10-17脚,通用io端口,多用途端口.作为多用途端口时锁存器为1,因为作为多用途端口时只有一个输出引脚,因此其他情况下代替输出功能始终为0,而串行输出端口的输出接到代替输出功能上。如果是通用io端口,则代替输出功能为1。
口线 | 定义 | 说明 |
---|---|---|
P3.0 | RXD | 串行数据输入端口 |
P3.1 | TXD | 串行数据输出端口 |
P3.2 | INT0 | 外部中断0输入口 |
P3.3 | INT1 | 外部中断1输入口 |
P3.4 | T0 | 计数器0外部信号 |
P3.5 | T1 | 计数器1外部信号 |
P3.6 | /WR | 外部数据存储器写信号 |
P3.7 | /RD | 外部数据存储器读信号 |
程序存储器
存储器分为片内存储器和片外存储器,如果使用片外存储器则需要p0端口和p2端口。
我们可以通过EA端口确定从片内还是片外存储器开始执行。如果EA=0从片外开始执行。EA=1从片内开始执行,并且超过片内存储容量之后会自动跳转到片外存储器。
存储器上有6个单元不能随便使用:
- 0000: 上电时pc指向的单元
- 0003: 外部中断入口地址
- 000b: 定时器t0中断入口地址
- 0013: 外部中断/INT1入口地址
- 001b: 定时器t1中断入口地址
- 0023: 串行口接受传送中断入口地址
片内存储
如图所示为片内ram和rom结构。ram的低128位是通用存储器,高128位有特殊用途。
可以看到ram和rom有地址重叠,但是我们可以使用不同的指令访问ram和rom,因此没有地址冲突。
例如:mov a, 20h
访问ram,而mov R0, #20h; movx a, @R0
访问rom
ram低128字节的地址分布为:
位寻址区有16个byte, 即256个bit。而通过一些指令如setb可以设置这些bit的值,此时每一个bit代表一个地址。
SFR区存放了一些特殊用途的寄存器,通过这些寄存器可以改变cpu的状态
标识符 | 名称 | 地址 |
---|---|---|
ACC | 累加器,存放算术指令结果 | E0 |
B | B寄存器, 乘除法指令使用 | F0 |
PSW | 程序状态字 | D0 |
SP | 栈指针 | 81 |
DPTR | 数据指针,有16位,可以分为DPH,DPL。用于访问片内和片外rom地址 | 83, 82 |
P0 | 端口0 | 80 |
P1 | 端口1 | 90 |
P2 | 端口2 | A0 |
P3 | 端口3 | B0 |
IP | 中断优先级控制器 | B8 |
IE | 中断允许控制寄存器 | A8 |
TMOD | 定时器方式控制寄存器 | 89 |
TCON | 定时器控制寄存器 | 88 |
TH0 | 定时器0初值寄存器高8位 | 8C |
TL0 | 定时器0初值寄存器低八位 | 8A |
TH1 | 定时器1初值寄存器高8位 | 8D |
TL1 | 定时器1初值寄存器低8位 | 8C |
SCON | 串行口控制寄存器 | 98 |
SBUF | 串行口数据缓冲器 | 99 |
PCON | 电源控制寄存器 | 97 |
设备及控制
定时器
- GATE: GATE=0,只要TR=1,计数器就开始工作。GATE=1,需要INT和TR同时为1才开始工作
- C/T: =0时,计数为内部震荡频率的12分频,=1时,为T0和T1引脚的外部事件。
- M1, M0: 用于选择计数模式
- TF1, TF0: 计数器溢出时硬件自动置位TF=1,进入中断后有硬件自动清除
- TR1,TR0: 控制计数器开始或停止工作
- IE1, IE0: 单片机检测到INT引脚上有下降沿时,IE=1,进入中断服务程序自动清除
- IT1, IT0: IT=1,下降沿时触发IE标志。IT=0, 低电平触发IE标志
定时器四种工作模式
- 模式0: 13位计数器模式
当计数器全1时,再来一个1就会触发中断 - 模式1: 16位计数器模式
- 模式2: 自动重装初始值模式
每当产生溢出中断时会自动重装初始值 - 模式3: 组合扩展模式
重新组合两个定时器,将TL0和TH0变为两个独立的计数器。此时TL1和TH1无效,但是可以在转换为模式3前就运行自动装载模式,那么进入模式3后还会自动运行。- TH0的计数脉冲只能来自时钟,因此它只能处于定时模式。
- TH0借用了TR1和TF1来为自己工作,并用TF1作为自己的溢出中断标志
- TH0的计数脉冲只能来自时钟,因此它只能处于定时模式。
串行接口
基本概念:
- 字符帧: 也称为数据帧,它由起始位,数据位和停止位构成
- 波特率: 每秒传输二进制数的个数
- 异步通讯: 发送和接受互相独立,互不同步
相关寄存器:
- 数据缓冲控制器SBUF
SBUF是用来发送和接受数据的寄存器,SFR地址为99,在物理上分为发送和接受两个缓冲器。cpu写SBUF就是发送数据MOV SBUF, A
,读SBUF就是接受数据MOV A, SBUF
串行口控制器SCON(98H)
SM0和SM1是操作模式选择位,共有四种模式
| SM0 SM1 | 功能 | 波特率 |
|-|-|-|
| 0 0 | 同步移位寄存器模式,他会按序发送8bit数据 | fosc / 12 |
| 0 1 | 8位异步通信UART | 可变 |
| 1 0 | 9位异步通信UART | fosc / 64 || fosc / 32 |
| 1 1 | 9位异步通信UART | 可变 |
RI: 完成一帧数据接受的标志位,原始为0,完成后为1且申请中断
TI: 完成一帧数据发送的标志位
RB8: 9位模式中接收到的第9位数据
TB8: 9位模式中发送的第9位数据
REN: 允许接受位,REN=1时允许
SM2: 第一个或第二个模式时,应设为0,否则无法接受中断。当为第二个或第三个模式时,如果SM2=0,则无论第9个数据是什么RI都会激活但不会产生中断。如果SM2=1,则第九位是0时不会激活,第九位是1激活RI且产生中断发送数据和接受数据过程
START:
CLR SCON.TI ;位清零
数据送到累加器a,并修改数据区指针
mov sbuf, a
LOOP;
wait(10)
bne SCON.TI, 1, LOOP
if not done goto START之所以有9位传输是因为最后一位可能是奇偶校验位,在这种情况下,必须让SM2=0.
如果使用模式1,3,则需要启动定时器T1.并将模式调整为自动重装且使用fosc为定时源。计算公式为:$B = \frac{2^{SMOD}}{32} \times (fosc / 12) / [256 - (TH1)]$
中断
中断过程
中断遵循如下规则:
- 低级中断在响应执行过程中可以被高级中断覆盖
- 同时收到同一个级别的中断请求时,cpu响应中断源取决于cpu查询硬件顺序
- 中断允许寄存器:
- EA: 总允许位。EA=0,禁止一切中断
- ES: 串行口中断允许位,=0禁止
- ET1, ET0: T1, T0允许位
- EX1, EX0: int中断允许位
- EA: 总允许位。EA=0,禁止一切中断
- 中断优先级寄存器IP:
- PS: 串行口中断优先级
- PT1, PT0: 定时器中断优先级
- PX1, PX0: int中断优先级
- PS: 串行口中断优先级