linux 驱动 硬件定时器,RT-Thread 设备驱动-硬件定时器浅析与使用

RT-Thread 4.0.0

访问硬件定时器设备

应用程序通过 RT-Thread 提供的 I/O 设备管理接口来访问硬件定时器设备,相关接口如下所示:

函数

描述

rt_device_find()

查找定时器设备

rt_device_open()

以读写方式打开定时器设备

rt_device_set_rx_indicate()

设置超时回调函数

rt_device_control()

控制定时器设备,可以设置定时模式(单次/周期)/计数频率,或者停止定时器

rt_device_write()

设置定时器超时值,定时器随即启动

rt_device_read()

获取定时器当前值

rt_device_close()

关闭定时器设备

RT-Thread 提供的 I/O 设备硬件定时器,示例仅提供最通用简单的定时功能,其他定时器高级功能需自行在control中添加;

下面对基于CubeMX、Hal库的BSP的硬件定时器的使用做简单描述。

配置CubeMX

7901d1ce1ff21fd153e284ff9718c616.png

配置之后生成代码,

在 stm32f4xx_hal_conf.h 中 会实现 hal模块驱动

#define HAL_TIM_MODULE_ENABLED

修改工程目录下的 Kconfig

在 Kconfig 中添加对 TIM的支持

menuconfig BSP_USING_TIMbool "Enable Hardware TIM"

defaultnselectRT_USING_HWTIMERifBSP_USING_TIM

config BSP_USING_TIM1bool "Enable TIM1"

defaultn

config BSP_USING_TIM2bool "Enable TIM2"

defaultn

config BSP_USING_TIM3bool "Enable TIM3"

defaultn

config BSP_USING_TIM4bool "Enable TIM4"

defaultn

config BSP_USING_TIM5bool "Enable TIM5"

defaultn

config BSP_USING_TIM6bool "Enable TIM6"

default n

然后使用Env工具 menuconfig 中使能 TIM3、TIM4

8e81b464eeaacb0b0808cbbf77c823ef.png

然后 scons --target=mdk5

用keil打开工程后在 tim_config.h 中 添加 TIM3、TIM4的配置

#ifdef BSP_USING_TIM3

#ifndef TIM3_CONFIG#define TIM3_CONFIG \{ \

.tim_handle.Instance=TIM3, \

.tim_irqn=TIM3_IRQn, \

.name= "timer3", \

}#endif /* TIM3_CONFIG */

#endif /* BSP_USING_TIM3 */#ifdef BSP_USING_TIM4

#ifndef TIM4_CONFIG#define TIM4_CONFIG \{ \

.tim_handle.Instance=TIM4, \

.tim_irqn=TIM4_IRQn, \

.name= "timer4", \

}#endif /* TIM4_CONFIG */

#endif /* BSP_USING_TIM4 */

然后就可以在应用中直接操作设备名为 "timer3" 和 "timer4" 的设备了。

设备驱动分析

定时器设备 I/O 实现

hwtimer.c  hwtimer.h

定时器底层驱动实现(操作Hal库)

drv_hwtimer.c  drv_hwtimer.h

下面主要追踪以下定时器设备的注册及其初始化

在 drv_hwtimer.c 中  定时器自动初始化,并注册设备

static int stm32_hwtimer_init(void)

INIT_BOARD_EXPORT(stm32_hwtimer_init);

其中 hwtimer_ops.rt_hwtimer_init 会 调用 timer_init

static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)

{

uint32_t prescaler_value= 0;

TIM_HandleTypeDef*tim =RT_NULL;struct stm32_hwtimer *tim_device =RT_NULL;

RT_ASSERT(timer!=RT_NULL);if(state)

{

tim= (TIM_HandleTypeDef *)timer->parent.user_data;

tim_device= (struct stm32_hwtimer *)timer;/*time init*/

#if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)

if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance ==TIM11)#elif defined(SOC_SERIES_STM32L4)

if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance ==TIM17)#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0)

if (0)#endif{

#ifndef SOC_SERIES_STM32F0

prescaler_value= (uint32_t)(HAL_RCC_GetPCLK2Freq() * 2 / 10000) - 1;#endif}else{

prescaler_value= (uint32_t)(HAL_RCC_GetPCLK1Freq() * 2 / 10000) - 1;

}

tim->Init.Period = 10000 - 1;

tim->Init.Prescaler =prescaler_value;

tim->Init.ClockDivision =TIM_CLOCKDIVISION_DIV1;if (timer->info->cntmode ==HWTIMER_CNTMODE_UP)

{

tim->Init.CounterMode =TIM_COUNTERMODE_UP;

}else{

tim->Init.CounterMode =TIM_COUNTERMODE_DOWN;

}

tim->Init.RepetitionCounter = 0;#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0)tim->Init.AutoReloadPreload =TIM_AUTORELOAD_PRELOAD_DISABLE;#endif

if (HAL_TIM_Base_Init(tim) !=HAL_OK)

{

LOG_E("%s init failed", tim_device->name);return;

}else{/*set the TIMx priority*/HAL_NVIC_SetPriority(tim_device->tim_irqn, 3, 0);/*enable the TIMx global Interrupt*/HAL_NVIC_EnableIRQ(tim_device->tim_irqn);/*clear update flag*/__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);/*enable update request source*/__HAL_TIM_URS_ENABLE(tim);

LOG_D("%s init success", tim_device->name);

}

}

}

我们发现之前设置的配置并没有使用,而是直接默认设置成频率10K,周期1s的定时器;

可根据情况后面用control修改,或注释掉 tim->Init. 的几条赋值语句,使用 user_data 传递过来的默认配置;

同时 stm32f4xx_hal_msp.c 中的TIM硬件初始化,也仅仅只是打开TIM外设时钟,所有锁CubeMX中只要使能对应TIM即可,无需配置;

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef*htim_base)

{if(htim_base->Instance==TIM3)

{/*USER CODE BEGIN TIM3_MspInit 0*/

/*USER CODE END TIM3_MspInit 0*/

/*Peripheral clock enable*/__HAL_RCC_TIM3_CLK_ENABLE();/*USER CODE BEGIN TIM3_MspInit 1*/

/*USER CODE END TIM3_MspInit 1*/}else if(htim_base->Instance==TIM4)

{/*USER CODE BEGIN TIM4_MspInit 0*/

/*USER CODE END TIM4_MspInit 0*/

/*Peripheral clock enable*/__HAL_RCC_TIM4_CLK_ENABLE();/*USER CODE BEGIN TIM4_MspInit 1*/

/*USER CODE END TIM4_MspInit 1*/}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值