STM32F4_TIM基本延时(计数原理)

本文详细介绍了STM32F4使用TIM进行基本延时的实现,包括TIM计数原理、参数配置、代码分析以及如何实现1us和1ms的延时。提供了实例工程下载链接,适合STM32F4初学者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Ⅰ、概述

STM32 TIM 定时器分为三类:基本定时器、通用定时器和高级定时器。从分类来看就知道 STM32 的定时器功能是非常强大的,但是,功能强大了,软件配置定时器就相对复杂多了。很多初学者甚至工作了一段时间的人都不知道 STM32 最基本的计数原理
虽然 STM32 定时器功能强大,也分了三类,但他们最基本的计数部分原理都是一样的,也就是我们常常使用的延时(或定时)多少 us ms 等。
接下来我会 讲述关于STM32最基本的计数原理,详细讲述如何做到 ( 配置 ) 计数1us的延时,并提供实例代码供大家参考学习。
 

关于本文的更多详情请往下看。

 

Ⅱ、实例工程下载

笔者针对于初学者提供的例程都是去掉了许多不必要的功能,精简了官方的代码,对初学者一看就明白,以简单明了的工程供大家学习。

笔者提供的实例工程都是在板子上经过多次测试并没有问题才上传至360云盘,欢迎下载测试、参照学习。

 

提供下载的软件工程是STM32F417的,但F4其他型号也适用(适用F4其他型号: 关注微信,回复“修改型号”)。

 

STM32F4_TIM基本延时(1us延时基准)实例:

https://yunpan.cn/cB3hC8amiyq2C  访问密码 5224

<think>我们正在解决STM32HAL库中出现的"HAL_InitTickmultiplydefined"链接错误。错误信息指出在core_delay.o和stm32f4xx_hal_timebase_tim.o中重复定义了HAL_InitTick函数。###错误原因分析在STM32HAL库中,`HAL_InitTick`函数是用于初始化系统滴答定时器(SysTick)的,它为HAL提供时基。这个错误通常发生在以下情况:1.**用户自定义了时基源**:当我们使用定时器(如TIM)代替SysTick作为HAL时基源时,我们通常会重新实现`HAL_InitTick`函数(以及相关的时基函数)并放在一个单独的文件中(例如`stm32f4xx_hal_timebase_tim.c`)。2.**同时存在多个定义**:如果工程中同时包含了HAL库默认的时基实现(通常通过`stm32f4xx_hal.c`提供)和我们自定义的时基实现文件(如`stm32f4xx_hal_timebase_tim.c`),那么就会导致`HAL_InitTick`函数被重复定义。###解决方案1.**移除默认的时基实现**:确保工程中没有同时包含默认的HAL时基源文件和自定义的时基源文件。通常,默认的时基实现在`stm32f4xx_hal.c`中,而自定义的时基实现在`stm32f4xx_hal_timebase_tim.c`中。我们需要从工程中移除其中一个。-如果使用自定义定时器作为时基源,则应该保留`stm32f4xx_hal_timebase_tim.c`,并从工程中移除`stm32f4xx_hal.c`(或者至少确保该文件中的时基相关函数不被编译)。但注意,`stm32f4xx_hal.c`中还有其他重要的HAL初始化函数,所以我们不能简单地移除整个文件。2.**正确配置HAL时基源**:在`stm32f4xx_hal_conf.h`配置文件中,我们需要确保正确设置了时基源:```c#defineHAL_TIM_MODULE_ENABLED//启用TIM模块(如果我们使用TIM作为时基源)```并且,我们需要指定HAL使用TIM而不是SysTick:```c#defineHAL_TIMEBASE_SOURCETIM//使用TIM作为HAL时基源```3.**检查自定义时基文件**:确保自定义的时基文件(如`stm32f4xx_hal_timebase_tim.c`)中实现了以下函数:```cHAL_StatusTypeDefHAL_InitTick(uint32_tTickPriority);uint32_tHAL_GetTick(void);voidHAL_Delay(uint32_tDelay);voidHAL_SuspendTick(void);voidHAL_ResumeTick(void);```同时,确保这些函数没有被定义两次(例如,检查是否在多个文件中定义了这些函数)。4.**避免重复包含**:检查工程中是否同时存在多个自定义时基文件,或者是否将同一个源文件添加了多次。###具体操作步骤1.打开工程,检查源文件:-移除`stm32f4xx_hal_timebase_tim.c`(自定义时基文件)和`stm32f4xx_hal.c`(HAL核心文件)中的其中一个?实际上,我们不能移除`stm32f4xx_hal.c`,因为它包含HAL库的核心初始化函数。正确的做法是:-在`stm32f4xx_hal.c`中,通过条件编译排除时基相关函数。但是,HAL库默认并没有提供这样的条件编译选项。因此,我们通常采用另一种方法:不将`stm32f4xx_hal.c`中的时基函数编译进工程。2.修改`stm32f4xx_hal.c`:我们可以通过宏定义来跳过`stm32f4xx_hal.c`中的时基函数定义。在`stm32f4xx_hal.c`中,时基函数(如`HAL_InitTick`)通常是弱定义的(weaksymbol),我们可以通过定义宏`HAL_TIM_MODULE_ENABLED`来覆盖这些弱定义。但是,如果我们自定义的时基文件已经实现了这些函数,链接器应该优先使用强定义(自定义文件中的定义)而忽略弱定义。然而,如果两个都是强定义(或者自定义文件中也是弱定义?)就会冲突。3.**最可靠的解决方案**:确保自定义时基文件(`stm32f4xx_hal_timebase_tim.c`)中的函数是强定义,并且从工程中排除默认的时基实现。但是,由于默认的时基实现在`stm32f4xx_hal.c`中,我们不能排除整个文件。因此,我们可以:-在`stm32f4xx_hal.c`中注释掉时基函数(不推荐,因为修改库文件可能导致升级问题)。-或者,在工程设置中,将`stm32f4xx_hal.c`中的时基函数排除编译(如果IDE支持单个函数排除,但通常不支持)。4.**使用条件编译**:在`stm32f4xx_hal.c`中,时基函数通常被包裹在`#ifndefHAL_TIMEBASE_SOURCE...#endif`中。检查该文件,我们会发现类似以下代码:```c#if!defined(HAL_TIMEBASE_SOURCE)||(HAL_TIMEBASE_SOURCE==HAL_TIMEBASE_SOURCE_SYSTICK)...//这里定义了默认的SysTick时基函数#endif```因此,我们只需要在`stm32f4xx_hal_conf.h`中定义:```c#defineHAL_TIMEBASE_SOURCEHAL_TIMEBASE_SOURCE_TIM//或者直接定义TIM```这样,`stm32f4xx_hal.c`中的默认时基函数就不会被编译。###总结步骤1.在`stm32f4xx_hal_conf.h`中定义:```c#defineHAL_TIM_MODULE_ENABLED#defineHAL_TIMEBASE_SOURCETIM//或者HAL_TIMEBASE_SOURCE_TIM,具体取决于HAL库版本```注意:有些HAL库版本使用`HAL_TIMEBASE_SOURCE_TIM`,请参考库文件中的定义。2.确保自定义时基文件(如`stm32f4xx_hal_timebase_tim.c`)已添加到工程中,并且该文件中实现了所有必要的时基函数。3.清理并重新编译工程。###注意事项-如果使用CubeMX生成代码,确保在CubeMX中正确配置了时基源(选择TIM而非SysTick),这样CubeMX会自动生成自定义时基文件并正确配置`stm32f4xx_hal_conf.h`。-如果手动移植,请仔细检查上述配置。通过以上步骤,应该能解决重复定义的问题。§§相关问题§§1.如何配置STM32CubeMX以使用TIM作为HAL时基源?2.在STM32HAL库中,如何实现微秒级延时?3.除了链接错误,使用自定义时基源时还有哪些常见问题?</think>### 解决STM32 HAL库中HAL_InitTick符号重复定义的链接错误 #### 错误原因分析 该错误通常由以下原因引起: 1. **时基源冲突**:工程中同时存在默认的SysTick时基实现和自定义的TIM时基实现,导致`HAL_InitTick()`被重复定义。 2. **配置错误**:`stm32f4xx_hal_conf.h`未正确定义`HAL_TIMEBASE_SOURCE`宏,或未禁用默认时基源。 3. **文件冲突**:`core_delay.o`(SysTick实现)和`stm32f4xx_hal_timebase_tim.o`(TIM实现)同时被链接。 #### 解决方案步骤 ##### 1. 修改HAL配置文件 在`stm32f4xx_hal_conf.h`中添加以下宏定义: ```c // 使用TIM作为HAL时基源 #define HAL_TIMEBASE_SOURCE TIM // 关键配置 // 禁用SysTick时基源 #undef HAL_SYSTICK_MODULE_ENABLED ``` ##### 2. 检查时基实现文件 - 保留 **自定义TIM时基文件**(如`stm32f4xx_hal_timebase_tim.c`) - 移除 **SysTick时基实现**: - 从工程中排除`stm32f4xx_hal.c`(或确保其不参与编译) - 如果使用CubeMX生成代码,需在IDE中移除该文件的编译 ##### 3. 验证自定义时基函数 在`stm32f4xx_hal_timebase_tim.c`中确保包含完整的TIM时基实现: ```c // TIM时基初始化 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { // 您的TIM配置代码(例如TIM6初始化) // ... } // 实现其他必要函数 uint32_t HAL_GetTick(void) { /* TIM计数转毫秒 */ } void HAL_Delay(uint32_t Delay) { /* 基于TIM延时 */ } ``` ##### 4. 清理和重建工程 1. 执行`Project → Clean`彻底清理中间文件 2. 重新编译整个工程(确保修改后的配置生效) #### 关键原理说明 - HAL库要求**只能有一个时基源**生效[^1]。 - 默认时基源是SysTick(通过`stm32f4xx_hal.c`实现)。 - 当使用TIM作为时基时,必须通过`#define HAL_TIMEBASE_SOURCE TIM`明确声明,并移除默认实现[^2]。 #### 常见错误排查 - **错误未消失**:检查是否仍有文件包含`HAL_SYSTICK_MODULE_ENABLED` - **新出现HardFault**:确认TIM时基配置正确(时钟频率、预分频等) - **CubeMX用户注意**:在`SYS`配置中需选择`TIM`作为Timebase Source > 通过以上步骤,可解决99%的`HAL_InitTick`重复定义问题。若仍有问题,请提供您的时基配置文件内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

strongerHuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值