中断就是当一个主程序正在执行时,遇到一个中断点 (好比一个闹钟)开始进行中断函数里面的内容,等在中断函数(或内容)跑完后,再重新回到主程序继续执行。通俗点 你正在打游戏,你妈让你去超市买瓶酱油,你就得停下游戏,去超市买瓶酱油回来,然后继续打游戏。
中断的过程:中断请求、中断响应、中断服务、中断返回
根据中断请求能否被 CPU 响应,可分为非屏蔽中断和 可屏蔽中断两种类型。STC15W4K系列单片机的所有中断都属于可屏蔽中断
若要求 T0 中断,除对 ET0 置 1 外,还需将 EA置 1
为什么会有出现中断优先级这种现象呢?就是因为假如你一个主函数,它出现了两个中断,但两个中断呢,他又是同时发生,编译器或者系统,他就不知道哪一个中断先跑,所以这时候他就懵了,所以你要先设置中断优先级,让单片机知道先执行哪一个中断。
就好比说你女朋友和你好兄弟同时给你发消息,你先回复谁的消息呢?
STC15W4K 系列单片机的中断优先等级分为两个优先级,由PX1
和PX0
设置。当处于同一个中断优先级时,前 5 个中断的自然优先顺序由高到低是外部中断0,定时器/计数器0溢出中断,外部中断1 ,定时器/计数器1溢出中断,串行口中断
中断号就是告诉机器你要执行哪个中断。当优先级相同时,中断号小的先执行。
中断源 | 优先级 | 中断向量号 | 中断向量地址 |
---|---|---|---|
INT0 – 外部中断0 | 最高 | 0 | 0003H |
T0 – 定时器/计数器0中断 | 第2 | 1 | 000BH |
INT1 – 外部中断1 | 第3 | 2 | 0013H |
T1 – 定时器/计数器1中断 | 第4 | 3 | 001BH |
串行口中断 | 第5 | 4 | 0023H |
T2 – 定时器/计数器2中断 | 最低 | 5 |
中断响应的条件:
1-中断允许位为1,开启总中断
2-中断源发出中断请求
3-无同级或跟高级优先级中断在执行子程序
序号 | 符号 | 说明 |
---|---|---|
D7 | EA | 总中断运行控制位 |
D6 | - | - |
D5 | - | - |
D4 | ES | 串行口1中断允许位 |
D3 | ET1 | 定时器/计数器T1中断允许位 |
D2 | EX1 | 外部中断1中断允许位 |
D1 | ET0 | 定时器/计数器T0中断允许位 |
D0 | EX0 | 外部中断0中断允许位 |
序号 | 符号 | 说明 |
---|---|---|
D7 | TF1 | 定时器1溢出标志位 |
D6 | TR1 | 定时器1运行控制位 |
D5 | TF0 | 定时器0溢出标志位 |
D4 | TR0 | 定时器0运行控制位 |
D3 | IE1 | 外部中断1请求标志 |
D2 | IT1 | 外部中断1触发方式控制位 |
D1 | IE0 | 外部中断0请求标志位 |
D0 | IT0 | 外部中断0触发方式控制位 |
51单片机有两个外部中断源——外部中断0、外部中断1。
分别由单片机的INT0/P3.2
、INT1/P3.3
引脚触发。
触发方式有 **仅下降沿触发(IT=1)和上升沿和下降沿均可触发(IT=0)**两种
由原理图可知, S5对应外部中断0,S4对应外部中断1。
外部中断0
void ex0_init()
{
IT0 = 1; //设置外部中断触发方式
//0 - 下降沿和上升沿均可触发 1 - 配置成下降沿触发
EX0 = 1; //开启外部中断0
EA = 1; //开启总中断
}
外部中断1
void ex1_init(void)
{
IT1 = 1; //配置成下降沿触发
EX1 = 1; //开启外部中断1
EA = 1; //打开总中断
}
外部中断0
void ex0_isr() interrupt 0
{
delay_ms(10); //延时10ms消抖
if(ex0_k == 0)
{
led=~led; //要实现的逻辑
}
}
外部中断1
void ex1_isr() interrupt 2
{
delay_ms(10); //延时10ms消抖
if(ex1_k == 0)
{
led=~led; //要实现的逻辑
}
}
1.振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡 周期)。
2.状态周期:2 个振荡周期为 1 个状态周期,用 S 表示。振荡周期又称 S 周 期或时钟周期。
3.机器周期:1 个机器周期含 6 个状态周期,12 个振荡周期。
4.指令周期:完成 1 条指令所占用的全部时间,它以机器周期为单位
STC15W4KS 系列单片机有5个 16 位定时/计数器。,因为既可以定时,又可以计数,故称之为定时器/计数器。 定时器/计数器和单片机的 CPU 是相互独立的。定时器/计数器工作的过程是自动完成的,不需要 CPU 的参与。 单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加 1。 定时/计数器的实质是加 1 计数器(16 位),由高8位和低 8 位两 个寄存器 THx 和 TLx 组成。它随着计数器的输入脉冲进行自加 1,也就是每来一个脉冲,计数器就自动加 1,当加到计数器为全1时,再输入一个脉冲就使计数 器回零,且计数器的溢出使相应的中断标志位置 1,向 CPU 发出中断请求 (定时 /计数器中断允许时)
T0 的定时/计数器计满溢出标志是 TF0、工作在计数时,计数脉冲引脚为P3.4
T1 的定时/计数器计满溢出标志是TF1 、工作在计数时,计数脉冲引脚为 P3.5
定时器的工作过程:以某个时间基准做加一计数,至溢出时TF0,TF1硬件置一,向CPU发送中断请求,当响应中断请求时,TF1,TF0自动撤销。
序号 | 符号 | 说明 |
---|---|---|
D7 | EA | 总中断运行控制位 |
D6 | - | - |
D5 | - | - |
D4 | ES | 串行口1中断允许位 |
D3 | ET1 | 定时器/计数器T1中断允许位 |
D2 | EX1 | 外部中断1中断允许位 |
D1 | ET0 | 定时器/计数器T0中断允许位 |
D0 | EX0 | 外部中断0中断允许位 |
序号 | 符号 | 说明 |
---|---|---|
D7 | TF1 | 定时器1溢出标志位 |
D6 | TR1 | 定时器1运行控制位 |
D5 | TF0 | 定时器0溢出标志位 |
D4 | TR0 | 定时器0运行控制位 |
D3 | IE1 | 外部中断1请求标志 |
D2 | IT1 | 外部中断1触发方式控制位 |
D1 | IE0 | 外部中断0请求标志位 |
D0 | IT0 | 外部中断0触发方式控制位 |
TCON 的 低 4 位用于控制外部中断
TCON 的高 4 位用于控制定时/计数器的启动和中断申请 。
工作方式寄存器 TMOD 用于设置定时/计数器的工作方式,
软启动:一条指令启动定时器
硬启动:除了指令启动外还需要外围硬件电路P3.2/P3.3来帮我们提供信号
设置要计时的时间
//定时器0
TH0 =
TL0 =
//定时器1
TH1 =
TL1 =
最好背下来 AUXR
->TMOD
->TL和TH
->TR
->ET
->EA
定时器0初始化
void Time0_init(void)
{
//定时器部分
AUXR |= 0x00 ; //0x80 1T模式 0x00 12T模式 可不写
TMOD &= 0xF0; //设置定时器模式 低四位清0 16位自动重载
// TMOD |= 0x01; 定时16位不自动
// TMOD |= 0x02; 8位自动
// +4变为计数模式
TL0 =; //12T模式可以(65536-us数)/256
TH0 =; //12T模式可以(65536-us数)%256
TR0=1;
//中断部分
ET0=1;
EA= 1;
}
time0
void t0_isr() interrupt 1
{
}
time1
void t1_isr() interrupt 3
{
}
串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。
对应的引脚
单工: 数据传输只支持数据在一个方向上传输
半双工:允许数据在两个方向上传输,但在某一时刻,只允许数据在一个方向上传输
全双工: 允许数据同时在两个方向上传输
异步通信:
以字符为单位组成的字符帧进行数据传输,要求传输速率一致(发送一个字符的时间和接受一个字符的时间相同,协议必须一致)
同步通信:
发送方和接受方必须同频同相,有一根时钟线。
字符帧:
波特率就是每秒钟传输的二进制位数。
波特率的单位是每秒比特数(bps),常用的单位还有:每秒千比特数Kbps,每秒兆比特数Mbps。
假设波特率为:115200,8位数据位,无校验位,一个停止位,一个开始位(共10位)则传输一位的时间是:t = 1/115200 (s) ,而传输一个字节需要10位,那么传输一个字节的时间是: t (1byte) = 10/115200 (s) 则一秒能传输的字节数是: 1/t = 115200 / 10 = 11520 byte
通信两端的接口类型必须匹配,否则无法进行通信,比如单片机和单片机直接,他们的电平全部是TTL电平,可以进行通信,但是电脑和单片机直接,前者是RS232电平,所以没有办法直接通信,需要进行电平的转换,才能进行通信
情况一:单片机和单片机直接,都是使用TTL电平可以直接通信
情况二:单片机和PC直接,需要进行电平转换
一般为1个起始位+数据(8位)+奇偶校验位(无)+停止位(1位)。串口标准规定串口空闲时的电平应该是高电平,所以起始位的电平应该是拉低。同理停止位应该是拉高。
SM0和SM1:
SM2:允许方式2或方式3多机通信控制位 (后面多级通信具体介绍);
REN:允许/禁止穿行接收控制位。
○ 由软件置位REN**,REN=1为允许串行接收状态,可启动串行接收器RxD,开始接收信息;
○ 软件复位REN,即REN=0,则禁止接收;
TB8:在方式2或方式3,它为要发送的第9位数据,按需要由软件置位或清0((后面多级通信具体介绍));
RB8:在方式2或方式3,是接收到的第9位数据(后面多级通信具体介绍);
TI: 发送中断请求标志位。在方式0,当串行发送数据第8位结束时,由内部硬件自动置位,即TI=1,向主机请求中断,响应中断后必须用软件复位,即TI=0。在其他方式中,则在停止位开始发送时由内部硬件置位,必须用软件复位;
RI:接收中断请求标志位。在方式0,当串行接收到第8位结束时由内部硬件自动置位RI=1,向主机请求中断,响应中断后必须用软件复位,即RI=0。
SMOD:波特率选择位。
○ 当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍;
○ SMOD=0,则各工作方式的波特率不加倍。复位时SMOD=0。
SMOD0:帧错误检测有效控制位。
○ 当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;
○ 当SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。复位时SMOD0=0
只能用定时器1设置波特率,并且要关闭定时器中断,开启IE中的ES表示串口中断。
void uart_init()
{
SCON=0x50; //0x50 方式1,允许接收和发送
//0x40 只允许发送
//PCON |= 0x80; 波特率倍速
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //定时器1 8位位
TL1 = 0xF9; //0xF9 4800 不倍速
TH1 = 0xF9; //0xF3 4800 倍速
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES=1; //开启串口中断
EA=1; //开启总中断
}
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte;
while(TI==0); // 发送结束TI==1
//所以TI=0时表示在发送在这等待
TI=0; //软件清零
}
void UART_Routine() interrupt 4
{
if(RI==1) //如果接收标志位为1,接收到了数据
{
//这里写具体要实现的逻辑,接受到的数据在SBUF中
UART_SendByte(SBUF); //将受到的数据发回串口,方便调试
RI=0; //接收标志位清0
}
}
多机通信充分利用了单片机内部的多机通信控制位SM2。当从机SM2=1时,从机只接收主机发出的地址帧(第九位为1),对数据帧(第九位为0)不予理睬;而当SM2=0时,可接收主机发送过来的所有信息。
多机通信的过程如下:
(1)所有从机SM2均置1,处于只接收地址帧状态。
(2)主机先发送一个地址帧,其中前8位数据表示地址,第9位为1表示该帧为地址帧。
(3)所有从机接收到地址帧后,进行中断处理,把接收到的地址与自身地址相比较。地址相符时将SM2清成0,脱离多机状态,地址不相符的从机不作任何处理,即保持SM2=1。
(4)地址相符的从机SM2=0,可以接收到主机随后发来的信息,即主机发送的所有信息。收到信息TB8=0,则表示是数据帧,而对于地址不符的从机SM2=1,收到信息TB8=0,则不予理睬,这样就实现了主机与地址相符的从机之间的双机通信。
(5)被寻址的从机通信结束后置SM2=1,恢复多机通信系统原有的状态。