feat: 添加TIM4心跳闪烁并更新文档

This commit is contained in:
2026-03-30 21:06:23 +08:00
parent 9efa2cdc59
commit 0abda47013
9 changed files with 256 additions and 24 deletions
+1 -1
View File
@@ -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 */
+1
View File
@@ -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);
+41
View File
@@ -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__ */
+23
View File
@@ -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();
+15
View File
@@ -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.
*/
+100
View File
@@ -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 */
+15
View File
@@ -414,6 +414,11 @@
<FileType>1</FileType>
<FilePath>../Core/Src/iwdg.c</FilePath>
</File>
<File>
<FileName>tim.c</FileName>
<FileType>1</FileType>
<FilePath>../Core/Src/tim.c</FilePath>
</File>
<File>
<FileName>spi.c</FileName>
<FileType>1</FileType>
@@ -504,6 +509,16 @@
<FileType>1</FileType>
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c</FilePath>
</File>
<File>
<FileName>stm32f1xx_hal_tim.c</FileName>
<FileType>1</FileType>
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c</FilePath>
</File>
<File>
<FileName>stm32f1xx_hal_tim_ex.c</FileName>
<FileType>1</FileType>
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c</FilePath>
</File>
<File>
<FileName>stm32f1xx_hal_uart.c</FileName>
<FileType>1</FileType>
+35 -17
View File
@@ -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
+25 -6
View File
@@ -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 生效路径
## 十、后续建议