十五届蓝桥杯嵌入式代码解析(省一)
一. 获奖证书
二. 真题
三. 题目解析
3.1 难度分析
博主在考场看到这套题的时候,感觉有点难度,做下去发现难度并不大(相较于14届),以前还预估蓝桥杯赛事题目难度会只增不减,现在看来想法错误了。
3.2 考察要点
这套题目也比较常规,考察LED,LCD,按键,PWM,输入捕获。而这套题目重点要求即是读懂题目,别混淆题意。
实际代码并不多,主要是思路问题。
四. 代码
4.1 main.c
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM2_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
led_init();
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
//HAL_TIM_Base_Start_IT(&htim4);
T_init=uwTick;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
lcd_proc();
scan_key();
key_proc();
led_proc();
cal_proc();
}
/* USER CODE END 3 */
}
4.2 config.c
#include "config.h"
extern int T_init;
uchar LED_s=0;
struct key keys[4]={0};
int T_key;
uchar UI=0;
int f_A=0;
int f_B=0;
uchar f_t=0;
int PD=1000,PH=5000,PX=0;
int NDA=0,NDB=0,NHA=0,NHB=0;
uchar para_mode=0;
int T_lcd;
int B3_time;
int temp_fa,temp_fb;
void lcd_proc(void)
{
if(uwTick-T_lcd<100)return;
T_lcd=uwTick;
float temp;
char text[20];
f_A=temp_fa;
f_B=temp_fb;
if(UI==0)
{
LCD_DisplayStringLine(Line1,(unsigned char *)" DATA");
if(f_t==0)
{
if(f_A<0)
sprintf(text," A=NULL ");
else if(f_A<1000)
sprintf(text," A=%dHz ",f_A);
else
{
temp=f_A/1000.0;
sprintf(text," A=%.2fKHz ",temp);
}
LCD_DisplayStringLine(Line3,(unsigned char *)text);
if(f_B<0) sprintf(text," B=NULL ");
else if(f_B<1000)
sprintf(text," B=%dHz ",f_B);
else
{
temp=f_B/1000.0;
sprintf(text," B=%.2fKHz ",temp);
}
LCD_DisplayStringLine(Line4,(unsigned char *)text);
}
else if(f_t==1)
{
if(f_A<0)sprintf(text," A=NULL ");
else if(f_A<1000)
{
temp=1000.0/f_A;
sprintf(text," A=%.2fmS ",temp);
}
else
{
sprintf(text," A=%duS ",1000000/f_A);
}
LCD_DisplayStringLine(Line3,(unsigned char *)text);
if(f_B<0) sprintf(text," B=NULL ");
else if(f_B<1000)
{
temp =1000.0/f_B;
sprintf(text," B=%.2fmS ",temp);
}
else
{
sprintf(text," B=%duS ",1000000/f_B);
}
LCD_DisplayStringLine(Line4,(unsigned char *)text);
}
}
else if(UI==1)
{
LCD_DisplayStringLine(Line1,(unsigned char *)" PARA");
sprintf(text," PD=%dHz ",PD);
LCD_DisplayStringLine(Line3,(unsigned char *)text);
sprintf(text," PH=%dHz ",PH);
LCD_DisplayStringLine(Line4,(unsigned char *)text);
sprintf(text," PX=%dHz ",PX);
LCD_DisplayStringLine(Line5,(unsigned char *)text);
}
else if(UI==2)
{
LCD_DisplayStringLine(Line1,(unsigned char *)" RECD");
sprintf(text," NDA=%d ",NDA);
LCD_DisplayStringLine(Line3,(unsigned char *)text);
sprintf(text," NDB=%d ",NDB);
LCD_DisplayStringLine(Line4,(unsigned char *)text);
sprintf(text," NHA=%d ",NHA);
LCD_DisplayStringLine(Line5,(unsigned char *)text);
sprintf(text," NHB=%d ",NHB);
LCD_DisplayStringLine(Line6,(unsigned char *)text);
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
temp_fa=1000000 /HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1)+PX;
__HAL_TIM_SET_COUNTER(htim,0);
HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);
}
if(htim->Instance==TIM3)
{
temp_fb=1000000 /HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1)+PX;
__HAL_TIM_SET_COUNTER(htim,0);
HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);
}
}
void cal_proc(void)
{
static int state1=1,state2=1;
int temp1,temp2;
static int A_min=1000000;
static int A_max=0;
static int B_min=1000000;
static int B_max=0;
if(f_A-PH<0)temp1=0;
else temp1=1;
if(state1==0&&temp1==1)NHA++;
state1=temp1;
if(f_B-PH<0)temp2=0;
else temp2=1;
if(state2==0&&temp2==1)NHB++;
state2=temp2;
if(uwTick-T_init<3000)
{
if(f_A<A_min)A_min=f_A;
if(f_A>A_max)A_max=f_A;
if(f_B<B_min)B_min=f_B;
if(f_B>B_max)B_max=f_B;
}
else
{
T_init=uwTick;
if(A_max-A_min>PD)NDA++;
if(B_max-B_min>PD)NDB++;
A_min=1000000;
A_max=0;
B_min=1000000;
B_max=0;
}
}
void key_proc(void) {
if(keys[0].press==1) {
keys[0].press=0;
if(para_mode==0)
{
if(PD<1000)PD+=100;
}
else if(para_mode==1)
{
if(PH<10000)PH+=100;
}
else if(para_mode==2)
{
if(PX<1000)PX+=100;
}
}
else if(keys[1].press==1) {
keys[1].press=0;
if(para_mode==0)
{
if(PD>100)PD-=100;
}
else if(para_mode==1)
{
if(PH>1000)PH-=100;
}
else if(para_mode==2)
{
if(PX>-1000)PX-=100;
}
}
else if(keys[2].press==1) {
keys[2].press=0;
if(UI==1)
{
para_mode=(para_mode+1)%3;
}
if(UI==0)
{
f_t=(f_t+1)%2;
}
}
else if(keys[3].press==1) {
keys[3].press=0;
UI=(UI+1)%3;
if(UI==0)f_t=0;
if(UI==1)para_mode=0;
LCD_Clear(Black);
}
}
void led_proc(void) {
if(UI==0)LED_s|=0x01;
else LED_s&=0xfe;
if(f_A>PH)LED_s|=0x02;
else LED_s&=0xfd;
if(f_B>PH)LED_s|=0x04;
else LED_s&=0xFB;
if(NDA>=3||NDB>=3)
LED_s|=0x80;
else LED_s&=0x7f;
HAL_GPIO_WritePin(GPIOC,(uint16_t)(0xff<<8),GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,(uint16_t)(LED_s<<8),GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
void scan_key(void) {
if(uwTick-T_key<20)return ;
T_key=uwTick;
keys[0].level=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
keys[1].level=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
keys[2].level=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
keys[3].level=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i=0; i<4; i++) {
switch(keys[i].count) {
case 0:
if(keys[i].level==0)keys[i].count++;
break;
case 1:
if(keys[i].level==0) {
keys[i].count++;
if(UI==2&&i==2)B3_time=uwTick;
}
else keys[i].count=0;
break;
case 2:
if(keys[i].level==1) {
keys[i].count=0;
keys[i].press=1;
if(UI==2&&uwTick-B3_time>=1000&&i==2)
{
NDA=0,NDB=0,NHA=0,NHB=0;
keys[i].press=0;
}
}
break;
default :
break;
}
}
}
void led_init(void) {
//初始化
HAL_GPIO_WritePin(GPIOC,(uint16_t)(0xff<<8),GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
五. 结语
最后博主希望你们每一个人都能在蓝桥杯赛事中取得好成绩,上天不会辜负每一个努力的人,加油!