佛山龙江做网站的,长沙建设公司网站,营销网站的渠道构成基本包括,北京本地服务信息网学习内容中断概念中断是计算机系统中一种重要的事件驱动机制#xff0c;用于在特定条件下打断正在执行的程序#xff0c;并跳转到预定义的中断处理程序中执行特定的操作。当发生中断时#xff0c;处理器会立即中止当前正在执行的指令#xff0c;保存当前的执行状态#xf…学习内容中断概念中断是计算机系统中一种重要的事件驱动机制用于在特定条件下打断正在执行的程序并跳转到预定义的中断处理程序中执行特定的操作。当发生中断时处理器会立即中止当前正在执行的指令保存当前的执行状态并执行相应的中断处理程序。中断可以由多种事件触发例如硬件设备的状态改变、定时器溢出、外部信号等。常见的中断事件包括键盘输入、鼠标移动、网络数据到达等。中断的作用是实现对实时事件的及时响应。通过中断计算机系统能够在发生特定事件时立即中断当前任务执行与该事件相关的处理程序以确保及时处理和响应事件。中断能够提高系统的实时性、可靠性和可处理性。中断的处理过程包括以下步骤中断触发某个事件触发中断如硬件设备发出中断请求信号。中断响应处理器检测到中断请求并立即中止当前执行的指令。保存现场处理器保存当前的执行状态如程序计数器、寄存器等以便在中断处理完成后能够恢复执行。中断服务程序执行处理器跳转到预定义的中断服务程序ISR执行与中断相关的操作。中断处理完成中断服务程序执行完成后处理器恢复之前保存的执行状态并继续执行原来的程序。通过合理使用中断可以实现并发处理、异步事件处理和实时响应提高系统的性能和可靠性。中断在各种计算机系统中广泛应用包括嵌入式系统、操作系统和实时系统等。 ARM中的中断优先级ARM Cortex-M 使用了 4 位宽的寄存器来配置中断的优先等级这个寄存器就是中断优先级配置寄存器。GD32中分为抢占优先级和子优先级。数值越小优先级越高分组抢占优先级响应优先级分组00可取值为04可取值为0到15分组11可取值为0到13可取值为0到7分组22可取值为0到32可取值为0到3分组33可取值为0到71可取值为0到1分组44可取值为0到150可取值为0通常我们在代码中来进行配置
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);全局中断的意思是把全局的中断优先级大概定义到一个区间具体到哪种类型的中断自行去配置合适的优先级。因此我们对于一些中断源可以通过以下代码来配置优先级
nvic_irq_enable(xxx_irqn, 6, 0); // 5上面中的全局中断配置配置为抢占优先级为4响应优先级为0那么就把具体中断源的区间给框定了。抢占优先级取值介于0到15响应优先级只能为0。因此上面配置具体中断源优先级为5和0在全局中断源的范畴内。当然你设置一个范围不在范畴内是不生效或者会出现其他问题。通常在FreeRTOS配置外设的中断优先级都在5及以上 (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)FreeRTOS的中断优先级在FreeRTOSConfig.h中configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY配置了中断优先级:
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5默认位置为5。在GD32中优先级的数值越小优先级越高。通过优先级分组可以知道优先级分为0到15个等级。那么FreeRTOS中的这个优先级是什么含义呢开启中断和关闭中断
portENABLE_INTERRUPTS();
portDISABLE_INTERRUPTS();优先级配置注意低于或等于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 优先级的中断函数数值越大优先级越低FreeRTOS的API函数才能对其生效。例如configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY为5则中断函数配置的参数必须为[5, 15]的任意值。所有优先级均为抢占优先级时 中断优先级和任务优先级示例创建timer中断每秒打印数据创建任务扫描按键事件当按键按下关闭所有中断当按键再次按下开启中断观察效果
注意vTaskDelay和delay_1ms的有区别//main.c
#include gd32f4xx.h
#include systick.h
#include stdio.h
#include main.h
#include FreeRTOS.h
#include task.h
#include usart0.hTaskHandle_t start_handler;
TaskHandle_t task_key_handler;void task_key(void *pvParameters) {uint32_t flag 0;FlagStatus pre_state RESET;while(1) {FlagStatus state gpio_input_bit_get(GPIOA, GPIO_PIN_0);if(SET state pre_state RESET) {// 当前高电平, 上一次为低电平,按下pre_state state;if(flag 0) {printf(disable \r\n);// 关闭中断portDISABLE_INTERRUPTS();} else if(flag 1) {// 开启中断printf(enable \r\n);portENABLE_INTERRUPTS();}flag;if(flag 1) flag 0;} else if(RESET state pre_state SET) {// 当前高电平, 上一次为低电平,抬起pre_state state;}delay_1ms(20);}
}void Usart0_recv(uint8_t *data, uint32_t len) {printf(recv: %s\r\n, data);
}static void GPIO_config() {// 时钟初始化rcu_periph_clock_enable(RCU_GPIOA);// 配置GPIO模式gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);
}#define PRESCALER 10000
#define FREQ 1static void TIMER_config() {// 时钟配置rcu_periph_clock_enable(RCU_TIMER5);// 复位定时器timer_deinit(TIMER5);rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);timer_parameter_struct tps;timer_struct_para_init(tps);tps.prescaler PRESCALER - 1; // 分频系数 240 000 000tps.period SystemCoreClock / PRESCALER / FREQ - 1; // 周期计数值 1Hztimer_init(TIMER5, tps);nvic_irq_enable(TIMER5_DAC_IRQn, 5, 0);timer_interrupt_enable(TIMER5, TIMER_INT_UP);timer_enable(TIMER5);
}void TIMER5_DAC_IRQHandler(void) {if(SET timer_interrupt_flag_get(TIMER5, TIMER_INT_UP)) {printf(timer\r\n);}//清除中断标志位timer_interrupt_flag_clear(TIMER5,TIMER_INT_FLAG_UP);
}void start_task(void *pvParameters) {GPIO_config();Usart0_init();TIMER_config();printf(start\r\n);taskENTER_CRITICAL();xTaskCreate(task_key, task_key, 64, NULL, 2, task_key_handler);vTaskDelete(start_handler);taskEXIT_CRITICAL();
}int main(void)
{nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);xTaskCreate(start_task, start_task, 128, NULL, 1, start_handler);vTaskStartScheduler();while(1) {}
}