蓝桥杯嵌入式赛道备赛
本文介绍了基于STM32的嵌入式开发代码实现,主要包括:1) 按键长短按检测,通过定时器计数判断按键状态;2) LCD显示控制,实现文本和计数的高亮显示;3) 输入捕获测频率,使用TIM17捕获外部信号频率;4) EEPROM的I2C写入操作,需注意写入延时;5) 开发中的关键问题解析,包括回调函数、NVIC使能、ADC测量、串口通信和LCD/LED引脚冲突解决方法。代码参考B站教程并进行了个人修
·
代码跟随B站up 我的代码没问题 敲出,有一点改动,仅做为个人学习的记录
按键长按短按
uint8_t B1_State;
uint8_t B1_Last_State = 1;
uint8_t B2_State;
uint8_t B2_Last_State;
void Key_Scan(void)
{
B1_State = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
if(B1_State == 0 && B1_Last_State == 1) //按键B1按下
{
TIM3->CNT = 0;
}
else if(B1_State == 1 && B1_Last_State == 0) //按键B1松开,判断长按短按
{
if(TIM3->CNT < 10000) //短按
{
led_show(1, 0);
Count = 0;
}
else if(TIM3->CNT > 10000) //短按
{
led_show(1, 1);
Count = Count + 1;
}
}
B1_Last_State = B1_State;
}
按完按键后判断长短按键的状态
高亮显示
char text[20];
void lcd_show(void)
{
sprintf(text, "text");
LCD_DisplayStringLine(Line0, (uint8_t *)text); //注意强制类型转化
if(LED_HighShow == 0)
{
LCD_SetBackColor(Yellow);
sprintf(text, "count: %d", Count);
LCD_DisplayStringLine(Line3, (uint8_t *)text);
LCD_SetBackColor(Black);
sprintf(text, "psc1");
LCD_DisplayStringLine(Line4, (uint8_t *)text);
sprintf(text, "psc2");
LCD_DisplayStringLine(Line5, (uint8_t *)text);
}
else if(LED_HighShow == 1)
{
sprintf(text, "count: %d", Count);
LCD_DisplayStringLine(Line3, (uint8_t *)text);
LCD_SetBackColor(Yellow);
sprintf(text, "psc1");
LCD_DisplayStringLine(Line4, (uint8_t *)text);
LCD_SetBackColor(Black);
sprintf(text, "psc2");
LCD_DisplayStringLine(Line5, (uint8_t *)text);
}
else if(LED_HighShow == 2)
{
sprintf(text, "count: %d", Count);
LCD_DisplayStringLine(Line3, (uint8_t *)text);
// LCD_SetBackColor(Yellow);
sprintf(text, "psc1");
LCD_DisplayStringLine(Line4, (uint8_t *)text);
LCD_SetBackColor(Yellow);
sprintf(text, "psc2");
LCD_DisplayStringLine(Line5, (uint8_t *)text);
LCD_SetBackColor(Black);
}
else
{
LED_HighShow = 0;
}
// led_show(1, LED_Mode);
}
输入捕获测频率
#include "headfile.h"
uint32_t fre, Capture_Value;
char text[20];
void lcd_show(void)
{
sprintf(text, "text");
LCD_DisplayStringLine(Line0, (uint8_t *)text);
sprintf(text, "FRE:%d", fre);
LCD_DisplayStringLine(Line3, (uint8_t *)text);
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM17)
{
// Capture_Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
Capture_Value = TIM17->CNT;
TIM17->CNT = 0;
fre = 1000000 / Capture_Value;
}
}
EEPROM I2C写入
void eeprom_write(uint8_t addr, uint8_t dat)
{
I2CStart();
I2CSendByte(0XA0); //找从机芯片地址, 读是1, 写是0
I2CWaitAck(); //等待回应
I2CSendByte(addr); //芯片内部地址
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
HAL_Delay(50);
}
注意,务必延时,测试不延时可能无法写入
我对于一些问题的理解和up对于问题的总结
什么是回调函数?
当标志位为1时的执行函数,执行后会自动清除标志位
什么时候需要使能NVIC?
需要用中断的时候
模拟输入ADC单端和差分的区别
单端:输入引脚对地电压
差分:两输入引脚压差
ADC测量电压计算
V=3.3*ADC_Value/4095
串口数据接收
通常为sprintf(用于将数据转换为字符串) + HAL_UART_Transmit()(发送数据)
LCD LED引脚冲突
在使用到的LCD函数头尾分别加上uint16_t temp = GPIOC -> ODR; GPIOC -> ODR = temp;
同时在LCD初始化之前关闭PD2的寄存器,注意要正确配置LED
布尔取反 按位取反
uint8_t LED;
LED = ~LED; 按位取反,并非单纯的1->0, 0->1
LED = !LED; 布尔取反,0变1, 1变0
写题目的总结
LCD显示要多检查几次,大小写不要写错
输入捕获测频率,PSC给80-1测频更准
rtc时钟实时刷新必须要开闹钟,且要给sTime和sDate赋值
修改RTC的值必须写入HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
更多推荐
所有评论(0)