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 生效路径
## 十、后续建议