LPC804开发(4.ctimer使用)

1.前言

昨天晚上画完板子,还剩点时间就再翻了翻手册,大致清楚了时钟树的运行,顺带搞清楚了定时的使用,那就出一份教程吧。

如果各位在此之前没有接触过LPC单片机,还是建议先把程序直接贴进自己的项目,稍微改改先把功能实现了,定时器能动起来再说,因为LPC的定时器和其他单片机还是有很大不同的。

2.图形化配置时钟树

在开始前有些东西要先讲一下,首先是如何打开图形化配置时钟树,我们在项目资源管理器的右上角有一个绿色X的按钮,点击一下就会生成工程对应的mex文件,这个就是图形化配置文件。第一次使用时点击按钮我们就会进入图形配置界面,然后工程会自动生成一个mex文件,后续如果还想再修改配置就可以双击mex文件进入

然后我们就会进入下图的这个界面,这是管脚配置界面,大家有需要可以自行配置。

我们将右手的界面向下滑,找到一个像pwm波的图标,点击进去就是时钟树

然后我们就会进入如图的界面

如果各位直接创建的新工程,芯片的主频设置的是18Mhz

我们双击最左边fro_osc框进行主频修改

我们将芯片主频设定为最高(30Mhz)

设置完成后点击页面顶端的更新源代码

我们可以大致了解到哪些更改了,哪些没有改动,没有问题后点击确定完成设置。

退回到程序开发界面后点击编译就可以了。

我们这次使用的ctimer挂在这条时钟树下面

 可以看到其中有一个2分频,因此我们的ctimer的默认频率是15Mhz

3.初始化

首先说一下在804芯片里只有一个ctimer0,还是有点蛋疼的,再加上一个systick就两个传统意义上的定时器,有些情况下还是不够用的,这点最开始选型的时候慎重一点,有复杂的定时器控制的项目上建议用其他芯片。

 ctimer0初始化代码如下,这部分需要重点说说。

ctimer_config_t config;

CTIMER_GetDefaultConfig(&config);

CTIMER_Init(CTIMER0, &config);

/* Configuration 0 */
matchConfig0.enableCounterReset = true;
matchConfig0.enableCounterStop  = false;
matchConfig0.matchValue         = CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000;
matchConfig0.outControl         = kCTIMER_Output_NoAction;
matchConfig0.outPinInitState    = false;
matchConfig0.enableInterrupt    = true;


CTIMER_RegisterCallBack(CTIMER0, &ctimer_callback_table[0], kCTIMER_MultipleCallback);
CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_0, &matchConfig0);
CTIMER_StartTimer(CTIMER0);

首先,第一行是获取默认配置,函数原型如下。

这里默认配置下,设定是的模式是定时器模式,输入模式0,这两个没啥好说的,一般也不会需要改,之后prescale是分频系数的设置,默认是没有的,那么此时我们的频率就是15Mhz,这里如果大家需要其他频率就要改了,但是不建议直接在库里面改。我们可以在主函数里像下图这样改,我这里就不动了。

完成之后就可以将配置信息放到ctimer里面就是后面一句CTIMER_Init(CTIMER0, &config);

之后就是设置匹配

我们看到设置,其他内容相信大家可以看得懂我就不过多介绍了,大家根据需要来设置,一般不用动。这里的配置主要改的是匹配值就是第三行,这里的匹配值也STM32内所说重装值,这里就涉及到我们中断时间了。刚刚我们说到定时器的时钟频率是15Mhz。那么如果我们的匹配值是1,那么我们单次进中断的时间就是1/15000000 s。我们这里的匹配值是15000,这样一来进中断的时间就是1/15000000*15000=1ms
 

这里匹配是啥意思?LPC的定时器挺别致的,它没有中断,用的是回调函数,这个回调函数是更高级语言的一种用法,大家可以自行上网搜索,我也不是很了解,就不献丑了。其效果和中断差不多,就是没有中断优先级。

下一步就是设置回调函数了,但在此之前我们要先准备三个东西,如下图所示。从上到下依次是(1)函数声明(2)回调函数表(3)回调函数本体。一会我们初始化的时候要用到。

这里第二个ctimer_callback_t ctimer_callback_table[]就是回调函数表,我们在里面填写的内容就是回调函数名称。

等这些都写完后我们就可以继续初始化了,下图就是定时器回调函数的配置

这个函数原型如下

第一个参数是指定哪个定时器,这里都是ctimer0,第二个参数是回调函数表的地址,第三个是回调函数的个数(单个或多个)。这里要说一下建议回调函数表里的顺序按照0,1,2这样排,因为当有多个回调函数的时候,程序会按照表里的顺序依次和匹配上。这里先将一个回调函数的情况吧,一会再将多个回调函数。

等这些都初始化完毕,我们就可以把设置的参数给ctimer了

而初始化的最后一句话就是开启定时器

 4.多重回调

因为芯片里只有一个定时器,那么我们怎么才能拓展定时器时间呢?

这里NXP芯片有一点好,那就是可以设置多个匹配数。这里我借用STM32的手册上一幅图来解释

在STM32里面定时器是只有一个重装值的,那么当计数器的值与设定值匹配时就会触发中断,但是在804里面ctimer最多支持4个匹配值,那么我们就可以,触发多个计数器溢出。我先把程序放在这具体解释我打算回头再写一篇文章来说。

void init_ctimer(void)
{
	ctimer_config_t config;

	CTIMER_GetDefaultConfig(&config);

	CTIMER_Init(CTIMER0, &config);

	/* Configuration 0 */
	matchConfig0.enableCounterReset = true;
	matchConfig0.enableCounterStop  = false;
	matchConfig0.matchValue         = CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000;
	matchConfig0.outControl         = kCTIMER_Output_NoAction;
	matchConfig0.outPinInitState    = false;
	matchConfig0.enableInterrupt    = true;

	/* Configuration 1 */
	matchConfig1.enableCounterReset = false;
	matchConfig1.enableCounterStop  = false;
	matchConfig1.matchValue         = 0;
	matchConfig1.outControl         = kCTIMER_Output_NoAction;
	matchConfig1.outPinInitState    = false;
	matchConfig1.enableInterrupt    = true;

	CTIMER_RegisterCallBack(CTIMER0, &ctimer_callback_table[0], kCTIMER_MultipleCallback);
	CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_0, &matchConfig0);
	CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_1, &matchConfig1);
	CTIMER_StartTimer(CTIMER0);
}

5.程序

我这里初始化了两个端口(13,22),在两个回调函数里让他们翻转,大家可以先下载程序,测试下效果。

#include "fsl_ctimer.h"
void ctimer_match0_callback(uint32_t flags);
void ctimer_match1_callback(uint32_t flags);

/* Array of function pointers for callback for each channel */
ctimer_callback_t ctimer_callback_table[] = {
    ctimer_match0_callback, ctimer_match1_callback, NULL, NULL, NULL, NULL, NULL, NULL};

/* Match Configuration for Channel 0 */
static ctimer_match_config_t matchConfig0;
/* Match Configuration for Channel 1 */
static ctimer_match_config_t matchConfig1;


void ctimer_match0_callback(uint32_t flags)
{
	GPIO_PortToggle(GPIO,0,1<<22);
	matchConfig1.matchValue=0;
	CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_1, &matchConfig1);
}

void ctimer_match1_callback(uint32_t flags)
{
	LEDTOL;
	matchConfig1.matchValue+=CLOCK_GetFreq(kCLOCK_CoreSysClk) / 2000;
	CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_1, &matchConfig1);
}


void init_ctimer(void)
{
	ctimer_config_t config;

	CTIMER_GetDefaultConfig(&config);

	CTIMER_Init(CTIMER0, &config);

	/* Configuration 0 */
	matchConfig0.enableCounterReset = true;
	matchConfig0.enableCounterStop  = false;
	matchConfig0.matchValue         = CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000;
	matchConfig0.outControl         = kCTIMER_Output_NoAction;
	matchConfig0.outPinInitState    = false;
	matchConfig0.enableInterrupt    = true;

	/* Configuration 1 */
	matchConfig1.enableCounterReset = false;
	matchConfig1.enableCounterStop  = false;
	matchConfig1.matchValue         = 0;
	matchConfig1.outControl         = kCTIMER_Output_NoAction;
	matchConfig1.outPinInitState    = false;
	matchConfig1.enableInterrupt    = true;

	CTIMER_RegisterCallBack(CTIMER0, &ctimer_callback_table[0], kCTIMER_MultipleCallback);
	CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_0, &matchConfig0);
	CTIMER_SetupMatch(CTIMER0, kCTIMER_Match_1, &matchConfig1);
	CTIMER_StartTimer(CTIMER0);
}

int main(void)
{

    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

    init_ctimer();

	GPIO_PortInit(GPIO, 0);
	CLOCK_EnableClock(kCLOCK_Gpio0);

	gpio_pin_config_t LED_RED_config = {
		.pinDirection = kGPIO_DigitalOutput,
		.outputLogic = 0U,
	};
	GPIO_PinInit(GPIO, 0, 13, &LED_RED_config);
	GPIO_PinInit(GPIO, 0, 22, &LED_RED_config);

    while (1)
    {
    }
}

 对于初学者来说可以先修改下图的这个参数,这里除1000是1ms,官方除2是1s。大家可以直接改这个参数来进行定时器实际的设置。

 6.实际效果

7.结语

总的来说,LPC系列的定时器还是很特殊的,用过那么多单片机很少是NXP这个思路,最开始我学LPC55S69,第一次接触到回调函数这个问题也是非常懵逼的,如果各位也有这个困扰,建议大家先把回调函数视作中断,等慢慢熟悉了再去深入了解。还是那句话,有问题评论区见,我会尽量解答,那么我们下篇文章见。

相关推荐

  1. Codeforces Round 806 (Div. 4)

    2024-01-29 11:00:04       21 阅读
  2. 【XR806开发板试用】xr806 RTC实验

    2024-01-29 11:00:04       19 阅读
  3. Linux中的时间戳mtime,ctimectime

    2024-01-29 11:00:04       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-29 11:00:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-29 11:00:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-29 11:00:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-29 11:00:04       20 阅读

热门阅读

  1. Linux 链接 GitHub 出现 Connection timed out

    2024-01-29 11:00:04       42 阅读
  2. 第十四章认识Ajax(五)

    2024-01-29 11:00:04       34 阅读
  3. 正则表达式在前端中的使用

    2024-01-29 11:00:04       37 阅读
  4. C++从零开始的打怪升级之路(day24)

    2024-01-29 11:00:04       36 阅读
  5. COMM394 Coding Literacy for Managers

    2024-01-29 11:00:04       30 阅读
  6. docker入门 问题一

    2024-01-29 11:00:04       39 阅读
  7. 状态管理与导航守卫

    2024-01-29 11:00:04       33 阅读
  8. Ubuntu系统桌面卡死,解决办法

    2024-01-29 11:00:04       36 阅读
  9. 计算机视觉(CV)技术的优势和挑战

    2024-01-29 11:00:04       32 阅读
  10. 【漏洞复现】金蝶云星空-AppDesigner-反序列化-rce

    2024-01-29 11:00:04       36 阅读