2026/4/15 2:00:17
网站建设
项目流程
网站架构原理,编程猫官网,联通沃手WordPress打不开,大网站制作公司需求#xff1a;想实现一个OLED显示#xff0c;按键可以操作的#xff0c;有上下左右选择的功能。遇到的问题#xff1a;OLED显示后按键总是卡死#xff0c;或者反应速度非常慢。首先#xff0c;STM32的delay和vTaskDelay好像是有冲突的#xff0c;毕竟在移植的时候我们…需求想实现一个OLED显示按键可以操作的有上下左右选择的功能。遇到的问题OLED显示后按键总是卡死或者反应速度非常慢。首先STM32的delay和vTaskDelay好像是有冲突的毕竟在移植的时候我们已经把Systick_Handler改动了可能会对Delay有影响所以按键的Delay都改成了vTaskDelay。至于OLED初始化里的Delay为什么没有影响推测应该是在调度器开启之前就没事调度器开启后如果再用Delay就会造成CPU阻塞卡死。卡死问题解决后按键的反应特别慢。OLED某一页的显示肯定是一个临界段要有个保护的不可能说它正显示呢中途来个操作这显示屏才显示一半所以某一页的显示内容需要用临界段保护起来。我原本的代码是在while(1)循环中显示保护taskENTER_CRITICAL()和taskEXIT_CRITICAL()也是在里面的。这样造成按键反应特别慢原因是按键扫描本身也是有vTaskDelay参与的那么这个时候OLED显示就见缝插针的运行它一运行就拖家带口大家都在保护区里不可能说延时结束就回去嘛。可是如果不要while(1)只让OLED显示一遍不知道为什么按键函数就卡死了一种敌不动我不动的感觉。所以while(1)还要保留。以下就是成功运行的案例按照这个格式填补就可以啦~void press(void *pvParameters) { //uint32_t press_num 0; //用来测试执行次数 while(1) { //OLED_ShowNum(0, 0, press_num, 3, 16, 0); //用来测试 keyNum Key_GetNum(); if(keyNum 1) { /* 一些操作 */ } else if (keyNum 2) //下一项 { /* 一些操作 */ } vTaskDelay(1); //留出时间允许调度器执行OLED显示函数 } } void OLED(void *pvParameters) { uint32_t sele_num 0; taskENTER_CRITICAL(); OLED_ShowNum(0, 016, sele_num, 3, 16, 0); /* 其他显示 */ while(1) { } }有人提出“按键的外部中断定时器的状态机写法。外部中断用任务通知然后定时器处理然后通过队列将按键事件发出去”听起来更正规一些有空也可以研究一下