当前位置:网站首页>【RT-Thread】nxp rt10xx 设备驱动框架之--hwtimer搭建和使用
【RT-Thread】nxp rt10xx 设备驱动框架之--hwtimer搭建和使用
2022-07-03 17:07:00 【L_17】
hwtimer 为我们常用的硬件定时器,下面将使用gpt定时器实现设备驱动搭建
开发前准备
- 硬件平台:nxp rt10xx单片机
- IDE: Keil
1.Kconfig 修改和menuconfig配置
在Env环境menuconfig中 RT-Thread Components->Device Drivers 设备驱动默认为n,所以需要开启
先在Kconfig中添加如下语句,然后在Env环境menuconfig中 Hardware Drivers Config->On-Chip Peripheral Drivers,然后根据需要选择指定HWTIMER,笔者用的外设GPT1即:HWTIMER1
2.工程添加HWTIMER驱动框架和BSP驱动接口
设备驱动框架:hwtimer.c BSP接口:drv_hwtimer.c fsl_gpt.c
3.添加或修改drv_hwtimer.c
笔者查阅了文件,该驱动比较完善,笔者改动了时钟源,使用osc 24M做为时钟源,另外把一些多余配置删除掉了
struct rt_hwtimer_ops
{
void (*init)(struct rt_hwtimer_device *timer, rt_uint32_t state);
rt_err_t (*start)(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
void (*stop)(struct rt_hwtimer_device *timer);
rt_uint32_t (*count_get)(struct rt_hwtimer_device *timer);
rt_err_t (*control)(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args);
};
static const struct rt_hwtimer_ops imxrt_hwtimer_ops =
{
.init = imxrt_hwtimer_init,
.start = imxrt_hwtimer_start,
.stop = imxrt_hwtimer_stop,
.count_get = imxrt_hwtimer_count_get,
.control = imxrt_hwtimer_control,
};
int rt_hw_hwtimer_init(void)
{
int ret = RT_EOK;
#ifdef BSP_USING_HWTIMER1
GPT_timer1.info = &imxrt_hwtimer_info;
GPT_timer1.ops = &imxrt_hwtimer_ops;
ret = rt_device_hwtimer_register(&GPT_timer1, "gpt1", GPT1);
if (ret != RT_EOK)
{
LOG_E("gpt1 register failed\n");
}
#endif
#ifdef BSP_USING_HWTIMER2
GPT_timer2.info = &imxrt_hwtimer_info;
GPT_timer2.ops = &imxrt_hwtimer_ops;
ret = rt_device_hwtimer_register(&GPT_timer2, "gpt2", GPT2);
if (ret != RT_EOK)
{
LOG_E("gpt1 register failed\n");
}
#endif
return ret;
}
时钟源选择和中断优先级是笔者改掉的地方,这里全部贴上代码
#define GPT_CLK_FREQ CLOCK_GetFreq(kCLOCK_OscClk)
#define SAI_ISR_PRE (14U)
static void NVIC_Configuration(void)
{
#ifdef BSP_USING_HWTIMER1
NVIC_SetPriority(GPT1_IRQn,SAI_ISR_PRE);
EnableIRQ(GPT1_IRQn);
#endif
#ifdef BSP_USING_HWTIMER2
NVIC_SetPriority(GPT2_IRQn,SAI_ISR_PRE);
EnableIRQ(GPT2_IRQn);
#endif
}
static rt_err_t imxrt_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
{
rt_err_t err = RT_EOK;
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
switch (cmd)
{
case HWTIMER_CTRL_FREQ_SET:
{
uint32_t clk;
uint32_t pre;
clk = GPT_CLK_FREQ;
pre = clk / *((uint32_t *)args);
GPT_SetClockDivider(hwtimer_dev, pre);
}
break;
default:
err = -RT_ENOSYS;
break;
}
return err;
}
static rt_uint32_t imxrt_hwtimer_count_get(rt_hwtimer_t *timer)
{
rt_uint32_t CurrentTimer_Count;
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
CurrentTimer_Count = GPT_GetCurrentTimerCount(hwtimer_dev);
return CurrentTimer_Count;
}
static void imxrt_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
{
GPT_Type *hwtimer_dev;
gpt_config_t gptConfig;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
if (state == 1)
{
/* Initialize GPT module by default config */
GPT_GetDefaultConfig(&gptConfig);
gptConfig.clockSource = kGPT_ClockSource_Osc; //选择外设时钟
gptConfig.divider = 24; //设置分频系数 24M/24 = 1M
GPT_Init(hwtimer_dev, &gptConfig);
}
}
static rt_err_t imxrt_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
{
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
hwtimer_dev->CR |= (mode != HWTIMER_MODE_PERIOD) ? GPT_CR_FRR_MASK : 0U;
GPT_SetOutputCompareValue(hwtimer_dev, kGPT_OutputCompare_Channel1, cnt);
GPT_EnableInterrupts(hwtimer_dev, kGPT_OutputCompare1InterruptEnable);
NVIC_Configuration();
GPT_StartTimer(hwtimer_dev);
return RT_EOK;
}
static void imxrt_hwtimer_stop(rt_hwtimer_t *timer)
{
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
GPT_StopTimer(hwtimer_dev);
}
4.搭建应用层demo
开启定时器,查阅时间精度是否ok
/**************************************************START OF FILE*****************************************************/
/*------------------------------------------------------------------------------------------------------------------ Includes */
#include <rtthread.h>
#include <rtdevice.h>
/*------------------------------------------------------------------------------------------------------------------ Macros */
#define HWTIMER_DEVICE_NAME "gpt1" /* 硬件定时器设备名称 */
/*------------------------------------------------------------------------------------------------------------------ Variables */
/*------------------------------------------------------------------------------------------------------------------ Functions */
/* 定时器超时回调函数 */
static rt_err_t timer_callback(rt_device_t dev, rt_size_t size)
{
rt_kprintf("this is hwtimer timeout callback fucntion!\n");
rt_kprintf("tick is :%d !\n", rt_tick_get());
return 0;
}
int xAPP_HwTimerInit(void)
{
rt_err_t ret = RT_EOK;
rt_hwtimerval_t timeout_s; /* 定时器超时值 */
rt_device_t hw_dev = RT_NULL; /* 定时器设备句柄 */
rt_hwtimer_mode_t mode; /* 定时器模式 */
rt_uint32_t freq = 100000; /* 计数频率 */
hw_dev = rt_device_find(HWTIMER_DEVICE_NAME);
if (hw_dev == RT_NULL)
{
rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEVICE_NAME);
return RT_ERROR;
}
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
if (ret != RT_EOK)
{
rt_kprintf("open %s device failed!\n", HWTIMER_DEVICE_NAME);
return ret;
}
/* 设置超时回调函数 */
rt_device_set_rx_indicate(hw_dev, timer_callback);
/* 设置计数频率(若未设置该项,默认为1Mhz 或 支持的最小计数频率) */
rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);
mode = HWTIMER_MODE_PERIOD;
ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
if (ret != RT_EOK)
{
rt_kprintf("set mode failed! ret is :%d\n", ret);
return ret;
}
/* 设置定时器超时值为5s并启动定时器 */
timeout_s.sec = 5; /* 秒 */
timeout_s.usec = 0; /* 微秒 */
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
{
rt_kprintf("set timeout value failed\n");
return RT_ERROR;
}
/* 延时3200ms */
rt_thread_mdelay(3200);
rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s));
rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec);
return ret;
}
/****************************************************END OF FILE*****************************************************/
补充一下,gpt换算方式:
时钟源为24M,分频系数 0xEF + 1 = 240,可得时钟为:100000Hz,COMP:0x7A120 即:500000
500000/100000=5s 所以5s中断一次
边栏推荐
- 13mnnimo5-4 German standard steel plate 13MnNiMo54 boiler steel 13MnNiMo54 chemical properties
- LeetCode 1658. Minimum operand to reduce x to 0
- One brush 145 force deduction hot question-2 sum of two numbers (m)
- 手把手带你入门 API 开发
- One brush 149 force deduction hot question-10 regular expression matching (H)
- Summary of three methods of PHP looping through arrays list (), each (), and while
- 匯編實例解析--實模式下屏幕顯示
- What is the difference between 14Cr1MoR container plate and 14Cr1MoR (H)? Chemical composition and performance analysis of 14Cr1MoR
- MySQL Basics
- Squid service startup script
猜你喜欢
The largest matrix (H) in a brush 143 monotone stack 84 histogram
CC2530 common registers for timer 1
Web crawler knowledge day03
UCORE overview
美团一面:为什么线程崩溃崩溃不会导致 JVM 崩溃
Depth first search of graph
CC2530 common registers for crystal oscillator settings
C language modifies files by line
Build your own website (23)
Fast Ethernet and Gigabit Ethernet: what's the difference?
随机推荐
C language string practice
深入理解 SQL 中的 Grouping Sets 语句
Svn full backup svnadmin hotcopy
汇编实例解析--实模式下屏幕显示
C language string inversion
Kotlin学习快速入门(7)——扩展的妙用
C语言字符串反转
人生还在迷茫?也许这些订阅号里有你需要的答案!
Apache服务挂起Asynchronous AcceptEx failed.
What is your income level in the country?
Unity notes unityxr simple to use
Prepare for the golden three silver four, 100+ software test interview questions (function / interface / Automation) interview questions. win victory the moment one raises one 's standard
匯編實例解析--實模式下屏幕顯示
SVN如何查看修改的文件记录
CC2530 common registers for port initialization
Why is WPA3 security of enterprise business so important?
How to allow remote connection to MySQL server on Linux system?
Hands on in-depth learning notes (XIV) 3.7 Simple implementation of softmax regression
Bcvp developer community 2022 exclusive peripheral first bullet
Thread pool: the most common and error prone component of business code