一个网站 两个域名,网站开发 项目规划 怎么写,杭州工业设计公司有哪些,平顶山专业做网站公司上图为单片机内部的中断结构框图#xff0c;可以看到STM32有很多外设模块可以产生中断#xff0c;所以需要中断优先级对中断进行排序。图中NVIC(Nested Vector Interrupt Controller)嵌套向量中断控制器是Cotex-M内核里专门管中断的硬件模块。可以把NVIC当成中断的 “总调度室…上图为单片机内部的中断结构框图可以看到STM32有很多外设模块可以产生中断所以需要中断优先级对中断进行排序。图中NVIC(Nested Vector Interrupt Controller)嵌套向量中断控制器是Cotex-M内核里专门管中断的硬件模块。可以把NVIC当成中断的 “总调度室”所有中断请求都先到 NVICNVIC 按优先级判断哪个先处理、能不能嵌套没有 NVIC中断会乱序、无法嵌套、响应慢抢占优先级更高会发生中断嵌套而子优先级用来排队在抢占优先级相同的情况下。注意数字越小中断优先级越高。如果抢占优先级与子优先级都相同那么按照先来后到的顺序处理。#本期实验通过单片机上的串口把单片机与电脑连接在一起然后通过电脑上的串口调试助手给我们的单片机发送命令来控制板载LED的闪灯速度。发0LED慢闪。发1LED正常闪烁。发2LED快闪。让USART的RXNE来触发中断c运行#include stm32f10x.h // 引入STM32F103系列标准库头文件 /************************** 硬件宏定义 **************************/ // LED引脚定义PC13开发板板载LED常用引脚 #define LED_PIN GPIO_Pin_13 // LED对应引脚 #define LED_PORT GPIOC // LED对应GPIO端口 #define LED_RCC RCC_APB2Periph_GPIOC // LED端口时钟 // USART1引脚定义TXPA9RXPA10 #define USART1_TX_PIN GPIO_Pin_9 #define USART1_RX_PIN GPIO_Pin_10 #define USART1_PORT GPIOA #define USART1_RCC RCC_APB2Periph_GPIOA /************************** 全局变量 **************************/ // LED闪烁间隔单位ms默认500ms正常闪烁 uint16_t g_led_flash_interval 500; /************************** 函数声明 **************************/ void Delay_ms(uint16_t ms); // 毫秒级延时函数 void LED_Init(void); // LED初始化开漏模式 void USART1_Init(void); // USART1初始化开启接收中断 void USART1_IRQHandler(void); // USART1中断服务函数 /************************** 延时函数 **************************/ /** * brief 毫秒级延时函数软件延时适配STM32F103 * param ms: 延时时间单位ms * retval 无 */ void Delay_ms(uint16_t ms) { uint16_t i 0, j 0; // 循环延时1ms≈1100次内层循环可根据实际硬件微调 for(i 0; i ms; i) { for(j 0; j 1100; j) { // 空循环仅消耗CPU时钟 } } } /************************** LED初始化函数 **************************/ /** * brief LED初始化PC13开漏输出模式 * note 开漏模式只能拉低电平高电平需依赖上拉电阻开发板自带 * param 无 * retval 无 */ void LED_Init(void) { // 定义GPIO初始化结构体标准库固定用法 GPIO_InitTypeDef GPIO_InitStruct; // 1. 使能GPIOC时钟外设使用前必须先开时钟 RCC_APB2PeriphClockCmd(LED_RCC, ENABLE); // 2. 配置PC13引脚参数 GPIO_InitStruct.GPIO_Pin LED_PIN; // 选择PC13引脚 GPIO_InitStruct.GPIO_Mode GPIO_Mode_Out_OD; // 开漏输出模式 GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; // IO口翻转速度50MHz // 3. 应用配置到GPIOC端口 GPIO_Init(LED_PORT, GPIO_InitStruct); // 4. 初始状态熄灭LED开漏模式SetBits释放引脚由上拉电阻拉至高电平 GPIO_SetBits(LED_PORT, LED_PIN); } /************************** USART1初始化函数 **************************/ /** * brief USART1初始化9600波特率8N1开启RXNE接收中断 * note RXNE中断接收数据寄存器非空时触发中断 * param 无 * retval 无 */ void USART1_Init(void) { // 定义GPIO、USART、中断优先级初始化结构体 GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; // 1. 使能时钟USART1时钟 GPIOA时钟TX/RX引脚 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | USART1_RCC, ENABLE); // 2. 配置TX引脚PA9复用推挽输出串口TX必须用复用模式 GPIO_InitStruct.GPIO_Pin USART1_TX_PIN; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(USART1_PORT, GPIO_InitStruct); // 3. 配置RX引脚PA10浮空输入串口RX推荐浮空输入 GPIO_InitStruct.GPIO_Pin USART1_RX_PIN; GPIO_InitStruct.GPIO_Mode GPIO_Mode_IN_FLOATING; // 浮空输入 GPIO_Init(USART1_PORT, GPIO_InitStruct); // 4. 配置USART1参数 USART_InitStruct.USART_BaudRate 9600; // 波特率9600串口调试助手需对应 USART_InitStruct.USART_WordLength USART_WordLength_8b; // 8位数据位 USART_InitStruct.USART_StopBits USART_StopBits_1; // 1位停止位 USART_InitStruct.USART_Parity USART_Parity_No; // 无校验位 USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None; // 无硬件流控 USART_InitStruct.USART_Mode USART_Mode_Rx | USART_Mode_Tx; // 开启收/发模式 USART_Init(USART1, USART_InitStruct); // 应用配置到USART1 // 5. 配置USART1中断优先级NVIC NVIC_InitStruct.NVIC_IRQChannel USART1_IRQn; // 选择USART1中断通道 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 1; // 抢占优先级10-3数值越小优先级越高 NVIC_InitStruct.NVIC_IRQChannelSubPriority 1; // 子优先级1 NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE; // 使能该中断通道 NVIC_Init(NVIC_InitStruct); // 应用中断配置 // 6. 开启USART1接收中断RXNE接收数据寄存器非空中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 7. 使能USART1外设 USART_Cmd(USART1, ENABLE); } /************************** USART1中断服务函数 **************************/ /** * brief USART1中断服务函数处理RXNE接收中断 * note 中断函数名必须与启动文件中的定义一致否则无法触发 * param 无 * retval 无 */ void USART1_IRQHandler(void) { uint8_t recv_data 0; // 存储接收到的串口数据 // 1. 判断是否是RXNE接收中断避免处理其他中断 if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { // 2. 读取接收的数据读取后RXNE标志会被硬件清0但建议手动清 recv_data USART_ReceiveData(USART1); // 3. 根据接收的指令修改LED闪烁间隔 switch(recv_data) { case 0: // 接收字符0慢闪1000ms间隔 g_led_flash_interval 1000; break; case 1: // 接收字符1正常闪500ms间隔 g_led_flash_interval 500; break; case 2: // 接收字符2快闪100ms间隔 g_led_flash_interval 100; break; default: // 无效指令保持当前闪烁速度 break; } // 4. 手动清除RXNE中断标志位确保下次中断能正常触发 USART_ClearITPendingBit(USART1, USART_IT_RXNE); } } /************************** 主函数 **************************/ /** * brief 程序入口函数 * note 主循环根据全局变量控制LED翻转实现不同速度闪烁 * param 无 * retval 无 */ int main(void) { // 1. 初始化外设 LED_Init(); // 初始化LED开漏模式 USART1_Init(); // 初始化USART1开启接收中断 // 2. 主循环死循环程序核心逻辑 while(1) { // 翻转LED电平读取当前输出电平取反后写入 // 开漏模式ResetBits拉低亮SetBits释放灭 GPIO_WriteBit(LED_PORT, LED_PIN, !GPIO_ReadOutputDataBit(LED_PORT, LED_PIN)); // 根据全局间隔变量延时实现不同速度闪烁 Delay_ms(g_led_flash_interval); } }