From 0abda470132273e7a438809d8f966e28822d30a1 Mon Sep 17 00:00:00 2001 From: xiao Date: Mon, 30 Mar 2026 21:06:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0TIM4=E5=BF=83?= =?UTF-8?q?=E8=B7=B3=E9=97=AA=E7=83=81=E5=B9=B6=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Inc/stm32f1xx_hal_conf.h | 2 +- Core/Inc/stm32f1xx_it.h | 1 + Core/Inc/tim.h | 41 ++++++++++++++ Core/Src/main.c | 23 ++++++++ Core/Src/stm32f1xx_it.c | 15 +++++ Core/Src/tim.c | 100 ++++++++++++++++++++++++++++++++++ MDK-ARM/TCP2UART.uvprojx | 15 +++++ TCP2UART.ioc | 52 ++++++++++++------ 项目技术实现.md | 31 +++++++++-- 9 files changed, 256 insertions(+), 24 deletions(-) create mode 100644 Core/Inc/tim.h create mode 100644 Core/Src/tim.c diff --git a/Core/Inc/stm32f1xx_hal_conf.h b/Core/Inc/stm32f1xx_hal_conf.h index 40e8fbe..a2abc7b 100644 --- a/Core/Inc/stm32f1xx_hal_conf.h +++ b/Core/Inc/stm32f1xx_hal_conf.h @@ -64,7 +64,7 @@ /*#define HAL_SMARTCARD_MODULE_ENABLED */ #define HAL_SPI_MODULE_ENABLED /*#define HAL_SRAM_MODULE_ENABLED */ -/*#define HAL_TIM_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ diff --git a/Core/Inc/stm32f1xx_it.h b/Core/Inc/stm32f1xx_it.h index c195d34..8920405 100644 --- a/Core/Inc/stm32f1xx_it.h +++ b/Core/Inc/stm32f1xx_it.h @@ -59,6 +59,7 @@ void DMA1_Channel4_IRQHandler(void); void DMA1_Channel5_IRQHandler(void); void DMA1_Channel6_IRQHandler(void); void DMA1_Channel7_IRQHandler(void); +void TIM4_IRQHandler(void); void SPI1_IRQHandler(void); void USART1_IRQHandler(void); void USART2_IRQHandler(void); diff --git a/Core/Inc/tim.h b/Core/Inc/tim.h new file mode 100644 index 0000000..8bdfb3a --- /dev/null +++ b/Core/Inc/tim.h @@ -0,0 +1,41 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for the tim.c file + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TIM_H__ +#define __TIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern TIM_HandleTypeDef htim4; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_TIM4_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_H__ */ + diff --git a/Core/Src/main.c b/Core/Src/main.c index c9f823c..1f51baf 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -21,6 +21,7 @@ #include "dma.h" #include "iwdg.h" #include "spi.h" +#include "tim.h" #include "usart.h" #include "gpio.h" @@ -67,6 +68,7 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ +static volatile uint16_t g_led_blink_ticks = 0; /* USER CODE END PV */ @@ -75,6 +77,7 @@ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ static void CH390_HardwareReset(void); static void LED_Init(void); +static void LED_StartBlink(void); static void App_Init(void); static void App_Poll(void); /* USER CODE END PFP */ @@ -109,6 +112,13 @@ static void LED_Init(void) HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET); } +static void LED_StartBlink(void) +{ + if (HAL_TIM_Base_Start_IT(&htim4) != HAL_OK) { + Error_Handler(); + } +} + /** * @brief LED 闪烁(用于指示系统运行状态) */ @@ -117,6 +127,17 @@ void LED_Toggle(void) HAL_GPIO_TogglePin(LED_PORT, LED_PIN); } +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + if (htim->Instance == TIM4) { + g_led_blink_ticks++; + if (g_led_blink_ticks >= 1000u) { + g_led_blink_ticks = 0u; + LED_Toggle(); + } + } +} + static void App_Init(void) { const device_config_t *cfg; @@ -247,10 +268,12 @@ int main(void) MX_USART2_UART_Init(); MX_USART3_UART_Init(); MX_SPI1_Init(); + MX_TIM4_Init(); /* USER CODE BEGIN 2 */ /* LED 初始化 */ LED_Init(); + LED_StartBlink(); /* CH390 硬件复位 */ CH390_HardwareReset(); diff --git a/Core/Src/stm32f1xx_it.c b/Core/Src/stm32f1xx_it.c index c200ee6..ebcc61c 100644 --- a/Core/Src/stm32f1xx_it.c +++ b/Core/Src/stm32f1xx_it.c @@ -59,6 +59,7 @@ /* External variables --------------------------------------------------------*/ extern SPI_HandleTypeDef hspi1; +extern TIM_HandleTypeDef htim4; extern DMA_HandleTypeDef hdma_usart1_rx; extern DMA_HandleTypeDef hdma_usart1_tx; extern DMA_HandleTypeDef hdma_usart2_rx; @@ -268,6 +269,20 @@ void DMA1_Channel7_IRQHandler(void) /* USER CODE END DMA1_Channel7_IRQn 1 */ } +/** + * @brief This function handles TIM4 global interrupt. + */ +void TIM4_IRQHandler(void) +{ + /* USER CODE BEGIN TIM4_IRQn 0 */ + + /* USER CODE END TIM4_IRQn 0 */ + HAL_TIM_IRQHandler(&htim4); + /* USER CODE BEGIN TIM4_IRQn 1 */ + + /* USER CODE END TIM4_IRQn 1 */ +} + /** * @brief This function handles SPI1 global interrupt. */ diff --git a/Core/Src/tim.c b/Core/Src/tim.c new file mode 100644 index 0000000..9e26f3d --- /dev/null +++ b/Core/Src/tim.c @@ -0,0 +1,100 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration of the TIM instances. + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "tim.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +TIM_HandleTypeDef htim4; + +/* TIM4 init function */ +void MX_TIM4_Init(void) +{ + + /* USER CODE BEGIN TIM4_Init 0 */ + + /* USER CODE END TIM4_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM4_Init 1 */ + + /* USER CODE END TIM4_Init 1 */ + htim4.Instance = TIM4; + htim4.Init.Prescaler = 7199; + htim4.Init.CounterMode = TIM_COUNTERMODE_UP; + htim4.Init.Period = 9; + htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim4) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM4_Init 2 */ + + /* USER CODE END TIM4_Init 2 */ + +} + +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM4) + { + /* USER CODE BEGIN TIM4_MspInit 0 */ + + /* USER CODE END TIM4_MspInit 0 */ + /* TIM4 clock enable */ + __HAL_RCC_TIM4_CLK_ENABLE(); + + /* TIM4 interrupt Init */ + HAL_NVIC_SetPriority(TIM4_IRQn, 6, 0); + HAL_NVIC_EnableIRQ(TIM4_IRQn); + /* USER CODE BEGIN TIM4_MspInit 1 */ + + /* USER CODE END TIM4_MspInit 1 */ + } +} + +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM4) + { + /* USER CODE BEGIN TIM4_MspDeInit 0 */ + + /* USER CODE END TIM4_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM4_CLK_DISABLE(); + + /* TIM4 interrupt Deinit */ + HAL_NVIC_DisableIRQ(TIM4_IRQn); + /* USER CODE BEGIN TIM4_MspDeInit 1 */ + + /* USER CODE END TIM4_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/MDK-ARM/TCP2UART.uvprojx b/MDK-ARM/TCP2UART.uvprojx index 8fc56b7..39646df 100644 --- a/MDK-ARM/TCP2UART.uvprojx +++ b/MDK-ARM/TCP2UART.uvprojx @@ -414,6 +414,11 @@ 1 ../Core/Src/iwdg.c + + tim.c + 1 + ../Core/Src/tim.c + spi.c 1 @@ -504,6 +509,16 @@ 1 ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c + + stm32f1xx_hal_tim.c + 1 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c + + + stm32f1xx_hal_tim_ex.c + 1 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c + stm32f1xx_hal_uart.c 1 diff --git a/TCP2UART.ioc b/TCP2UART.ioc index 678ee15..5abec43 100644 --- a/TCP2UART.ioc +++ b/TCP2UART.ioc @@ -31,7 +31,7 @@ Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY Dma.USART2_RX.0.Instance=DMA1_Channel6 Dma.USART2_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.USART2_RX.0.MemInc=DMA_MINC_ENABLE -Dma.USART2_RX.0.Mode=DMA_CIRCULAR +Dma.USART2_RX.0.Mode=DMA_NORMAL Dma.USART2_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.USART2_RX.0.PeriphInc=DMA_PINC_DISABLE Dma.USART2_RX.0.Priority=DMA_PRIORITY_LOW @@ -49,7 +49,7 @@ Dma.USART3_RX.4.Direction=DMA_PERIPH_TO_MEMORY Dma.USART3_RX.4.Instance=DMA1_Channel3 Dma.USART3_RX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.USART3_RX.4.MemInc=DMA_MINC_ENABLE -Dma.USART3_RX.4.Mode=DMA_CIRCULAR +Dma.USART3_RX.4.Mode=DMA_NORMAL Dma.USART3_RX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.USART3_RX.4.PeriphInc=DMA_PINC_DISABLE Dma.USART3_RX.4.Priority=DMA_PRIORITY_LOW @@ -74,10 +74,11 @@ Mcu.IP2=NVIC Mcu.IP3=RCC Mcu.IP4=SPI1 Mcu.IP5=SYS -Mcu.IP6=USART1 -Mcu.IP7=USART2 -Mcu.IP8=USART3 -Mcu.IPNb=9 +Mcu.IP6=TIM4 +Mcu.IP7=USART1 +Mcu.IP8=USART2 +Mcu.IP9=USART3 +Mcu.IPNb=10 Mcu.Name=STM32F103R(8-B)Tx Mcu.Package=LQFP64 Mcu.Pin0=PC13-TAMPER-RTC @@ -91,7 +92,10 @@ Mcu.Pin15=PA13 Mcu.Pin16=PA14 Mcu.Pin17=VP_IWDG_VS_IWDG Mcu.Pin18=VP_SYS_VS_Systick +Mcu.Pin19=VP_TIM4_VS_ControllerModeReset Mcu.Pin2=PD1-OSC_OUT +Mcu.Pin20=VP_TIM4_VS_ClockSourceINT +Mcu.Pin21=VP_TIM4_VS_ClockSourceITR Mcu.Pin3=PA2 Mcu.Pin4=PA3 Mcu.Pin5=PA4 @@ -99,7 +103,7 @@ Mcu.Pin6=PA5 Mcu.Pin7=PA6 Mcu.Pin8=PA7 Mcu.Pin9=PB0 -Mcu.PinsNb=19 +Mcu.PinsNb=22 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F103R8Tx @@ -113,14 +117,16 @@ NVIC.DMA1_Channel5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Channel6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DMA1_Channel7_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.EXTI0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SPI1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:false +NVIC.TIM4_IRQn=true\:6\:0\:false\:false\:true\:true\:false\:true NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.USART2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.USART3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true @@ -135,8 +141,8 @@ PA2.Mode=Asynchronous PA2.Signal=USART2_TX PA3.Mode=Asynchronous PA3.Signal=USART2_RX -PA4.Locked=true -PA4.Signal=GPIO_Output +PA4.Mode=NSS_Signal_Hard_Output +PA4.Signal=SPI1_NSS PA5.Mode=Full_Duplex_Master PA5.Signal=SPI1_SCK PA6.Mode=Full_Duplex_Master @@ -184,7 +190,7 @@ ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x0 ProjectManager.KeepUserCode=true ProjectManager.LastFirmware=true -ProjectManager.LibraryCopy=0 +ProjectManager.LibraryCopy=1 ProjectManager.MainLocation=Core/Src ProjectManager.NoMain=false ProjectManager.PreviousToolchain= @@ -194,7 +200,7 @@ ProjectManager.ProjectName=TCP2UART ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 -ProjectManager.TargetToolchain=MDK-ARM V5.32 +ProjectManager.TargetToolchain=CMake ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= @@ -227,15 +233,21 @@ RCC.USBFreq_Value=72000000 RCC.VCOOutput2Freq_Value=8000000 SH.GPXTI0.0=GPIO_EXTI0 SH.GPXTI0.ConfNb=1 -SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8 -SPI1.CLKPhase=SPI_PHASE_2EDGE -SPI1.CLKPolarity=SPI_POLARITY_HIGH -SPI1.CalculateBaudRate=9.0 MBits/s +SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4 +SPI1.CLKPhase=SPI_PHASE_1EDGE +SPI1.CLKPolarity=SPI_POLARITY_LOW +SPI1.CalculateBaudRate=18.0 MBits/s SPI1.Direction=SPI_DIRECTION_2LINES SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,VirtualNSS,CLKPolarity,CLKPhase SPI1.Mode=SPI_MODE_MASTER -SPI1.VirtualNSS=VM_NSSSOFT +SPI1.VirtualNSS=VM_NSSHARD SPI1.VirtualType=VM_MASTER +TIM4.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_DISABLE +TIM4.IPParameters=AutoReloadPreload,Prescaler,Period,CounterMode,ClockDivision +TIM4.Period=9 +TIM4.Prescaler=7199 +TIM4.CounterMode=TIM_COUNTERMODE_UP +TIM4.ClockDivision=TIM_CLOCKDIVISION_DIV1 USART1.IPParameters=VirtualMode USART1.VirtualMode=VM_ASYNC USART2.IPParameters=VirtualMode @@ -246,4 +258,10 @@ VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM4_VS_ClockSourceINT.Mode=Internal +VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT +VP_TIM4_VS_ClockSourceITR.Mode= +VP_TIM4_VS_ClockSourceITR.Signal=TIM4_VS_ClockSourceITR +VP_TIM4_VS_ControllerModeReset.Mode= +VP_TIM4_VS_ControllerModeReset.Signal=TIM4_VS_ControllerModeReset board=custom diff --git a/项目技术实现.md b/项目技术实现.md index 0c9c91c..0cdf1d8 100644 --- a/项目技术实现.md +++ b/项目技术实现.md @@ -168,6 +168,24 @@ 1. 工程内置最小 `SEGGER RTT` 源文件 2. `main.c` 中 `printf/fputc` 已重定向到 RTT +### 5.7 TIM4 心跳闪烁 + +文件:`Core/Src/tim.c`、`Core/Src/main.c`、`Core/Src/stm32f1xx_it.c` + +已实现: + +1. 使用 `TIM4` 作为 LED 心跳定时器 +2. `TIM4` 时钟来自 `APB1 Timer Clock = 72 MHz` +3. 通过 `Prescaler = 7199` 和 `Period = 9` 生成 `1 ms` 更新中断 +4. 在 `HAL_TIM_PeriodElapsedCallback()` 中进行 1ms 计数 +5. 累计 `1000` 次后翻转一次 `PC13`,形成 `1 s` 闪烁节拍 + +当前实现说明: + +1. `PC13` 为低电平点亮、高电平熄灭 +2. 当前逻辑为每 `1 s` 翻转一次 LED 状态,即完整亮灭周期为 `2 s` +3. 若后续需要“每 1 秒完整闪烁一次”,可改为 `500 ms` 翻转一次 + ## 六、lwIP 配置策略 当前 `lwIP` 配置以适配 `R8T6` 资源为原则,核心策略如下: @@ -227,10 +245,10 @@ while (1) 1. `0 Error(s)` 2. `0 Warning(s)` -3. `Code=38664` +3. `Code=39988` 4. `RO-data=1272` -5. `RW-data=168` -6. `ZI-data=19120` +5. `RW-data=172` +6. `ZI-data=19188` 说明当前版本已经满足: @@ -250,9 +268,10 @@ while (1) 1. 验证 CH390 INT 极性与 EXTI 触发行为 2. 验证 `SPI1` 与 CH390 的稳定性 -3. 验证 `UART2/UART3 DMA + IDLE` 在长连续流量下的行为 -4. 验证 TCP Server 与 TCP Client 双链路同时工作时的稳定性 -5. 验证配置保存、复位、MAC 生效路径 +3. 验证 `TIM4` 1ms 中断稳定性与 `PC13` 1秒翻转节拍 +4. 验证 `UART2/UART3 DMA + IDLE` 在长连续流量下的行为 +5. 验证 TCP Server 与 TCP Client 双链路同时工作时的稳定性 +6. 验证配置保存、复位、MAC 生效路径 ## 十、后续建议