赞
踩
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @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 * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "led.h" #include "key.h" #include "usart1.h" #include "stdio.h" #include "string.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ uint8_t view = 1; uint8_t carnums = 8; uint8_t CNBRnums = 2; uint8_t VNBRnums = 4; uint8_t IDLEnums = 2; float CNBRprice = 3.50f; float VNBRprice = 2.00f; uint8_t lcdtext[20]; extern struct Key key[4]; uint8_t pwm = 0; extern uint8_t rxflag; extern uint8_t rxdata[1]; extern uint8_t rxindex; extern uint8_t rxbuffer[22]; uint8_t cartype[4]; uint8_t carnum[4]; uint8_t cartime[12]; uint8_t printtext[30]; struct Times { int year; int month; int day; int hour; int min; }; struct Cars // 串口接收 { char carKind[5]; //车型 char carNum[5]; //车牌号 char carTime[12]; //进入时间 struct Times Time; }; struct Cars car; struct Cars park[8]={0,0,0,0,0,0,0,0}; float stopprice; uint8_t led,led1enable,led2enable; int monthDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; uint8_t isError = 0; /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ void key_process(void); void usart1_process(void); void lcd_process(void); void led_process(void); void outpark(uint8_t car_num); void inpark(void); void isErrorProcess(void); void lcdclear(void); int isLeapYear(int year); long dateToTotalMinutes(struct Times t); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); MX_TIM17_Init(); MX_USART1_UART_Init(); HAL_TIM_Base_Start_IT(&htim2); HAL_UART_Receive_IT(&huart1,rxdata,1); /* USER CODE BEGIN 2 */ LCD_Init(); lcdclear(); led_Display(0x00); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { key_process(); usart1_process(); lcd_process(); led_process(); isErrorProcess(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ 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 RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2; RCC_OscInitStruct.PLL.PLLN = 20; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 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 buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } /** Initializes the peripherals clocks */ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ void key_process(void) { if(key[0].key_single_flag) { key[0].key_single_flag = 0; if(view==1) { view = 2; }else{ view = 1; } } if(key[1].key_single_flag) { key[1].key_single_flag = 0; if(view==2) { CNBRprice+=0.5f; VNBRprice+=0.5f; } } if(key[2].key_single_flag) { key[2].key_single_flag = 0; if(view==2) { CNBRprice-=0.5f; VNBRprice-=0.5f; } } if(key[3].key_single_flag) { key[3].key_single_flag = 0; pwm=!pwm; if (pwm) { HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,200); }else{ HAL_TIM_PWM_Stop(&htim17, TIM_CHANNEL_1); // 停止PWM HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); // 设置PA7为低电平 } } } void outpark(uint8_t car_num) { sscanf(car.carTime, "%4d%2d%2d%2d%2d", &car.Time.year, &car.Time.month, &car.Time.day, &car.Time.hour, &car.Time.min); // 计算两个时间点的总分钟数 long carTimeInMin = dateToTotalMinutes(car.Time); long parkTimeInMin = dateToTotalMinutes(park[car_num].Time); // 计算经过的总时间(以分钟为单位),并转换为小时 long diffInMin = carTimeInMin - parkTimeInMin; int hoursPassed = diffInMin / 60; // 如果不满一小时,则按一小时计算 if(diffInMin % 60 > 0) { hoursPassed++; } // 保证至少为1小时 if(hoursPassed <= 0) { hoursPassed = 1; } if(strcmp(car.carKind,"VNBR") ==0) { VNBRnums --; IDLEnums ++; stopprice=hoursPassed*VNBRprice; }else if(strcmp(car.carKind,"CNBR") ==0) { CNBRnums --; IDLEnums ++; stopprice=hoursPassed*CNBRprice; } memset(&park[car_num],0,sizeof(park[car_num])); sprintf((char *)printtext,"%s:%s:%d:%.2f\r\n",car.carKind,car.carNum,hoursPassed,stopprice); HAL_UART_Transmit(&huart1,printtext,strlen((char *)printtext),50); } void inpark(void) { sscanf(car.carTime, "%4d%2d%2d%2d%2d", &car.Time.year, &car.Time.month, &car.Time.day, &car.Time.hour, &car.Time.min); for (int i = 0; i < 8; i++) { // 查找第一个空位 if (park[i].carNum[0] == '\0') { // 假设未使用的车位carNum为'\0' park[i] = car; // 更新车位统计信息 if (strcmp(car.carKind, "CNBR") == 0) { CNBRnums++; IDLEnums--; } else if (strcmp(car.carKind, "VNBR") == 0) { VNBRnums++; IDLEnums--; } break; // 退出循环 } } } void usart1_process(void) { if(rxflag) { rxflag = 0; rxindex = 0; int parsedItems = sscanf((char*)rxbuffer,"%4s:%4s:%12s",car.carKind,car.carNum,car.carTime); if(parsedItems == 3) { if(strcmp(car.carKind,"CNBR")==0||strcmp(car.carKind,"VNBR")==0)//格式正确 { for(int i = 0;i < 8;i++) { if(strcmp(park[i].carNum,car.carNum)==0) //车库中有,需要出库 { if(strcmp(park[i].carKind,car.carKind) == 0) { outpark(i); break; }else{ isError = 1; } }else if(strcmp(park[i].carNum,car.carNum)!=0&&IDLEnums>0)//车库中没有需要,入库 { inpark(); break; } } }else { isError = 1; } }else { isError = 1; } rxflag = 0; rxindex = 0; HAL_UART_Receive_IT(&huart1,rxdata,1); } } void isErrorProcess(void) { if(isError == 1) { sprintf((char *)printtext,"Error\r\n"); HAL_UART_Transmit(&huart1,(uint8_t*)printtext,strlen((char *)printtext),50); isError = 0; } } void lcd_process(void) { switch (view) { case 1://车位显示页面 { sprintf((char *)lcdtext," Data"); LCD_DisplayStringLine(Line1,lcdtext); sprintf((char *)lcdtext," CNBR:%d",CNBRnums); LCD_DisplayStringLine(Line3,lcdtext); sprintf((char *)lcdtext," VNBR:%d",VNBRnums); LCD_DisplayStringLine(Line5,lcdtext); sprintf((char *)lcdtext," IDLE:%d",IDLEnums); LCD_DisplayStringLine(Line7,lcdtext); } break; case 2: //费率设置页面 { sprintf((char *)lcdtext," Para"); LCD_DisplayStringLine(Line1,lcdtext); sprintf((char *)lcdtext," CNBR:%.2f",CNBRprice); LCD_DisplayStringLine(Line3,lcdtext); sprintf((char *)lcdtext," VNBR:%.2f",VNBRprice); LCD_DisplayStringLine(Line5,lcdtext); } break; } } void led_process(void) { if(IDLEnums>0) { led1enable = 1; }else{ led1enable = 0; } if(pwm==1) { led2enable = 1; }else{ led2enable = 0; } if(led1enable) { led|=0x01; }else{ led&=~0x01; } if(led2enable) { led|=0x02; }else{ led&=~0x02; } led_Display(led); } void lcdclear() { LCD_Clear(Black); LCD_SetBackColor(Black); LCD_SetTextColor(White); } int isLeapYear(int year) { if (year % 4 != 0) return 0; if (year % 100 != 0) return 1; if (year % 400 == 0) return 1; return 0; } long dateToTotalMinutes(struct Times t) { // 添加之前的年份所包含的分钟数 long totalMinutes = (t.year - 1) * 365 * 24 * 60; // 添加闰年的额外分钟数 totalMinutes += ((t.year - 1) / 4 - (t.year - 1) / 100 + (t.year - 1) / 400) * 24 * 60; // 添加当前年份中之前月份的分钟数 for (int i = 0; i < t.month - 1; i++) { totalMinutes += monthDays[i] * 24 * 60; } // 如果当前年份是闰年并且月份大于2,则额外添加一天的分钟数 if (t.month > 2 && isLeapYear(t.year)) totalMinutes += 24 * 60; // 添加当前月份中的天数、小时和分钟 totalMinutes += (t.day - 1) * 24 * 60; // 天数减1,因为当天不满24小时 totalMinutes += t.hour * 60; totalMinutes += t.min; return totalMinutes; } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#include "key.h" struct Key key[4]={0,0,0,0}; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance==TIM2) { key[0].key_gpio = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0); key[1].key_gpio = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1); key[2].key_gpio = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2); key[3].key_gpio = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0); for(int i = 0;i<4;i++) { switch (key[i].key_status) { case 0: { if(key[i].key_gpio==0) { key[i].key_status = 1; } } break; case 1: { if(key[i].key_gpio==0) { key[i].key_single_flag = 1; key[i].key_status = 2; }else{ key[i].key_status = 0; } } break; case 2: { if(key[i].key_gpio==1) { key[i].key_status = 0; } } break; } } } }
#include "led.h"
void led_Display(uint8_t led)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC,led<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
#include "usart1.h" #include "usart.h" #include "string.h" uint8_t rxflag; uint8_t rxdata[1]; uint8_t rxindex = 0; uint8_t rxbuffer[22]; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance==USART1) { rxbuffer[rxindex++] = rxdata[0]; HAL_UART_Receive_IT(huart,rxdata,1); if(rxindex==22) { rxflag = 1; } } }
程序很常规,只有串口那里处理比较麻烦,有几个注意事项
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。