蓝桥杯嵌入式开发经验分享(4.按键的配置)

作者:马一飞                                                        

 QQ:791729359         

 

同样,与LED的配置相同,我们先创建一个HARDWARE目录,并且创建一个IO.c和IO.h放在HARDWARE目录下。同时还要吧IO.c文件放入到工程里。还要把.h文件的路径告诉编译器。

那么到这一步,我们的准备工作就做好了,可以开始准备编写独立按键的代码。

编写按键初始化函数

void KEY_Init(void)  //按键初始化函数
{
		GPIO_InitTypeDef GPIO_InitStructure;
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
	
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
		GPIO_Init(GPIOB, &GPIO_InitStructure);
}

在编写的过程中我们还得看一下开发板电路原理图,确定好按键是连接在哪个引脚上

        很显然,我们能够很清楚的看到,他分别连接在了PA0,PA8,PB1,PB2的引脚上。那我们就可以开始对他们进行编程了。

        首先必不可少的要先使能PA,PB引脚的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);

        那么这个函数的原型我们可以再RCC的库函数里找到。同时,我们对这个引脚进行初始化。

GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); 

        这个函数原型在GPIO的库函数里可以找到。(具体寻找方法请参考LED章节)

        并且把这PA0,PA8,PB1,PB2的模式设置为上拉输入,也就是GPIO_Mode_IPU。因为我们这个按键另外一端连接的是地,当我们按键没有按下的时候,我们的引脚会被上拉电阻拉高,获取到高电平,只有当我们按下按键时,引脚的电平才会变为低电平。

        同时我们还在IO.h里进行了一个宏定义

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

        这个函数的作用是可以用来获取某个引脚的电平,返回值就是它的电平状态(高电平返回1,低电平返回0)。我们进行一个宏定义可以使我们接下来更方便的获取引脚的电平值(注意:宏定义后一定不要加分号)。

        接下来我们就可以开始撰写按键的读取函数了(按键的读取函数编写比较长,我们就截取一部分来讲解,因为下面都是一样的)

        可以很明显的看到,我定义了4个16位的静态无符号整型变量,这4个静态变量的作用就是用来计数的。当我们按键一被按下时候,我们的key1_sum 加一,然后就可以执行短按按键的程序,直到我们松开了按键一后,key1_sum才会清零。当然,大家也可以自己编写自己的按键程序,每个人都有自己的代码风格,我的这样编写按键读取函数的好处是可以使用长短按键的功能,那么这个功能的实现后面在讲解。

        在编写完按键读取函数后,我们要通过定时器,来扫描我们的按键函数,我们现在main.c里面定义一个按键读取标志位

同时在主循环里面还得编写,当这个按键读取标志位被置1时候,按键就进行一次读取,读取完成后就标志位清零。

 这个方式有点类似于我们任务调度一样,只有当这个标志位置1了,才代表我们可以读取这个按键函数,如果没置1的话我们则不读取。

        那么我们这个KEY_Flag到底什么时候才置1呢,这时候我们就要开始用我们的滴答定时器来定时了。我们去到stm32f10x_it.c这个文件里,添加这些命令。

        之前说过,这个滴答定时中断函数我们可以看做是一个1ms的定时器,我们在定时器里面计数,当计数值等于50(也就是50ms),我们就把计数值清零,同时KEY_Flag 置1,我们就可以在主循环里读取我们按键函数了。也就是说来理想状态下,每50ms就会读取一次KEY_Read()这个函数,那么就会有人问,这也就是在理想情况,那么我们再主循环里面添加了很多其他的函数,那么KEY_Read()的读取间隔就会大于50ms,答案是一定会的,但是在蓝桥杯里我们可以不考虑这个情况,因为蓝桥杯嵌入式的比赛中,其他外设所考的模块里,没有一个模块是需要用到长时间的延时函数的,因此这个干扰在蓝桥杯中可以忽略不计,我们直接按照理想状态来编写就好。

            同时也会有人问,为什么要50ms扫描一次KEY_Read()呢?想了解这个问题的话建议还是私聊我吧,经测试扫描间隔只要大于50ms,基本就已经不会受到按键抖动的影响了。大家可以使用这个结论。

        

 

        

拓展部分(长按触发)

     长按触发功能其实在蓝桥杯嵌入式的比赛中并不常考,但第九届的嵌入式省赛中却考到了长短按键的功能。

     给大家的代码里面,我也写了一个长按触发的代码提供给大家理解,其实这个原理也很简单,也就使用了一个计数的方式,然后到了你指定的计数值再触发。

        我用了按键4来演示这个效果,之前也讲到了,我们每50ms就会扫描一次KEY_Read()这个函数,如果按键被按下的话,相应的计数值每50ms加1,直到松开按键,相应的计数值才会清零。

        在程序中我们可以看到,当我们一直按下按键4,直到key4_sum加到40的时候,我们才执行长按的程序,也就是 40 * 50 = 2000ms ,我们就对进行LED8取反的操作。为了更好的显示这个长按的效果,当触发了长按之后,我把key4_sum = 30,只要持续按下按键4不松开,每过500ms都会执行一次长按的程序。

        那么达到的效果就是,当我们按下按键4超过2s时候,LED8就会以0.5S的间隔进行闪烁,知道按键松开后停止。我们可以把程序烧录到蓝桥杯嵌入式开发板里查看他的效果。

 

                                                                                                                                                                (以上仅属于个人观点)

<think>好的,用户想通过蓝桥杯嵌入式开发板学习FreeRTOS,需要教程和资源。首先,我得确认蓝桥杯常用的嵌入式开发板型号,比如CT117E,因为不同型号的硬件可能有所不同。接着,用户需要了解FreeRTOS的基础知识,所以应该推荐官方文档和入门教程。 然后是开发环境,蓝桥杯通常使用Keil MDK-ARM,需要安装对应的pack支持包,确保开发板能被正确识别。接下来,可能需要具体的例程和实验指导,比如任务创建、队列、信号量等,这些对学习RTOS很重要。 另外,用户可能需要视频教程或社区资源,比如B站或者蓝桥杯官网的论坛,这些地方可能有其他学习者的经验分享。还要注意结合开发板的硬件资源,比如LED、按键、串口等外设,来做实际的FreeRTOS应用,这样理论与实践结合效果更好。 最后,用户可能会遇到问题,所以推荐调试工具和常见问题解答也很重要。确保提供的资源是最新的,并且适合他们的开发板型号。需要分步骤整理这些信息,让用户能一步步跟着学习,同时生成相关问题帮助深入理解。</think># 使用蓝桥杯嵌入式开发板学习 FreeRTOS 的教程和资源 ## 一、基础准备 1. **开发板型号确认** 蓝桥杯嵌入式竞赛常用CT117E开发板(基于STM32F103RBT6),需确认开发板主控芯片与硬件资源是否支持FreeRTOS运行[^1]。 2. **开发环境搭建** 推荐使用Keil MDK-ARM开发环境,需安装: - STM32F1xx_DFP支持包 - FreeRTOS源码包(V10.4.1+) ```c // FreeRTOSConfig.h 关键配置示例 #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ ((unsigned long)72000000) ``` ## 二、学习路径 ### 阶段1:基础实验 1. **任务管理实验** 创建LED闪烁任务与串口打印任务,理解任务优先级: ```c void vTaskLED(void *pvParameters) { for(;;) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); vTaskDelay(500 / portTICK_PERIOD_MS); } } ``` 参考蓝桥杯官方实验指导书第5章[^2]。 2. **通信机制** 通过队列实现任务间数据传输: $$xQueue = xQueueCreate(5, sizeof(int));$$ ### 阶段2:进阶应用 1. **外设驱动开发** 结合开发板资源: - LCD显示任务状态 - 按键触发任务切换 - ADC采样使用信号量同步 2. **内存优化** 使用heap_4内存管理方案: ```c #define configTOTAL_HEAP_SIZE ((size_t)(6*1024)) ``` ## 三、核心资源推荐 1. **官方文档** - [FreeRTOS官方手册](https://www.freertos.org/Documentation/RTOS_book.html) - STM32标准外设库文档 2. **实验代码包** 蓝桥杯官网提供《嵌入式竞赛FreeRTOS实验套件》包含: - 任务调度示例 - 中断服务例程 - 资源管理实验 3. **调试工具** 使用SEGGER SystemView进行实时任务可视化分析[^3]。 ## 四、常见问题解决方案 1. **任务栈溢出** 通过uxTaskGetStackHighWaterMark()检测栈使用量 2. **优先级反转** 采用优先级继承协议: ```c xMutex = xSemaphoreCreateMutex(); ``` 3. **定时器漂移** 校准系统时钟源,推荐使用TIM2硬件定时器
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fei...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值