蓝桥杯嵌入式12届省赛真题1

一、前言:

这编文章意义不大,还有很多逻辑有待完善,比赛时还是建议优先实现功能,比如如何入库出库,而不是去花大量的时间去考虑接收字符串时间格式是否正确,比如像有没有超过24个小时,超过60分钟,或者是否都为数字字符这些,还有像字符串的长度是否正确,你如果要一一考虑的话需要太多的时间了,笔者已经是第二次做了,依旧花了快7个小时,而且评测时还不是一次就过的,还是需要看着错误修修改改才能满分。

二、题目展示:

三、具体实现:

1、头文件的相关定义与声明

#ifndef _code_h
#define _code_h

#include "stm32g4xx.h"                  // Device header
#include "stdio.h"
#include "string.h"
#include "stdint.h"

#include "main.h"
#include "gpio.h"
#include "lcd.h"
#include "tim.h"
#include "usart.h"

void lcd_proc(void);
void key_proc(void);
void led_proc(u8 led_x,u8 led_mode);
void usart_proc(void);

#endif

2、主函数的初始化

    #include "code.h"   


    ……

    ……

    ……


    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
	LCD_Init();
	LCD_SetTextColor(White);
	LCD_SetBackColor(Black);
	LCD_Clear(Black);
	
	HAL_TIM_Base_Start(&htim2);
	HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
	TIM17->CCR1=0;
	
	extern u8 my_pData;
	HAL_UART_Receive_IT(&huart1,&my_pData,1);

    while (1)
    {
	    lcd_proc();
		key_proc();
		usart_proc();

    }

3、各个模块的实现

#include "code.h"

/*----------------------------lcd--------------------------------------*/
u8 ui;
char lcd_val[30];
u8 CNBR,VNBR,IDLE=8;
double CNBR_P=3.5,VNBR_P=2;
void lcd_proc(void)
{
	if(ui==0)
	{
		sprintf(lcd_val,"       Data");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"   CNBR:%d     ",CNBR);
		LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
		sprintf(lcd_val,"   VNBR:%d     ",VNBR);
		LCD_DisplayStringLine(Line5,(u8 *)lcd_val);
		sprintf(lcd_val,"   IDLE:%d     ",IDLE);
		LCD_DisplayStringLine(Line7,(u8 *)lcd_val);
	}
	else
	{
		sprintf(lcd_val,"       Para");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"   CNBR:%.2f     ",CNBR_P);
		LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
		sprintf(lcd_val,"   VNBR:%.2f     ",VNBR_P);
		LCD_DisplayStringLine(Line5,(u8 *)lcd_val);
	}
	led_proc(1,IDLE);
	led_proc(2,TIM17->CCR1);
}



/*----------------------------key--------------------------------------*/
u8 key_val[4];
u8 key_old[4];
u8 key;

void key_proc(void)
{
	for(u8 i=0;i<4;i++)
	{
		key_val[i]=HAL_GPIO_ReadPin(i<3?GPIOB:GPIOA,GPIO_PIN_0<<i%3);
	}
	for(u8 i=0;i<4;i++)
	{
		if(key_val[i]==0&&key_old[i]==1)
		{
			HAL_Delay(20);
			if(key_val[i]==0&&key_old[i]==1)
			{
				key=i+1;
			}
		}
	}
	for(u8 i=0;i<4;i++)
	{
		key_old[i]=key_val[i];
	}
	switch(key)
	{
		case 1:
		{
			ui=!ui;
			LCD_Clear(Black);
			break;
		}
		case 2:
		{
			if(ui)
			{
				CNBR_P+=0.5;
				VNBR_P+=0.5;
			}
			break;
		}
		
		case 3:
		{
			if(ui&&VNBR_P>0)
			{
				CNBR_P-=0.5;
				VNBR_P-=0.5;
			}
			break;
		}
		case 4:
		{
			if(TIM17->CCR1==20)TIM17->CCR1=0;
			else TIM17->CCR1=20;
			break;
		}
	}
	key=0;
}

/*----------------------------led--------------------------------------*/

void led_proc(u8 led_x,u8 led_mode)
{
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	if(led_mode)
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led_x-1),GPIO_PIN_RESET);
	else
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led_x-1),GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

/*----------------------------usart--------------------------------------*/
u8 my_pData,count,rx_flag;
char rx_val[30];
char tx_val[30];
//VNBR:D583:20 0202 120000 == 22

struct Car_Data
{
	char Type[5];
	char Id[5];
	char Time[13];
	int Time_S;

}car[9];//8个车位,多出来的一位用来存放串口接收的临时数据

int Time_proc()
{
	int time_S=0;
	//年
	time_S+=(car[8].Time[0]-'0')*10*360*24*3600;
	time_S+=(car[8].Time[1]-'0')*360*24*3600;
	//月
	time_S+=(car[8].Time[2]-'0')*10*30*24*3600;
	time_S+=(car[8].Time[3]-'0')*30*24*3600;
	//日
	time_S+=(car[8].Time[4]-'0')*10*24*3600;
	time_S+=(car[8].Time[5]-'0')*24*3600;
	//时
	time_S+=(car[8].Time[6]-'0')*10*3600;
	time_S+=(car[8].Time[7]-'0')*3600;
	//分
	time_S+=(car[8].Time[8]-'0')*10*60;
	time_S+=(car[8].Time[9]-'0')*60;
	//秒
	time_S+=(car[8].Time[10]-'0')*10;
	time_S+=(car[8].Time[11]-'0');
	return time_S;
}

double Money(u8 time,u8 type)
{
	if(!type)
		return CNBR_P*time;
	else
		return VNBR_P*time;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	rx_val[count]=my_pData;
	TIM2->CNT=0;
	count++;
	rx_flag=1;
	HAL_UART_Receive_IT(&huart1,&my_pData,1);
}

void usart_proc(void)
{
	if(rx_flag==0)return;
	if(TIM2->CNT<15)return;
	
	sscanf(rx_val,"%4s:%4s:%12s",car[8].Type,car[8].Id,car[8].Time);
	car[8].Time_S=Time_proc();
	
	for(u8 i=0;i<8;i++)//判断是入库还是出库,即判断车俩是否已在车库
	{
		if(strcmp(car[8].Id,car[i].Id)==0)//已在车库则出库
		{
			int time=car[8].Time_S-car[i].Time_S,type=1;
			if(time<=0)goto ERROR;
			if(time%3600!=0)time+=3600;
			if(strcmp(car[i].Type,"CNBR")==0)
			{
				CNBR--;
				type=0;
			}
			else VNBR--;
			IDLE++;
			
			                          sprintf(tx_val,"%s:%s:%d:%.2f",car[i].Type,car[i].Id,time/3600,Money(time/3600,type));
			
			HAL_UART_Transmit(&huart1,(u8*)tx_val,strlen(tx_val),50);
			car[i].Type[0]='\0';
			car[i].Id[0]='\0';
			car[i].Time[0]='\0';
			car[i].Time_S=0;
			goto OK;
		}
	}

	for(u8 i=0;i<8;i++)//寻找空位,入库操作
	{
		if(car[i].Type[0]==NULL)
		{
			car[i].Time_S=car[8].Time_S;
			sscanf(rx_val,"%4s:%4s:%12c",car[i].Type,car[i].Id,car[i].Time);
			if(strcmp(car[i].Type,"CNBR")==0)CNBR++;
			else VNBR++;
			IDLE--;
			goto OK;
		}
		if(i==7)goto ERROR;
	}
	OK://操作成功处理
	{
		count=0;
		rx_flag=0;
		memset(rx_val,NULL,sizeof(rx_val));
		return;
	}
	ERROR://错误处理
	{
		HAL_UART_Transmit(&huart1,(u8*)"Error",5,50);
		count=0;
		rx_flag=0;
		memset(rx_val,NULL,sizeof(rx_val));
	}
	
}

四、结语:

代码还需要很多的优化,尤其是时间的处理,虽然实现很快很简单,但也看起来傻傻的,参考意义不大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值