#include "system.h" #include "uart.h" #include "relay.h" DMA_HandleTypeDef hdma_usart3_rx; DMA_HandleTypeDef hdma_uart4_rx; static IWDG_HandleTypeDef hiwdg; /* 独立看门狗句柄,本模块内私有 */ /* LSI(~40kHz) / 256分频 / 重载4095 → 超时约26s(LSI 漂移下最短约17s) */ static void MX_IWDG_Init(void) { hiwdg.Instance = IWDG; hiwdg.Init.Prescaler = IWDG_PRESCALER_256; hiwdg.Init.Reload = 4095; if (HAL_IWDG_Init(&hiwdg) != HAL_OK) Error_Handler(); } /* 喂狗:主循环和 app_bg_service(长阻塞等待间隙)都必须调用 */ void IWDG_Feed(void) { HAL_IWDG_Refresh(&hiwdg); } /** * @brief 基础硬件初始化一条龙:HAL/时钟/GPIO/DMA/UART/看门狗 * @note BootLoader 跳转前已启动 IWDG,这里尽早接管喂狗; * 之后 NET_init 等长阻塞流程通过 bg_delay → app_bg_service 喂狗 */ void Board_Init(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); /* RS485 喂料秤 */ MX_USART3_UART_Init(); /* 4G Air780E */ MX_UART4_UART_Init(); /* WiFi ESP-01S */ MX_IWDG_Init(); } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) Error_Handler(); 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_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) Error_Handler(); } void MX_DMA_Init(void) { __HAL_RCC_DMA1_CLK_ENABLE(); __HAL_RCC_DMA2_CLK_ENABLE(); HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn); HAL_NVIC_SetPriority(DMA2_Channel3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Channel3_IRQn); } void MX_GPIO_Init(void) { GPIO_InitTypeDef g = {0}; __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /* 继电器为高电平吸合,上电瞬间必须立即置低,防止浮空导致误吸合 */ HAL_GPIO_WritePin(Relay1_Port, Relay1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Relay2_Port, Relay2_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Relay3_Port, Relay3_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(Relay4_Port, Relay4_Pin, GPIO_PIN_RESET); g.Mode = GPIO_MODE_OUTPUT_PP; g.Pull = GPIO_NOPULL; g.Speed = GPIO_SPEED_FREQ_LOW; g.Pin = Relay1_Pin; HAL_GPIO_Init(Relay1_Port, &g); g.Pin = Relay2_Pin; HAL_GPIO_Init(Relay2_Port, &g); g.Pin = Relay3_Pin; HAL_GPIO_Init(Relay3_Port, &g); g.Pin = Relay4_Pin; HAL_GPIO_Init(Relay4_Port, &g); } void Error_Handler(void) { /* 初始化失败:停在这里,若 IWDG 已启动则由看门狗复位 */ __disable_irq(); while (1) { } }