题目
题目和程序:阿里云盘链接
题目分析
1.LCD显示驱动
移植官方提供的LCD程序
2.PA7脉冲输出
只需要改变脉冲高电平时间即可。
3.uart
中断接受字符串,IDLE中断来判断字符串接受完成。
总结
1.比赛的时候在字符串处理部分浪费的时间较长,没看清题目要求的格式,导致没做完。字符串处理部分可以优化。
2.GPIO部分自己练的时候没注意LCD对LED的影响。练习的时候基本上没对多个操作,比赛的时候每次操作LED,其他灯也亮起来,傻眼了。后面重新写了驱动。
程序
cubemx初始化要用到的外设
用的平台:stm32g474re
1.配置时钟和debug
2.初始化用到按键的GPIO和PD2
先不初始化LED引脚
3.初始化tim3,和uart1
uart用中断接受
4·生成mdk5工程
程序
1.用官方提供的LCD程序,LCD有关的部分添加到生成的工程
如果新建文件夹的话,先把文件夹添加到头文件路径中
打开官方提供的LCD工程,在main.c里找到MX_GPIO_Init()函数,复制到自己的工程gpio.c
文件里,然后改名static void LCD_MX_GPIO_Init(void),然后在MX_GPIO_Init()调用即可。
/**
******************************************************************************
* @file gpio.c
* @brief This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/* USER CODE BEGIN 0 */
static void LCD_MX_GPIO_Init(void);
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure GPIO */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB0 PB1 PB2 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PD2 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
LCD_MX_GPIO_Init(); //lcd有关gpio初始化
}
/* USER CODE BEGIN 2 */
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void LCD_MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0
|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4
|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
/*Configure GPIO pins : PC13 PC14 PC15 PC0
PC1 PC2 PC3 PC4
PC5 PC6 PC7 PC8
PC9 PC10 PC11 PC12 */
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0
|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4
|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PA8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB5 PB8 PB9 */
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE END 2 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
tips:原理图可以发现,所有LED引脚和LCD引脚引脚共用,所有不用在cubemx里浪费时间初始化LED引脚。
编译器设置为armcompiler6,选择微库。armcompiler6编译速度快
复制LCD工程,main函数LCD有关部分的代码,编译下载测试是否移植正确
2.全部程序
1.LED和按键
uint16_t gpio = 0xff00; //高8位对应我们设置LED的状态
/*******************************************************************************
* Description : open the led.
* Input : led number (1-8)
* Return : None
*******************************************************************************/
void led_on(uint8_t num)
{
gpio = gpio & (~(0x80 << num)); //清零对应的位,不影响其他位
GPIOC->ODR = gpio | ((GPIOC->ODR) & 0x00ff); //不影响低8位
//更新到LED
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
/*******************************************************************************
* Description : close the led.
* Input : led number (1-8)
* Return : None
*******************************************************************************/
void led_off(uint8_t num)
{
gpio = gpio | (0x80 << num); //置位应的位,不影响其他位
GPIOC->ODR = gpio | ((GPIOC->ODR) & 0x00ff); //不影响低8位
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7 << num, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
/*******************************************************************************
* Description : close all led.
* Input : None
* Return : None
*******************************************************************************/
void led_off_all(void)
{
gpio = 0xff00;
GPIOC->ODR = gpio | ((GPIOC->ODR) & 0x00ff); //不影响低8位
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
/*******************************************************************************
* Description : get the keyvalue
* Input : None
* Return : None
*******************************************************************************/
key key_scan()
{
key key_value = no_key;
if ((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) || (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET) ||
(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET) || (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET))
{
HAL_Delay(20);
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)
{
key_value = key1_on;
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)
;
return key_value;
}
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)
{
key_value = key2_on;
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)
;
return key_value;
}
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)
{
key_value = key3_on;
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)
;
return key_value;
}
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
{
key_value = key4_on;
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
;
return key_value;
}
}
return no_key;
}
LED的话,因为LED和LCD共用引脚,每次写LCD 会会改变gpio的输出状态,所有用一个全局变量来保存LED的状态,每次操作LED,先写这个全局变量,然后更新到GPIOC的odr寄存器,否则的会出现干扰情况。(为了不影响GPIOC的第八位,可以先读取GPIOC,ODR,然后保存到gpio变量中,再次写入)uart
开接受中断,重定向printf
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
#include "stdio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); //开接受中断
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
//重定向printf
int fputc(int ch,FILE *f)
{
while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TXE)!=SET);
huart1.Instance->TDR=(uint8_t)ch;
return ch;
}
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
重写中断处理程序
按照hal库设定来写中断处理函数,比较啰嗦,低效
bsp.c
char rxbuff[50];
uint8_t uart_flag_rx = 0;
uint8_t uart_rx_index = 0;
stm32g4xx_it.c
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
uint8_t ch;
if(__HAL_UART_GET_IT(&huart1,UART_IT_RXNE)==SET)
{
ch=huart1.Instance->RDR;
{
rxbuff[uart_rx_index++]=ch;
uart_flag_rx=1;
}
__HAL_UART_CLEAR_IT(&huart1,UART_IT_RXNE);
}
/* USER CODE END USART1_IRQn 0 */
//HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
总的功能实现
#ifndef _BSP_H_
#define _BSP_H_
#include "main.h"
#include "lcd.h"
#include "usart.h"
typedef enum
{
no_key,
key1_on,
key2_on,
key3_on,
key4_on
} key;
typedef struct
{
uint8_t year;
uint8_t mounth;
uint8_t date;
uint8_t hour;
uint8_t minute;
uint8_t second;
} time_s;
typedef enum
{
NO_car,
CNBR,
VNBR
} cartype_e;
typedef struct
{
cartype_e cartype;
char bianhao[5];
time_s time;
} car;
extern char rxbuff[50];
extern uint8_t uart_flag_rx;
extern uint8_t uart_rx_index;
void led_on(uint8_t num);
void led_off_all(void);
void led_off(uint8_t num);
key key_scan();
void carbus_running(void);
#endif
#include "bsp.h"
#include "tim.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define ERROR printf("Error")
const uint8_t mouth_data[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
car carbus[8]; //代表车库,有8个车位
struct para_s
{
float CNBR;
float VNBR;
} para;
char rxbuff[50];
uint8_t uart_flag_rx = 0;
uint8_t uart_rx_index = 0;
uint16_t gpio = 0xff00; //高8位对应我们设置LED的状态
/*******************************************************************************
* Description : open the led.
* Input : led number (1-8)
* Return : None
*******************************************************************************/
void led_on(uint8_t num)
{
gpio = gpio & (~(0x80 << num)); //清零对应的位,不影响其他位
GPIOC->ODR = gpio | ((GPIOC->ODR) & 0x00ff); //不影响低8位
//更新到LED
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
/*******************************************************************************
* Description : close the led.
* Input : led number (1-8)
* Return : None
*******************************************************************************/
void led_off(uint8_t num)
{
gpio = gpio | (0x80 << num); //置位应的位,不影响其他位
GPIOC->ODR = gpio | ((GPIOC->ODR) & 0x00ff); //不影响低8位
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7 << num, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
/*******************************************************************************
* Description : close all led.
* Input : None
* Return : None
*******************************************************************************/
void led_off_all(void)
{
gpio = 0xff00;
GPIOC->ODR = gpio | ((GPIOC->ODR) & 0x00ff); //不影响低8位
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
/*******************************************************************************
* Description : get the keyvalue
* Input : None
* Return : None
*******************************************************************************/
key key_scan()
{
key key_value = no_key;
if ((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) || (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET) ||
(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET) || (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET))
{
HAL_Delay(20);
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)
{
key_value = key1_on;
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)
;
return key_value;
}
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)
{
key_value = key2_on;
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)
;
return key_value;
}
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)
{
key_value = key3_on;
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)
;
return key_value;
}
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
{
key_value = key4_on;
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
;
return key_value;
}
}
return no_key;
}
/*******************************************************************************
* Description : change the pwm captre PA7,更改pa7的模式
* Input : None
* Return : None
*******************************************************************************/
void pwm_change()
{
uint32_t value = 0;
value = __HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_2); //获取tim3,channnel2的ccr值
if (value == 100)
{
led_off(2);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
}
else if (value == 0)
{
led_on(2);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 100);
}
else
{
led_off(2);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
}
}
void carbus_init()
{
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
para.CNBR = 3.50f;
para.VNBR = 2.00f;
for (int i = 0; i < 8; i++)
carbus[i].cartype = NO_car;
}
/*******************************************************************************
* Description :
* Input : None
* Return : None
*******************************************************************************/
void show_data()
{
char lcdbuff[20];
uint16_t cnbr, vnbr;
cnbr = 0;
vnbr = 0;
int i = 0;
for (i = 0; i < 8; i++)
{
if (carbus[i].cartype == CNBR)
cnbr++;
else if (carbus[i].cartype == VNBR)
vnbr++;
}
LCD_ClearLine(Line3);
sprintf(lcdbuff, " CNBR:%d", cnbr);
LCD_DisplayStringLine(Line3, (uint8_t *)lcdbuff);
LCD_ClearLine(Line5);
sprintf(lcdbuff, " VNBR:%d", vnbr);
LCD_DisplayStringLine(Line5, (uint8_t *)lcdbuff);
LCD_ClearLine(Line7);
sprintf(lcdbuff, " IDLE:%d", 8 - cnbr - vnbr);
LCD_DisplayStringLine(Line7, (uint8_t *)lcdbuff);
if (vnbr + cnbr == 8)
{
led_off(1);
}
else
led_on(1);
}
void show_para_s()
{
char lcdbuff[20];
LCD_ClearLine(Line3);
sprintf(lcdbuff, " CNBR:%.2f", para.CNBR);
LCD_DisplayStringLine(Line3, (uint8_t *)lcdbuff);
LCD_ClearLine(Line5);
sprintf(lcdbuff, " VNBR:%.2f", para.VNBR);
LCD_DisplayStringLine(Line5, (uint8_t *)lcdbuff);
}
/*******************************************************************************
* Description : 计算2000年到2100年间输入的两个时间差
* Input : @time_new:更 新的时间
@time_old: 老的时间 两个都是时间结构体
* Return : None
*******************************************************************************/
uint32_t calc(time_s time_new, time_s time_old)
{
uint32_t time1, time2;
uint32_t m1, t;
time1=time2=m1=0;
int i=0;
if (time_old.year % 4 == 0)
{
t = 1;
}
else
t = 0;
for (i = 1; i < time_old.mounth; i++)
{
m1 += mouth_data[i-1];
}
m1 = m1 + t + time_old.date; //计算输入的是今年的那天
time1 = (time_old.year - 1) * 365 + (time_old.year - 1) / 4 + m1; //2000起的第几天
time1 = time1 * 24 * 60 + time_old.hour * 60 + time_old.minute; //2000起的第几分钟
time1 = time1 * 60 + time_old.second;
m1 = 0;
if (time_new.year % 4 == 0)
{
t = 1;
}
else
t = 0;
for (i = 1; i < time_new.mounth; i++)
{
m1 += mouth_data[i-1];
}
m1 = m1 + t + time_new.date; //计算输入的是今年的那天
time2 = (time_new.year - 1) * 365 + (time_new.year - 1) / 4 + m1; //2000起的第几天
time2 = time2 * 24 * 60 + time_new.hour * 60 + time_new.minute; //2000起的第几分钟
time2 = time2 * 60 + time_new.second;
if (time2 < time1)
return 0xffffffff;
time2 = time2 - time1; //算出两个时间差
time1 = time2 / 3600 + ((time2 % 3600 == 0) ? 0 : 1); //求差几个小时
return time1;
}
void carbusdeal(car car1)
{
int i = 0;
uint32_t time1;
float mony;
//车已经存在
for (i = 0; i < 8; i++)
{
if (carbus[i].cartype == car1.cartype)
{
if (strncmp(carbus[i].bianhao, car1.bianhao, 5) == 0)
{
time1 = calc(car1.time, carbus[i].time);
if (time1 == 0xffffffff)
{
ERROR;
return;
}
mony = time1 * ((car1.cartype == CNBR) ? para.CNBR : para.VNBR);
carbus[i].cartype = NO_car;
printf("%s:%s:%d:%.2f", ((car1.cartype == CNBR) ? "CNBR" : "VNBR"), car1.bianhao, time1, mony);
return;
}
}
}
//车刚入库
for (i = 0; i < 8; i++)
{
if (carbus[i].cartype == NO_car)
{
carbus[i] = car1;
return;
}
}
//无车位
ERROR;
}
void uart_string_deal()
{
uint8_t strlenth = strlen(rxbuff);
if (strlenth != 22)
{
printf("Error");
memset(rxbuff, 0, 50);
return;
}
car car1;
char buff[5];
int i = 0;
for (i = 0; i < 4; i++)
{
buff[i] = rxbuff[i];
}
buff[4] = '\0';
if (strncmp(buff, "VNBR", 5) == 0)
{
car1.cartype = VNBR;
}
else if (strncmp(buff, "CNBR", 5) == 0)
{
car1.cartype = CNBR;
}
else
{
ERROR;
memset(rxbuff, 0, 50);
return;
}
for (i = 5; i < 9; i++)
{
car1.bianhao[i - 5] = rxbuff[i];
}
car1.bianhao[4] = '\0';
for (i = 10; i < 12; i++)
{
buff[i - 10] = rxbuff[i];
}
buff[2] = '\0';
buff[3] = '\0';
buff[4] = '\0';
car1.time.year = atoi(buff);
if (car1.time.year > 99 || car1.time.year < 0)
{
ERROR;
memset(rxbuff, 0, 50);
return;
}
for (i = 12; i < 14; i++)
{
buff[i - 12] = rxbuff[i];
}
car1.time.mounth = atoi(buff);
if (car1.time.mounth < 1 || car1.time.mounth > 12)
{
ERROR;
memset(rxbuff, 0, 50);
return;
}
for (i = 14; i < 16; i++)
{
buff[i - 14] = rxbuff[i];
}
car1.time.date = atoi(buff);
if (car1.time.date < 1 || car1.time.date > 31)
{
ERROR;
memset(rxbuff, 0, 50);
return;
}
for (i = 16; i < 18; i++)
{
buff[i - 16] = rxbuff[i];
}
car1.time.hour = atoi(buff);
if (car1.time.hour < 0 || car1.time.hour > 23)
{
ERROR;
memset(rxbuff, 0, 50);
return;
}
for (i = 18; i < 20; i++)
{
buff[i - 18] = rxbuff[i];
}
car1.time.minute = atoi(buff);
if (car1.time.minute < 0 || car1.time.minute > 59)
{
ERROR;
memset(rxbuff, 0, 50);
return;
}
for (i = 20; i < 22; i++)
{
buff[i - 20] = rxbuff[i];
}
car1.time.second = atoi(buff);
if (car1.time.second < 0 || car1.time.second > 59)
{
ERROR;
memset(rxbuff, 0, 50);
return;
}
memset(rxbuff, 0, 50);
carbusdeal(car1);
}
void carbus_running()
{
key key_v = no_key;
carbus_init();
LCD_Clear(Black);
LCD_DisplayStringLine(Line1, (uint8_t *)" Data ");
show_data();
while (1)
{
key_v = key_scan();
if (key_v == key1_on)
{
LCD_Clear(Black);
LCD_DisplayStringLine(Line1, (uint8_t *)" Para ");
show_para_s();
while (1)
{
key_v = key_scan();
if (key_v == key2_on)
{
para.VNBR += 0.5f;
para.CNBR += 0.5f;
show_para_s();
}
else if (key_v == key3_on)
{
if (para.VNBR < 0.5f)
{
continue;
}
para.VNBR -= 0.5f;
para.CNBR -= 0.5f;
show_para_s();
}
else if (key_v == key4_on)
{
pwm_change();
}
else if (key_v == key1_on)
{
LCD_Clear(Black);
LCD_DisplayStringLine(Line1, (uint8_t *)" Data ");
show_data();
break;
}
}
}
else if (key_v == key4_on)
{
pwm_change();
}
//接受完成标志
if ((uart_flag_rx == 1) && (__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)==1))
{
uart_string_deal();
uart_flag_rx = 0;
uart_rx_index=0;
show_data();
}
}
}
版权声明:本文为CSDN博主「nuralimengineer」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nuralimengineer/article/details/119845331
暂无评论