参考: STC89C51RC-RD.pdf (stcmcudata.com)
一、中断系统
1.中断概述
中断是响应内部和外部随机事件(紧急事件实时处理),单片机CPU暂停当前工作,转去处理这个事件,再回到原来被中断的地方继续工作的过程。
2.中断系统
3.中断寄存器
1.IE中断允许寄存器(可位寻址)
2.TCON定时器/计数器中断控制寄存器(可位寻址)
3.SCON串行控制寄存器(可位寻址)
4.T2CON中断控制寄存器(可位寻址)有时钟标志
5.优先级控制寄存器
4.中断优先级
4个中断优先级,通过控制相关寄存器
00、01、10、11
优先级0、1、2、3
两条基本原则:
1.低优先级中断可被高优先级中断所中断,反之不能
2.任何一种中断,一旦得到响应,不会再被它的同级中断所中断
同时受到几个同一优先级中断的情况下,响应顺序如下
5.中断处理过程
当某个中断产生且被CPU响应,主程序被中断,接下来执行如下操作
1.当前正被执行的指令全部执行完毕
2.PC值被压入栈(保护断点)
3.现场保护
4.阻止同级别其他中断
5.将中断向量地址装载到PC(程序计数器)
6.执行中断服务函数
7.恢复现场,再执行中断返回指令RET1
二、定时器
1.定时器/计数器概述
定时器/计数器是用来实现定时控制、延时、频率测量、脉冲宽度测量、信号发生、信号检测、波特率发生器等。
定时器----可根据设置时间进行计时
计数器----可对输入脉冲数进行统计
定时器和计数器本质是一样的,前者对时钟脉冲进行计数,后者对外来脉冲进行计数
2.定时器/计数器基本工作原理
3.相关寄存器
TCON控制寄存器:
启动控制位TR1/TR0(1启动,0停止)
溢出标志位TF1/TF0(1溢出,0清零)
TMOD模式寄存器:
GATE:控制是否引入外部输入
C/T、M1、M0:
4.定时器程序编写步骤
1.设置系统CLK
2.设置工作模式 TMOD
3.设置初值 TH\TL
4.启动定时器 TR
5.打开中断、总中断使能 IT、EA
三、串口
1.串行口的结构
2.数据接收和发生过程
串行通信口接收到一字节数据后,置接收中断标志RI,通知CPU到SBUF读取数据。
当一字节写入到发送SBUF中,便可以通过串行通信接口将数据发送出去。发送完毕后置发送中断标志TI,通知CPU数据已发送。
3.相关寄存器
SCON串行状态控制器(可位寻址)
SBUF数据缓冲寄存器
SBUF既是发送缓冲寄存器又是接收缓冲寄存器,物理上发送和接收各有一个SBUF缓冲寄存器
CPU写SBUF就是修改发送寄存器,读SBUF就是读接收寄存器。接收器是双缓冲的,以避免在接收下一帧数据之前,CPU未能及时的响应接收器的中断,没有把上一帧的数据读走而产生两帧数据重叠的问题。对于发送器,为了保持最大的传输速率,一般不需要双缓冲,因为发送时CPU是主动的,不会产生重叠问题。
PCON电源控制寄存器
SADEN和SADDR
SADEN为从机地址掩模寄存器(地址为B9H,复位值为00H)
SADDR是从机地址寄存器(地址为A9H,复位值为00H)
4.工作方式一
四、test-C51-使用printf
51单片机重定义putchar发送单个字符函数,AMR处理器如stm32重定义的函数名fputc
#include"reg52.h"
#include <intrins.h>
#include <stdio.h>
typedef unsigned char u8;
void UART_Init(void)
{
SCON |= 0x50; //串口方式1,接收REN使能
TMOD |= 0x20; //定时器1,方式二8位自动装载
PCON &= 0x7F; //SMOD=0,波特率不加倍
TL1 = 0xFD; //bps9600 重装载值FD
TH1 = 0xFD;
TR1 = 1; //启动定时器
ES = 1; //串口中断
EA = 1; //总中断使能
}
void UART_SndByte(u8 b)
{
SBUF = b;
while(TI == 0); //等待发送完毕
TI = 0; //发送完,清除发送标志
}
void UART_SndString(u8 *s)
{
while(*s)
{
UART_SndByte(*s++);
}
}
int main(void)
{
UART_Init();
UART_SndString("hello world\r\n");
printf("hello world\r\n");
while(1);
}
void uart(void) interrupt 4 //中断4号 串口
{
//unsigned char temp;
if(RI) //接收到数据
{
RI = 0;
//temp = SBUF;
//接收到的数据发送到pc
UART_SndByte(SBUF);
}
//还有TI中断标志
}
char putchar(char ch)
{
UART_SndByte(ch);
return ch;
}