// 定义结构体数组,用于存储密钥信息
extern struct keys key[];
// 定义字符数组,用于存储接收到的文本信息
extern char rx_txt[30];
// 定义无符号字符,用于存储某个日期值
extern unsigned char re_date;
// 定义 8 位整型变量,用于存储某个指针值
extern uint8_t re_pointer;
// 定义结构体类型,包含车辆信息和时间信息
struct cars
{
char car_tapy[5];
char car_value[5];
char time_year[3];
char time_month[3];
char time_day[3];
char time_mintute[3];
char time_second[3];
};
// 定义字符串数组,用于存储车型信息、车值信息、年月日等时间信息
char car_tapy_text[5];
char car_value_text[5];
char time_year_text[3];
char time_month_text[3];
char time_day_text[3];
char time_mintute_text[3];
char time_second_text[3];
// 定义各种计时器和值
int car_mintute = 0;
int car_second = 0;
int text_mintute = 0;
int text_second = 0;
float time_value = 0;
int time_car = 0;
// 定义结构体数组,用于存储车辆信息和时间信息。数组大小为9。
struct cars car[9] = { 0, 0, 0, 0, 0, 0, 0, 0 };
// 定义数值型变量,用于存储某些数值
uint8_t cnbr_num = 0;
uint8_t vnbr_num = 0;
uint8_t A7_flag = 0;
uint8_t car_flag = 0;
unsigned char car_kong_num = 8;
char car_for = 0;
float cnbr_value = 3.50;
float vnbr_value = 2.00;
float value_5 = 0.50;
// 定义整型变量,用于存储是否显示液晶屏和要显示的文本
uint8_t show_lcd = 0;
char lcd_txt[30];
void LCD_real()
{
// 判断是否需要显示液晶屏数据
if(show_lcd==0)
{
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," Data ");
// 显示lcd_txt变量的内容在第一行 LCD 上
LCD_DisplayStringLine(Line1, (uint8_t*)lcd_txt);
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," CNBR:%d ",cnbr_num);
// 显示lcd_txt变量的内容在第三行 LCD 上
LCD_DisplayStringLine(Line3, (uint8_t*)lcd_txt);
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," VNBR:%d ",vnbr_num);
// 显示lcd_txt变量的内容在第五行 LCD 上
LCD_DisplayStringLine(Line5, (uint8_t*)lcd_txt);
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," IDLE:%d ",car_kong_num);
// 显示lcd_txt变量的内容在第七行 LCD 上
LCD_DisplayStringLine(Line7, (uint8_t*)lcd_txt);
}
// 如果show_lcd为1,则执行下面的代码块
else if(show_lcd==1)
{
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," Para ");
// 显示lcd_txt变量的内容在第一行 LCD 上
LCD_DisplayStringLine(Line1, (uint8_t*)lcd_txt);
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," CNBR:%.2f ",cnbr_value);
// 显示lcd_txt变量的内容在第三行 LCD 上
LCD_DisplayStringLine(Line3, (uint8_t*)lcd_txt);
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," VNBR:%.2f ",vnbr_value);
// 显示lcd_txt变量的内容在第五行 LCD 上
LCD_DisplayStringLine(Line5, (uint8_t*)lcd_txt);
// 将文本信息写入lcd_txt变量
sprintf(lcd_txt," ");
// 显示lcd_txt变量的内容在第七行 LCD 上
LCD_DisplayStringLine(Line7, (uint8_t*)lcd_txt);
}
}
void key_real()
{
if(key[0].sing_str==1) // 判断按键0是否被按下
{
if(++show_lcd==2) // 如果show_lcd自增后等于2
show_lcd=0; // 就将show_lcd归零
key[0].sing_str=0; // 清除按键0的标志位
}
if(key[1].sing_str==1) // 判断按键1是否被按下
{
if(show_lcd==1) // 如果show_lcd的值等于1
{
cnbr_value=cnbr_value+value_5; // 增加CNBR的值
vnbr_value=vnbr_value+value_5; // 增加VNBR的值
}
key[1].sing_str=0; // 清除按键1的标志位
}
if(key[2].sing_str==1) // 判断按键2是否被按下
{
if(show_lcd==1) // 如果show_lcd的值等于1
{
cnbr_value=cnbr_value-value_5; // 减小CNBR的值
vnbr_value=vnbr_value-value_5; // 减小VNBR的值
}
key[2].sing_str=0; // 清除按键2的标志位
}
if(key[3].sing_str==1) // 判断按键3是否被按下
{
if(++A7_flag==2) // 如果A7_flag自增后等于2
A7_flag=0; // 将A7_flag归零
if(A7_flag==1) // 如果A7_flag的值等于1
{
if(car_kong_num!=0) // 如果空位数不等于0
{
LED_real(0x03); // 亮红灯
}
else // 否则
{
LED_real(0x02); // 亮黄灯
}
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,200); // 设置定时器的比较值为200
}
else if(A7_flag==0) // 如果A7_flag的值等于0
{
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,0); // 将定时器的比较值归零
if(car_kong_num!=0) // 如果空位数不等于0
{
LED_real(0x01); // 亮绿灯
}
else // 否则
{
LED_real(0x00); // 不亮灯
}
}
key[3].sing_str=0; // 清除按键3的标志位
}
}
MX_GPIO_Init(); // 初始化GPIO
MX_TIM4_Init(); // 初始化定时器4
MX_USART1_UART_Init(); // 初始化串口1
MX_TIM17_Init(); // 初始化定时器17
/* USER CODE BEGIN 2 */
LCD_Init(); // 初始化LCD屏幕
LCD_Clear(Black); // 清屏
LCD_SetTextColor(White); // 设置字体颜色为白色
LCD_SetBackColor(Black); // 设置背景颜色为黑色
HAL_TIM_Base_Start_IT(&htim4); // 启动定时器4
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1); // 启动定时器17
HAL_UART_Receive_IT(&huart1,&re_pointer,1); // 开始接收串口1的中断
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,0); // 设置定时器17的比较值为0
LED_real(0x00); // 关闭所有的LED灯
if(car_kong_num!=0) // 如果停车位上有车
{
LED_real(0x01); // 将绿灯点亮
}
// 调用 LCD_real() 函数,用来更新液晶屏上的显示内容
LCD_real();
// 调用 key_real() 函数,读取按键操作
key_real();
// 如果 re_date 不为0,则执行下面的代码块
if(re_date!=0)
{
// 将 re_date 的值存入 temp 变量中
int temp=re_date;
// 延时1ms
HAL_Delay(1);
// 如果 re_date 的值与 temp 相等,则执行 Re_Receive() 函数
if(re_date==temp)Re_Receive();
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); // 配置主内部稳压器输出电压
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 设置时钟源为外部高速时钟(HSE)
RCC_OscInitStruct.HSEState = RCC_HSE_ON; // 使能HSE时钟
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; // 使能PLL锁相环
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; // 将HSE作为PLL锁相环的时钟源
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3; // 设置PLL的输入分频系数
RCC_OscInitStruct.PLL.PLLN = 20; // 设置PLL的倍频系数
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // 设置PLL的P分频系数
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) // 如果时钟配置失败,则调用错误处理函数
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 将PLL作为系统时钟
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 设置AHB总线时钟分频系数
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 设置APB1总线时钟分频系数
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 设置APB2总线时钟分频系数
if (HAL_RCC_