目录
- 一、STM32 NVIC中断系统
- 1、NVIC介绍
- 2、Cortex-M4优先级设置
- 二、UART介绍
- 1、原理图介绍
- 2、原理图介绍及编程步骤
- (1)CubeMX设置
- (2)UART 发送
- (3)UART 接收
一、STM32 NVIC中断系统
1、NVIC介绍
STM32G431总共有111个中断源,所以有时难免有两个或者两个以上的中断一起来临,或者正在处理一个中断服务函数时突然又有一个中断来临,以上种种情况微控制器要怎样运行呢?所以微控制器都有一个处理中断的机制。STM32系列芯片用到的机制是:NVIC。
NVIC即嵌套向量中断控制器(Nested Vectored Interrupt Controller)。STM32的中有一个强大而方便的NVIC,它是属于CM4内核的器件。NVIC 控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对CM4内核里面的NVIC进行裁剪,把不需要的部分去掉,所以说STM32的NVIC是CM4的NVIC的一个子集。
NVIC寄存器定义在core_cm4.h文件中,CM4内核支持256个中断,其中包含了16个系统异常和240个外部中断,并且具有256级的可编程中断设置。但 STM32并没有使用CM4内核的全部东西,而是只用了它的一部分。 stm32G431芯片有111个中断,包括9个内核中断和102个可屏蔽中断,具有16级可编程的中断优先级, 我们常用的就是这102个可屏蔽中断。
2、Cortex-M4优先级设置
- STM32中有两个优先级的概念:抢占式优先级和响应优先级,响应优先级也称子优先级,每个中断源都需要被指定这两种优先级。每个中断的优先级由一个8位的寄存器来设定,分为高低两个位段。高位段表示抢占优先级,低位段表示响应(子)优先级。
- 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套在低抢占式优先级的中断中。
- 当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。
- 如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个。
- 如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断向量表中的排位顺序决定先处理哪一个。
二、UART介绍
1、原理图介绍
如图所示,UART1的收发引脚分别是PA10和PA9。具体关于UART的具体内容可以查看之前文章—— 嵌入式硬件学习(五)——定时器和UART 进行学习。
2、原理图介绍及编程步骤
一般在UART的程序设计中,发送功能在主程序的while()中进行发送,而接收功能一般使用的是中断。 所以本次代码分为两部分,以下是实现步骤:
(1)CubeMX设置
- 将RCC中的HSE配置为晶振,时钟配置为80MHz。
- 在GPIO中设置PA9和PA10为UART的收发模式。
- 之后在Connectivity中选择USART1,首先将模式设置为异步(Asynchronous)模式,在下面参数中设置所需波特率、数据位宽、校验位和停止位(这里保留默认),之后在NVIC Settings中选择中断使能。
- 最后保存项目。
(2)UART 发送
(1) 定义一个变量str表示要发送的数据;
char str[24];
(2)在while(1)循环中使用sprintf函数将字符串写入str中;
sprintf(str, "hello world, num: %d", i++);
(3)使用发送函数发送str。
HAL_UART_Transmit(&huart1, str, strlen(str), 50);
(4)完整代码
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
#include "string.h"void SystemClock_Config(void);char str[24];int main(void)
{int i = 0;HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();while (1){sprintf(str, "hello world, num: %d", i++);HAL_UART_Transmit(&huart1, str, strlen(str), 50);HAL_Delay(1000);}
}
(5)实验结果
(3)UART 接收
(1) 定义一个变量num表示要接收的数据;
uint8_t num;
(2)在main主函数中使用HAL_UART_Receive_IT初始化中断,表明将接收到的数据写入num中;
HAL_UART_Receive_IT(&huart1, &num, sizeof(num));
(3)编写回调函数HAL_UART_RxCpltCallback表示接收到中断后要做什么。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{LED_Disp((unsigned char)num);HAL_UART_Receive_IT(&huart1, &num, sizeof(num));
}
(4)完整代码
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
#include "string.h"void SystemClock_Config(void);uint8_t num;int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();HAL_UART_Receive_IT(&huart1, &num, sizeof(num));while (1){}
}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{LED_Disp((unsigned char)num);HAL_UART_Receive_IT(&huart1, &num, sizeof(num));
}
(5)实验结果