蓝桥杯嵌入式CT117E硬件开发平台 | 2011天华杯(蓝桥杯)赛题解答
本人也是从开始接触STM32到最后多少有点熟悉,因为之前只做过51单片机,对于STM32了解的还是比较少的,因此代码也是从最原来的杂乱到最后多少有点结构的想法,慢慢进步的一个过程,第一届赛题设计,对整体把握略微不足。本文章仅作大致讲解,具体实现方法可自行下载完整工程源代码及试题: 模拟停车场停车计费系统试题解答。
- 拿到赛题后,第一步则是先做出来显示界面,因为LCD驱动已给,所以显示界面还是很快上手的一个任务突破点。在做显示的时候,按照之前讲解的思路设计显示函数和结构体。如下所示:
typedef enum{
LCDMENU_CARIN = 0,
LCDMENU_CAROUT
}LCDMENU_TypeDef;
char LCD_DisBuff[20]={0};
LCDMENU_TypeDef LCD_MENU = LCDMENU_CARIN;
void LCD_Proc()
{
static LCDMENU_TypeDef LCD_MenuState_Last = LCDMENU_CARIN;
if(LCD_MENU != LCD_MenuState_Last)
{
LCD_MenuState_Last = LCD_MENU;
LCD_Clear(White);
LCD_SetBackColor(White);
LCD_SetTextColor(Blue);
}
if(LCD_MENU == LCDMENU_CARIN)
{
LCD_DisplayStringLine(Line3 ,(unsigned char *)" ID Code Time ");
memset(LCD_DisBuff,'0',sizeof(LCD_DisBuff));
sprintf(LCD_DisBuff," %d %02d:%02d:%02d ",IDx,PARKING_Structure[IDx].Idx_hour, \
PARKING_Structure[IDx].Idx_min,PARKING_Structure[IDx].Idx_sec);
LCD_DisplayStringLine(Line5 ,(unsigned char *)LCD_DisBuff);
memset(LCD_DisBuff,'0',sizeof(LCD_DisBuff));
sprintf(LCD_DisBuff," Rates:%d",Rates);
LCD_DisplayStringLine(Line8 ,(unsigned char *)LCD_DisBuff);
}
else if(LCD_MENU == LCDMENU_CAROUT)
{
LCD_DisplayStringLine(Line3 ,(unsigned char *)" ID Code Fee ");
memset(LCD_DisBuff,'0',sizeof(LCD_DisBuff));
sprintf(LCD_DisBuff," %d %d ",IDx,PARKING_Structure[IDx].IDx_Fee);
LCD_DisplayStringLine(Line5 ,(unsigned char *)LCD_DisBuff);
memset(LCD_DisBuff,'0',sizeof(LCD_DisBuff));
sprintf(LCD_DisBuff," Rates:%d",Rates);
LCD_DisplayStringLine(Line8 ,(unsigned char *)LCD_DisBuff);
}
else
{
}
}
- 显示界面可以后则是按键输入任务
typedef struct{
u8 Idx_hour;
u8 Idx_min;
u8 Idx_sec;
u16 IDx_Fee;
JUDGE_TypeDef IsPark;
}PARKING_TypeDef;
void KEY_Proc(u8 key_num)
{
u8 i=0;
if(key_num != 0xff)
{
switch(key_num)
{
case 1:
LCD_MENU = LCDMENU_CARIN;
if(IsPark_Count >= 10)
BUZ_Structure.IS_KEY_PARKING_FULL = TRUE;
else
{
BUZ_Structure.IS_KEY_PARKING_FULL = FAUSE;
while(USART2REC_Structure.IS_USART2_RecSucess == FAUSE)
{
LED_Control(LED7,REVERSE);
BUZ_Control(REVERSE);
DelaySisTick_Time(DELAY_SISTICKTIMESET_MS(200));
}
LED_Control(LED7,OFF);
BUZ_Control(OFF);
if(USART2REC_Structure.USART2_RecTab[0] == 'I')
{
IDx = (USART2REC_Structure.USART2_RecTab[2] - 0x30);
if(USART2REC_Structure.USART2_RecTab[2] == '1' && USART2REC_Structure.USART2_RecTab[3] == '0')
{
IDx = 10;
}
USART2REC_Structure.IS_USART2_RecSucess = FAUSE;
}
PARKING_Structure[IDx].Idx_sec = PARKING_Structure[IDx].Idx_min = PARKING_Structure[IDx].Idx_hour = 0;
PARKING_Structure[IDx].IsPark = TRUE;
}
break;
case 2:
LCD_MENU = LCDMENU_CAROUT;
while(USART2REC_Structure.IS_USART2_RecSucess == FAUSE)
{
LED_Control(LED8,REVERSE);
BUZ_Control(REVERSE);
DelaySisTick_Time(DELAY_SISTICKTIMESET_MS(200));
}
LED_Control(LED8,OFF);
BUZ_Control(OFF);
if(USART2REC_Structure.USART2_RecTab[0] == 'I')
{
IDx = (USART2REC_Structure.USART2_RecTab[2] - 0x30);
if(USART2REC_Structure.USART2_RecTab[2] == '1' && USART2REC_Structure.USART2_RecTab[3] == '0')
{
IDx = 10;
}
USART2REC_Structure.IS_USART2_RecSucess = FAUSE;
}
PARKING_Structure[IDx].IDx_Fee = PARKING_Structure[IDx].Idx_sec * Rates;
PARKING_Structure[IDx].IsPark = FAUSE;
break;
case 3:
IDx ++;
if(IDx > 10)
IDx = 1;
break;
case 4:
if(LCD_MENU == LCDMENU_CARIN)
LCD_MENU = LCDMENU_CAROUT;
else
LCD_MENU = LCDMENU_CARIN;
break;
default :
break;
}
}
IsPark_Count = 0;
for(i = 1 ;i < 11;i++)
{
if(PARKING_Structure[i].IsPark == TRUE)
IsPark_Count ++ ;
}
}
- 既然是任务要求,免不了初始化 的了,之所以现在提,则是因为需要考虑定义多少变量,都需要定义并使用哪些,以及如何定义,是结构体类型还是什么类型等,因此这一步则是结合前面时候及时更新的初始化操作。
extern char LCD_DisBuff[20];
extern LCDMENU_TypeDef LCD_MENU;
extern BUZ_TypeDef BUZ_Structure;
u8 IDx = 1;
u8 Rates = 1;
u8 IsPark_Count = 0;
PARKING_TypeDef PARKING_Structure[11];
DelaySisTick_Init(SISTICK_10US,1);
STM3210B_LCD_Init();
LCD_Clear(White);
LCD_SetBackColor(White);
LCD_SetTextColor(Blue);
LED_Init();
LED_Control(LEDALL,OFF);
Key_Init();
BUZ_Init();
USART2_Config();
USART2_SendString("\r\nUSART2 TEST:\r\n");
TIM3_Config();
- 串口操作,关于串口的接收之后的处理。
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
ucTemp = USART_ReceiveData(USART2);
if(ucTemp == 'I' || ucTemp == 'F' )
{
USART2REC_Structure.USART2_RecNum = 0;
memset(USART2REC_Structure.USART2_RecTab,0x00,USART2_RecTab_Max);
}
if(ucTemp == '\n')
USART2REC_Structure.IS_USART2_RecSucess = TRUE;
if(USART2REC_Structure.IS_USART2_RecSucess == FAUSE)
USART2REC_Structure.USART2_RecTab[USART2REC_Structure.USART2_RecNum++] = USART_ReceiveData(USART2);
if(USART2REC_Structure.USART2_RecNum > USART2_RecTab_Max - 1)
{
USART2REC_Structure.USART2_RecNum = 0;
}
}
extern USART2REC_TypeDef USART2REC_Structure;
void USERT2_Proc()
{
if(USART2REC_Structure.IS_USART2_RecSucess == TRUE)
{
if(USART2REC_Structure.USART2_RecTab[0] == 'F')
{
Rates = (USART2REC_Structure.USART2_RecTab[2] - 0x30);
if(USART2REC_Structure.USART2_RecTab[2] == '1' && USART2REC_Structure.USART2_RecTab[3] == '0')
{
Rates = 10;
}
USART2REC_Structure.IS_USART2_RecSucess = FAUSE;
}
}
}
- LED指示灯操作和蜂鸣器操作,放在最后,也是最方便做的,在处理数据时候放是否LED工作的标志位和蜂鸣器工作的标志位即可。
两种状态类型定义:
typedef enum{
OFF = 0,
ON = 1,
REVERSE = 2
}STATE_TypeDef;
typedef enum{
FAUSE = 0,
TRUE = 1
}JUDGE_TypeDef;
void LED_Proc()
{
if(IsPark_Count < 10)
{
LED_Control(LED1,ON);
LED_Control(LED2,OFF);
}
else
{
LED_Control(LED2,ON);
LED_Control(LED1,OFF);
}
}
BUZ_TypeDef BUZ_Structure;
void BUZ_Proc(void)
{
if(BUZ_Structure.IS_KEY_PARKING_FULL == TRUE)
BUZ_Control(ON);
else
BUZ_Control(OFF);
}