1、中断的原理
2、M3内核的中断结构
3、STM32的中断
4、编写外部中断和USART中断
你在图书馆学习stm32,你朋友突然要来学校找你,给你打电话,说,我坐公交,快到的时候给你打电话,那么,你有两种方式,一种就是一直拿着手机,等着电话响;另一种就是你先学习,等电话响的时候才去接电话,然后把你同学带上来。
1.中断的原理:
例如:判断一个按键是否按下?
1--查询 (软件-- 一直去读该管脚是否被按下)
while(1)--CPU一直在判断按键是否按下!!!
2--中断:(硬件产生的--当CPU检测到按键按下之后,立刻去执行相关函数)
1.中断:预先知道某件事情要发生,但是不知道什么时间发生,我们就把该事件分配为中断。(当事件发生,CPU执行中断服务函数)
2.中断源:能够发生中断的这个事件
3.中断服务函数:当CPU检测到有中断发生后,自动去执行的函数。
中断执行过程:
1、响应中断(保存原CPU执行中的数据) ---接到同学的电话
2、执行中断(执行中断服务函数) ---下楼去把同学接上来
3、退出中断(恢复原CPU执行的数据 ) ---继续学习
4. 中断优先级:
当多个中断同时到达,根据中断优先级的大小,去执行中断服务函数。
2、M3内核的中断结构:
1.STM32 -- CPU -- M3内核
对于优先级执行中断的顺序是通过中断的管理者NVIC来决定的;
M3内核中有一个NVIC中断控制器:中断的管理者--根据优先级分配中断执行的顺序!
2.查看M3技术手册:
M3提供了256个中断源 ----16个内核中断+240个核外中断
优先级:占先优先级+次优先级
优先级分组:8个位0000 0000来配置--0~255 0000 0000~1111 1111
占先优先级+次优先级==一共8个位配置!
在STM32中,只使用了4个位来配置占先优先级+次优先级
0~15
0000 =占先优先级+次优先级
无 0000
0(0~1) 000(0~7)
00(0~3) 00(0~3)
000(0~7) 0(0~1)
0000(0~15) 无
当中断正在执行的时候:又来了一个中断
占先优先级:可以实现中断的嵌套---如果占先优先级高,那么可以暂停正在执行的中断, 而去执行该中断;
A: 1 2
B:1 0
不同时发生,占先优先级可以实现抢占;
同时发生,并且占先优先级相同,次优先级可以决定谁先执行!
次优先级:如果占先优先级相同,中断不可以被打断-----
优先级数字越小,优先级越高;
占先 次级
A 1 1
B 2 1
C 2 2
C中断在执行: 那么A来的时候,执行中断A;B来的时候,仍然先执行C;
3.STM32的中断:
1.STM32F103--HD共有60个中断通道
内部中断通道50个+外部中断通道10个;
内部中断:stm32内部控制器引起的中断---串口接收数据
外部中断:外部信号电平引起的中断 ----按键
对中断通道进行管理--NVIC:
2.外部中断:通过外部中断线控制的
打开STM32中文参考手册: -- 9 中断和事件
外部中断线:19个
GPIOA ~ G:7个端口分为16个外部中断:
PA0 PB0 PCO PD0 PE0 PF0 PG0 --- EXTI0
PA1
.
PA15 PB15 PC15 PD15 PE15 PF15 PG15 --- EXTI15
EXTI线16连接到PVD输出(电源管理)
EXTI线17连接到RTC闹钟事件
EXTI线18连接到USB唤醒事件
19个中断线对应了10个不同的外部中断通道---
中断线0、1、2、3、4分别对应一条中断通道;
Line9..5共用一条中断通道;
Line15..10 对应了一条中断通道;
每条中断通道对应一个中断服务函数--hd.s
EXTI0_IRQHandler ; EXTI Line 0
EXTI1_IRQHandler ; EXTI Line 1
EXTI2_IRQHandler ; EXTI Line 2
EXTI3_IRQHandler ; EXTI Line 3
EXTI4_IRQHandler ; EXTI Line 4
EXTI9_5_IRQHandler ; EXTI Line 9..5
EXTI15_10_IRQHandler ; EXTI Line 15..10
例如
STM32外部中断的过程:
检测电路 -- 中断挂起(通知CPU) -- 判断该中断是否允许发生中断 -- 执行中断
4、软件编程外部中断
1、KEY1作为中断源 --
查看原理图:KEY1 -- PA0 -- EXTI0
2、初始化GPIO口,并且初始化EXTI0
3、初始化NVIC通道
EXTI0_IRQHandler ; EXTI Line 0
EXTI1_IRQHandler ; EXTI Line 1
EXTI2_IRQHandler ; EXTI Line 2
EXTI3_IRQHandler ; EXTI Line 3
EXTI4_IRQHandler ; EXTI Line 4
EXTI9_5_IRQHandler ; EXTI Line 9..5
EXTI15_10_IRQHandler ; EXTI Line 15..10
4、编写中断服务函数。
格式 : void 函数名(void)
函数名: STM32库已经定义好了,我们不能自己随便定义。--相当于库函数-- 不用自己定义,声明,也不用调用!!!
串口中断:
注意:1、使能串口中的中断类型(接收 发送等等)
2、该中断为内部中断,只需要配置NVIC管道就行。
外部中断配置步骤:
//PA0---按键
//1.打开时钟 端口A 和AFIO时钟
//2.映射---把中断线EXTI0映射到PA0;
GPIO_EXTILineConfig();
//3.配置中断线EXTI0;
EXTI_Init();
//4.配置NVIC---优先级配置 0000 ---优先级分组
NVIC_Init();
//5.执行中断--中断服务函数
Hd.s---- void 函数名(void)
If(EXTI_GetITStatus(EXTI_Line0)==SET)
{
清除中断标志位---往PR写1;
}
---优先级分组 在主函数里面,只分配一次就行;
NVIC_PriorityGroup_2
0~3 0~3
作业:
1、外部按键的4个中断 --1个按键控制1个灯的亮灭
2.用2个不同的中断去实现中断的执行过程--中断嵌套
//1. 有一个中断在执行,占先优先级高的中断来了;
在主函数里面让一个灯闪烁;
2、串口接收中断,实现字符串接收
"123" 蜂鸣器响
"456" 蜂鸣器不响
*作为开始接收数据; *123 **12*3#
以#作为结束接收数据;
"123" 蜂鸣器响
"456" 蜂鸣器不响
注意点:
- 中断里面最好不要加延时。
- 中断不要写while(1),死循环。
- 中断里面不要写太长程序--中断执行时间要短。--可以用flag标志位跳出中断,需要执行的操作写在主函数里面,判断flag来执行。效果一样但是中断服务函数里程序会减少。
串口中断:
- 串口协议
- 配置为接收中断并使能
- 配置NVIC
- 打开串口--USART_Cmd();
- 中断服务函数
If(是否是接收中断)
{
接收数据;
清中断标志;
}