参加蓝桥杯嵌入式比赛,首先要搭建好开发环境。这个环节看似简单,但很多同学在这里就踩了不少坑。我当年第一次参赛时,光是环境配置就折腾了两天。现在回想起来,如果当时有人能给我一个清晰的指导,至少能节省一天时间。
开发环境主要涉及两个核心工具:STM32CubeMX和Keil MDK。CubeMX是ST官方提供的图形化配置工具,它能帮我们快速完成芯片外设的初始化配置;Keil则是我们编写和调试代码的IDE。这两个工具的配合使用,构成了蓝桥杯嵌入式开发的标准流程。
安装CubeMX时要注意版本兼容性。建议下载最新稳定版,同时确保Java运行环境已安装。Keil的安装稍微复杂些,需要先注册账号,然后申请MDK的license。这里有个小技巧:学生可以申请教育版license,完全免费。安装完成后,记得安装对应芯片的器件支持包,比如STM32F1xx_DFP,这样才能在Keil中正常编译和调试。
打开CubeMX后,首先要创建一个新工程。在芯片选择界面,蓝桥杯比赛通常使用STM32系列单片机,具体型号可能因年份而有所不同。以常见的STM32F103RCT6为例,在搜索框中输入型号即可找到对应芯片。
芯片选好后,会进入图形化配置界面。这个界面分为三个主要区域:左侧是外设树状图,中间是芯片引脚图,右侧是配置详情。我建议新手先花点时间熟悉这个界面布局,因为后续所有配置工作都是在这里完成的。
时钟配置是CubeMX中最关键也最容易出错的部分。在RCC配置中,需要根据实际硬件选择时钟源。蓝桥杯开发板通常使用外部高速晶振(HSE),所以在RCC配置中要选择"HSE Crystal/Ceramic Resonator"。
时钟树的配置更需要格外小心。我建议先设置好系统时钟源为PLL,然后逐步调整各分频系数,最终使系统时钟达到72MHz(STM32F103的最高主频)。这里有个实用技巧:CubeMX会自动计算时钟配置是否合法,如果出现红色警告,就说明配置有问题,需要调整分频系数。
GPIO是最基础的外设,蓝桥杯比赛中常用于按键检测和LED控制。以配置四个独立按键为例:
在配置GPIO时,建议给每个引脚设置一个有意义的用户标签(User Label),比如"KEY1"、"LED1"等。这样生成的代码可读性会更好,后续开发时也更容易理解。
定时器在嵌入式系统中用途广泛,蓝桥杯比赛中常用于PWM输出和输入捕获。以TIM3配置为例:
这样配置后,TIM3会产生一个频率为72MHz/(169+1)/(9999+1)≈42Hz的PWM信号,占空比约为10%。实际比赛中,可以根据具体需求调整这些参数。
完成所有外设配置后,就可以生成Keil工程了。在Project Manager标签页中:
点击"Generate Code"按钮,CubeMX会自动生成完整的Keil工程。第一次生成可能需要较长时间,因为CubeMX要下载所需的HAL库文件。
生成的Keil工程包含以下重要目录和文件:
特别要注意的是main.c文件中的MX_GPIO_Init()、MX_TIM3_Init()等函数,这些都是CubeMX根据我们的配置自动生成的初始化代码。在编写应用层代码时,不要修改这些函数,否则下次重新生成代码时修改会被覆盖。
第一次编译Keil工程时,可能会遇到各种错误。最常见的是头文件找不到的问题,这通常是因为工程路径包含中文或特殊字符。解决方法是将整个工程移动到纯英文路径下。
另一个常见问题是未定义符号错误,这往往是因为没有正确配置器件支持包。在Keil的Pack Installer中检查是否安装了对应芯片的支持包,如果没有就立即安装。
程序编译通过后,就可以下载到开发板运行了。在下载前,需要正确配置调试器。蓝桥杯官方开发板通常使用ST-Link调试器,在Keil的Options for Target→Debug选项卡中选择ST-Link Debugger。
如果遇到下载失败的情况,首先检查开发板供电是否正常,然后检查调试器连接是否可靠。有时候复位电路设计问题也会导致下载失败,这时可以尝试手动复位开发板的同时点击下载按钮。
在CubeMX的NVIC配置中,可以设置各个中断的优先级。对于实时性要求高的外设(如串口接收),应该给予更高的优先级。但要注意,STM32的中断优先级数值越小优先级越高,这与很多人的直觉相反。
我建议将系统关键中断(如定时器)设置为最高优先级(数值最小),普通外设中断设置为中等优先级,非实时性任务设置为最低优先级。这样配置可以确保系统稳定运行。
虽然蓝桥杯比赛对功耗要求不高,但了解低功耗配置还是有必要的。在CubeMX中,可以配置多种低功耗模式,包括Sleep、Stop和Standby模式。通过合理使用这些模式,可以显著降低系统功耗。
例如,在等待按键输入时,可以让MCU进入Sleep模式,当按键触发外部中断时再唤醒。这样处理可以大幅降低系统平均功耗,对于电池供电的应用场景特别有用。