一.题目
二.思路分析
2.1 知识点分析
本届蓝桥杯相比于上一届难度有所提升,但是基本考察的外设和知识点都基本没变,只是提高了代码逻辑,知识点还是常规,LCD,LED,按键,PWM,定时器,串口。
2.2 逻辑分析
这套题做法其实也跟上一届题目大径相同,先把基本模块实现了,按键,LCD,LED,PWM模块,最后也就是难点就说串口模块,最后我们再去处理,边写串口,边重新去修改其他模块的逻辑。大致思路就是如此。
三.代码示例
下面是核心代码
#include "interrupt.h"
#include "main.h"
#include "string.h"
extern ADC_HandleTypeDef hadc2;
extern uint T_adc;
extern uint T_led;
extern uint T_key;
extern TIM_HandleTypeDef htim17;
extern UART_HandleTypeDef huart1;
uchar CNBR,VNBR,IDLE;
bool Mode=0;
struct key keys[4]={0};
double ADC_Value;
bool _UI=0;
double cnbr_price=3.5;
double vnbr_price=2.0;
uchar uart1_rxbuf[30];
uchar cars_type[8]={2,2,2,2,2,2,2,2};
uchar car_num[8][5]={0};
uchar car_time[8][8];
uchar car_free=8;
uchar car_loc[8]={0};
uchar car_flag[8]={0};
uchar LED_s=0;
uint pass;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance==USART1)
{
//HAL_UART_Transmit(&huart1, uart1_rxbuf, 10, 100);
HAL_UARTEx_ReceiveToIdle_IT(&huart1,uart1_rxbuf,30);
uart1_rxbuf[22]='\0';
// printf("%s\n",uart1_rxbuf);
if(((uart1_rxbuf[0]=='C')&&(uart1_rxbuf[1]=='N')&&(uart1_rxbuf[2]=='B')&&(uart1_rxbuf[3]=='R'))||((uart1_rxbuf[0]=='V')&&(uart1_rxbuf[1]=='N')&&(uart1_rxbuf[2]=='B')&&(uart1_rxbuf[3]=='R')))
{
// printf("test1\n");
// printf("car_num=%s",car_num[0]);
int i;
char text[5]="CNBR";
// printf("anser=%s",strstr((char *)car_num[i],(char *)uart1_rxbuf));
for( i=0;i<8;i++)
{
//出去
if(strstr((char *)uart1_rxbuf,(char *)car_num[i])&&car_flag)
{
// printf("test2\n");
car_flag[i]=0;
double result=(uart1_rxbuf[12]-car_time[i][0])*30*24;
result+=(uart1_rxbuf[13]-car_time[i][1])*24;
result+=(uart1_rxbuf[14]-car_time[i][2])*10*24;
result+=(uart1_rxbuf[15]-car_time[i][3])*24;
result+=(uart1_rxbuf[16]-car_time[i][4])*10;
result+=(uart1_rxbuf[17]-car_time[i][5]);
if(uart1_rxbuf[18]>car_time[i][6])
{
result+=1;
}
int time=result;
if(cars_type[i]==1)result*=vnbr_price;
else if(cars_type[i]==0)result*=cnbr_price;
car_free++;
car_loc[i]=0;
if(cars_type[i]==1)text[0]='V';
printf("%s:%s:%d:%.2f",text,car_num[i],time,result);
memset(car_num[i],0,4);
break;
}
}
//进去
if(car_free==0)return ;
if(i==8)
{
int j=0;
for(j=0;j<8;j++)
{
if(car_loc[j]==0)
{
car_loc[j]=1;
break;
}
}
car_flag[j]=1;
car_num[j][0]=uart1_rxbuf[5];
car_num[j][1]=uart1_rxbuf[6];
car_num[j][2]=uart1_rxbuf[7];
car_num[j][3]=uart1_rxbuf[8];
car_time[j][0]=uart1_rxbuf[12];
car_time[j][1]=uart1_rxbuf[13];
car_time[j][2]=uart1_rxbuf[14];
car_time[j][3]=uart1_rxbuf[15];
car_time[j][4]=uart1_rxbuf[16];
car_time[j][5]=uart1_rxbuf[17];
car_time[j][6]=uart1_rxbuf[18];
car_time[j][7]=uart1_rxbuf[19];
if((uart1_rxbuf[0]=='C')&&(uart1_rxbuf[1]=='N')&&(uart1_rxbuf[2]=='B')&&(uart1_rxbuf[3]=='R'))
{
cars_type[j]=0;
}
else cars_type[j]=1;
car_free--;
}
}
}
memset(uart1_rxbuf,0,22);
}
void lcd_proc()
{
char Text[40];
sprintf(Text,"V=%.2f",ADC_Value);
LCD_DisplayStringLine(Line9,(uchar *)Text);
if(_UI==0)
{
LCD_DisplayStringLine(Line1,(unsigned char *)" Data");
sprintf(Text," CNBR:%d",CNBR);
LCD_DisplayStringLine(Line3,(uchar *)Text);
sprintf(Text," VNBR:%d",VNBR);
LCD_DisplayStringLine(Line5,(uchar *)Text);
sprintf(Text," IDLE:%d",IDLE);
LCD_DisplayStringLine(Line7,(uchar *)Text);
}
else if(_UI==1)
{
LCD_DisplayStringLine(Line1,(unsigned char *)" Para");
sprintf(Text," CNBR:%.2f",cnbr_price);
LCD_DisplayStringLine(Line3,(uchar *)Text);
sprintf(Text," VNBR:%.2f",vnbr_price);
LCD_DisplayStringLine(Line5,(uchar *)Text);
}
}
void led_init()
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
void led_proc()
{
if(car_free>0)LED_s|=0x01;
else LED_s&=0xfe;
if(Mode==0)LED_s&=0xfd;
else LED_s|=0x02;
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12,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 key_proc()
{
if(keys[0].press==1)
{
_UI=!_UI;
LCD_Clear(Black);
keys[0].press=0;
}
if(keys[1].press==1)
{
keys[1].press=0;
if(_UI==0)return ;
cnbr_price+=0.5;
vnbr_price+=0.5;
}
if(keys[2].press==1)
{
keys[2].press=0;
if(_UI==0)return ;
cnbr_price-=0.5;
vnbr_price-=0.5;
}
if(keys[3].press==1)
{
Mode=!Mode;
if(Mode==1)
{
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,8);
}
else if(Mode==0)
{
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,0);
}
keys[3].press=0;
}
}
void scan_key()
{
if(uwTick-T_key<50) 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=1;
break;
case 1:
if(keys[i].level==0)keys[i].count=2;
else keys[i].count=0;
break;
case 2:
if(keys[i].level==1)
{
keys[i].press=1;
keys[i].count=0;
}
break;
default:break;
}
}
}
void read_adc()
{
if(uwTick-T_adc<10)return ;
T_adc=uwTick;
static double temp = 0;
static uchar count_V=0;
count_V++;
HAL_ADC_Start(&hadc2);
temp += HAL_ADC_GetValue(&hadc2);
HAL_ADC_Stop(&hadc2);
if(count_V==5)
{
ADC_Value=temp*3.3/5/4096;
temp=0;
count_V=0;
}
}