蓝桥杯比赛
竞赛提供文件
USB驱动程序(一般不会用到)
底层驱动代码参考
DS18B20温度传感器,一般省赛不会用,该配件在扩展版上
I2C驱动程序(重要)
芯片资料:板子上几乎所有芯片的手册,大多数用不到,重要的在于STM32的编程手册和参考手册。客观题中相关问题可以直接查阅手册。
库文件(STM32CubeMX配置完成之后该文件也一般不会用到)
液晶驱动参考程序(重点)
开始比赛后直接将HAL_06_LCD直接复制一份作为工程模板使用,不用再写额外的LCD调试程序(其CubeMX工程版本可能有问题,需要事先注意版本移植的问题)。
CT117E_M4_SCH.pdf:开发板原理图
CT117E_M4产品手册:开发板开发手册,包含原理图
客观题部分
客观题包含:STM32相关、数电模电部分知识。主要看平时的积累,STM32相关不会的要会查阅手册。
程序设计部分
1 LED模块
- 修改CubeMX配置:IO引脚,IO端口
- 注意事项:使用LED时必须将
LE
引脚拉高,不用时拉低 - 使用说明:高电平LED熄灭,低电平LED点亮
2 按键KEY模块
修改CubeMX配置:IO引脚,IO端口
注意事项:未按下为高电平,按下为低电平
按键需要消抖,但是不能阻塞程序,可以参考以下的扫描方式
Key Scan Code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30uint8_t KeyScanCount = 0;
uint8_t KeyScanFlag = 0;
uint8_t KeyPressedFlag = 0;
uint8_t KeyFlag = 0;
/* 按键扫描函数,20ms扫描一次实现消抖 */
void Key_Scan(void)
{
for (uint8_t i = 0; i < 4; i ++)
{
if (HAL_GPIO_ReadPin(KeyPort[i], KeyPin[i]) == GPIO_PIN_SET) // lift up
{
KeyPressedFlag &= ~(1 << i);
}
else if ((KeyPressedFlag & (1 << i)) == 0) // first push
{
if (HAL_GPIO_ReadPin(KeyPort[i], KeyPin[i]) == GPIO_PIN_SET)
{
return;
}
KeyFlag |= (1 << i);
KeyPressedFlag |= (1 << i);
}
}
}
void Key_Process(void)
{
printf("keyFlag: %X\n", KeyFlag);
}
3 串口收发模块
CubeMX配置USART1初始化;
CubeMX使能USART中断;
串口发送:重写
fputc()
函数(赛前多写几次),即可直接使用printf()
函数进行串口发送;1
2
3
4
5int fputc(int ch, FILE* f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFF);
return ch;
}串口接收:使能中断接收,之后重写中断服务函数
HAL_UART_RxCpltCallback()
函数即可:1
HAL_UART_Receive_IT(&huart1, uartRxBuffer, 1);
1
2
3
4void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* 接收处理代码 */
}
4 ADC模块
初始化:直接在CubeMX中配置即可,推荐使用DMA循环模式触发ADC采样
开始采样:在程序初始化中直接开启DMA模式ADC采样。之后CPU就不用处理ADC的内容了,需要数据直接读取即可。
1
2
3uint16_t AdcBuffer[2] = {0};
HAL_ADC_Start_DMA(&hadc2, (uint32_t*)Adcbuffer, 2);读取数据:直接读取即可,DMA会自动更新其中的内容。
1
2AdcDisplay[0] = Adcbuffer[0] * 3.3 / 4095.0;
AdcDisplay[1] = Adcbuffer[1] * 3.3 / 4095.0;数据不稳定:延长采样时间
5 PWM输出
初始化:直接在CubeMX中配置好TIM与对应通道的PWM输出
开始/停止:直接调用库函数即可
1
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
调节频率设置占空比:直接设置PSC(预分频系数,一般不用设置这个)、ARR(自动重装载值)、CCRx(捕获比较寄存器)的值即可:
1
2htim3.Instance->ARR = 49;
htim3.Instance->CCR2 = 99;
6 测量PWM频率和占空比
使用定时器的捕获中断服务回调函数处理。
1 | uint8_t pwmMode = 0; |
- 第一次先捕获上升沿,清空计数器,并将两个时间设置为0;
- 第二次捕获下降沿,记录高电平时间;
- 第三次再捕获上升沿,记录整个周期的时间;
- 主函数中判断是否已经捕获完成一个周期,将pwmMode设置为0开始下一次捕获;
整体代码编写思路
题目的主要特点:
- 任务要求多
- 实时处理和显示
- 同一任务的处理时间间隔有一定要求
从HAL_06_LCD
工程开始逐步添加功能。最重要的编写思想是==前后台系统==。
前后台系统
前后台系统即将每一个模块及其相应称为一个任务。使用SysTick计时,每隔一段时间执行一次某个任务,同时该任务不能占据太长时间。以下面的代码为例:
1 | void SysTick_Handler(void) |
在main
函数中:
1 | void main(void) |
About this Post
This post is written by Yun Zhang, licensed under CC BY-NC 4.0.