stm32中断之串口点灯和串口通信

目录

前言

一、中断简介

1.1中断全过程

1.2中断的作用 

1.3中断优先级

1.4中断响应过程 

1.5外部中断控制器(EXTI)

二、配置外部中断点灯

2.1新建工程

2.2具体配置

 2.3添加代码

三、串口通信中断方式

3.1建立工程

3.2具体配置

3.3代码编写

3.4编译烧录及运行结果

​ 

总结

参考文献





前言

中断通常被定义为一个事件,该事件能够改变处理器执行指令的顺序。这样的事件与 CPU 芯片内外部硬件电路产生的电信号相对应。




一、中断简介

1.1中断全过程

中断是指计算机在执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序,待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。

1.2中断的作用 

速度匹配:可以解决快速的cpu与慢速的外部设备之间的传送数据的矛盾

分时操作:cpu可以分时位多个外部设备服务,提高计算机的利用率

实时响应:cpu能够即使应用处理系统的随机事件,增强系统的实时性

可靠性高:cpu可以处理设备故障及掉电等突发事件,提高系统可靠性

1.3中断优先级

处理器根据不同中断的重要程序设置不同的中断优先级,不同优先级中断的处理原则:

(1)多个中断同时出现时,处理器先响应高优先级的中断

(2)低优先级中断的ISR执行时,可以被高优先级中断再次打断

(3)ISR比App Code拥有更高的执行优先级

1.4中断响应过程 

步骤一:中断源发出请求

步骤二:判断处理器是否允许中断,以及该中断源是否被屏蔽

步骤三:中断优先级排队

步骤四:处理器暂停当前程序,保护断点地址和当前的处理器状态,根据中断类型号查找中断向量表,转到对应的中断服务程序

步骤五:执行中断服务程序

步骤六:恢复被保护的状态,执行中断返回指令,回到被中断的程序

1.5外部中断控制器(EXTI)

EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20 个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿 检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为 中断或者事件,以及触发事件的属性

编号 1 是输入线, EXTI 控制器有 19 个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个 GPIO,也可以是一些外设的事件,这部分内容我们将在后面专门讲解。输入线一般是存在电平变化的信号。

编号 2 是一个边沿检测电路,它会根据上升沿触发选择寄存器 (EXTI_RTSR) 和下降沿触发选择寄存器 (EXTI_FTSR)对应位的设置来控制信号触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号 1 给编号 3 电路,否则输出无效信号0。而 EXTI_RTSR 和EXTI_FTSR 两个寄存器可以控制器需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。
 

编号 3 电路实际就是一个或门电路,它一个输入来自编号 2 电路,另外一个输入来自软件中断事件寄存器 (EXTI_SWIER)。
EXTI_SWIER 允许我们通过程序控制就可以启动中断/事件线,这在某些地方非常有用。我们知道或门的作用就是有 1 就为 1,所以这两个输入随便一个有有效信号 1就可以输出 1 给编号 4 电路。
 

编号 4 电是一个与门电路,它一个输入是编号 3 电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR)。与门电路要求输入都为 1 才输出1,导致的结果是如果 EXTI_IMR 设置为 0 时,那不管编号 3 电路的输出信号是 1 还是 0,最终编号 4 电路输出的信号都为
0;如果 EXTI_IMR设置为 1 时,最终编号 4 电路输出的信号才由编号 3 电路的输出信号决定,这样我们可以简单的控制 EXTI_IMR 来实现是否产生中断的目的。编号 4 电路输出的信号会被保存到挂起寄存器(EXTI_PR) 内,如果确定编号 4 电路输出为 1 就会把

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要在 STM32CubeMX 中配置串口通信和 GPIO 端口。以下是基本步骤: 1. 在 Pinout & Configuration 选项卡中,选择需要使用的 GPIO 端口和管脚,将其配置为输出模式。 2. 在 Connectivity 选项卡中,选择需要使用的串口,配置其波特率、奇偶校验等参数。 3. 在 Code Generator 选项卡中,选择使用 HAL 库,生成代码。 接下来,你可以使用以下代码来实现串口通信点灯: ```c #include "stm32f4xx_hal.h" #include <string.h> UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); uint8_t buffer[20]; uint8_t received[10]; uint8_t led_state = GPIO_PIN_RESET; while (1) { if (HAL_UART_Receive(&huart2, received, 1, HAL_MAX_DELAY) == HAL_OK) { if (received[0] == '1') { led_state = GPIO_PIN_SET; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, led_state); strcpy(buffer, "LED ON\r\n"); HAL_UART_Transmit(&huart2, buffer, strlen(buffer), HAL_MAX_DELAY); } else if (received[0] == '0') { led_state = GPIO_PIN_RESET; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, led_state); strcpy(buffer, "LED OFF\r\n"); HAL_UART_Transmit(&huart2, buffer, strlen(buffer), HAL_MAX_DELAY); } } } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 168; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 4; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } } static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 在此代码中,我们在主函数中使用了一个 while 循环来不断监听串口数据。如果接收到 '1',则点亮 LED 并发送 "LED ON" 消息;如果接收到 '0',则关闭 LED 并发送 "LED OFF" 消息。你可以通过串口调试工具向串口发送 '1' 或 '0' 来测试代码是否正常工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值