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是10ms,官方除2是1s。大家可以直接改这个参数来进行定时器实际的设置。

 6.实际效果

 

7.结语

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/653112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“拔叔”的新片又杀疯了!

近&#xff0c;“拔叔”麦斯米科尔斯的新片登上口碑榜。 该片曾入围去年威尼斯金狮奖&#xff0c;上映后颇受好评&#xff0c;目前豆瓣评分8.2分。 将代表丹麦角逐2024年奥斯卡最佳外语片&#xff0c;目前已入15强。 作为“丹麦最性感的男人”&#xff0c;拔叔的实力不容小觑。…

Logistics 逻辑回归概念

1. sigmoid函数 逻辑回归算法的拟合函数&#xff0c;叫做sigmoid函数&#xff1a; 函数图像如下&#xff08;百度图片搜到的图&#xff09;&#xff1a; sigmoid函数是一个s形曲线&#xff0c;就像是阶跃函数的温和版&#xff0c;阶跃函数在0和1之间是突然的起跳&#xff0c;…

std::for_each

std::for_each 是 C STL 中的标准函数之一&#xff0c;用于对指定的容器或序列中的元素执行指定的操作。该函数的头文件为 <algorithm>&#xff0c;定义在 namespace std 中&#xff0c;因此需要包含该头文件才能使用该函数。 std::for_each 函数是 C STL 中自 C98 就开…

【JavaSE篇】——类和对象

目录 &#x1f393;类定义和使用 &#x1f393;简单认识类 &#x1f6a9;类的定义格式 ❗注意事项 &#x1f393;类的实例化 &#x1f6a9;什么是实例化 &#x1f6a9;类和对象的说明 &#x1f393;this引用 &#x1f6a9;为什么要有this引用 &#x1f6a9;什么是thi…

【JavaScript 基础入门】02 JavaScrip 详细介绍

JavaScrip 详细介绍 目录 JavaScrip 详细介绍1. JavaScript 是什么2. JavaScript的作用3. HTML/CSS/JS 的关系4. 浏览器执行 JS 简介5. JavaScript 的组成6. JavaScript 的特点 1. JavaScript 是什么 JavaScript&#xff0c;通常缩写为 JS&#xff0c;是一种高级的&#xff0c;…

分布式技术浅见之复制

分布式技术浅见之复制 前言一、何为复制&#xff1f;1.1 主从复制和无主从复制1.2 同步复制与异步复制1.3 来点栗子1.3.1 Redis1.3.2 Mysql1.3.3 Mongo 二、复制是如何实现的&#xff1f;2.1 复制的过程2.2 来点栗子2.2.1 Redis2.2.2 Mysql2.2.3 Mongo 2.2 复制的实现方式2.4 举…

OpenHarmony—不支持解构赋值

规则&#xff1a;arkts-no-destruct-assignment 级别&#xff1a;错误 ArkTS不支持解构赋值。可使用其他替代方法&#xff0c;例如&#xff0c;使用临时变量。 TypeScript let [one, two] [1, 2]; // 此处需要分号 [one, two] [two, one];let head, tail [head, ...tail]…

MySQL十部曲之六:数据操作语句(DML)

文章目录 前言语法约定DELETEINSERTSELECT查询列表SELECT 选项子句FROMWHEREORDER BYGROUP BYHAVINGWINDOWLIMITFOR SELECT ... INTO连接查询CROSS JOIN和INNER JOINON和USINGOUTER JOINNATURE JOIN 子查询标量子查询使用子查询进行比较带有ANY、IN或SOME的子查询带有ALL的子查…

DETR解读,将Transformer带入CV

论文出处 [2005.12872] End-to-End Object Detection with Transformers (arxiv.org) 一个前置知识 匈牙利算法&#xff1a;来源于二部图匹配&#xff0c;计算最小或最大匹配 算法操作&#xff1a;在n*n的矩阵中 减去行列最小值&#xff0c;更新矩阵&#xff08;此时行或者…

搜维尔科技:【简报】元宇宙数字人赛道,优秀作品赏析《大福太郎》

这次采用亮眼的浅粉做为发色&#xff0c;为了贴合她小警察的身分 给了她一顶特制的警帽&#xff0c;上面有大福的荧光蓝叶片作为标 志&#xff0c;而在配件及裙子上也加入了许多科技元素的小巧思。 学校&#xff1a; 朝阳科技大学&#xff08;台湾&#xff09; 选手&#xff…

消息中间件之RocketMQ(二)

RocketMQ支持的消息类型 了解之前&#xff0c;首先要熟悉RocketMQ中的组件架构设计 1.顺序消息 将同一个订单(即具有相同的orderId)的消息按状态先后顺序消费的&#xff0c;所以消息生产者调用send方法发送时需要传入MessageQueueSelector接口的,实现类&#xff0c;将order…

【GitHub项目推荐--开源PDF 工具】【转载】

12 年历史的 PDF 工具开源了 最近在整理 PDF 的时候&#xff0c;有一些需求普通的 PDF 编辑器没办法满足&#xff0c;比如 PDF 批量合并、编辑等。 于是&#xff0c;我就去 GitHub 上看一看有没有现成的轮子&#xff0c;发现了这个 PDF 神器「PDF 补丁丁」&#xff0c;让人惊…

Vue+OpenLayers7入门到实战:快速搭建Vue+OpenLayers7地图脚手架项目。从零开始构建Vue项目并整合OpenLayers7.5.2

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7 前言 本章针对Vue初学者,对Vue不熟悉,甚至还不会Vue的入门学生读者。 本章会详细讲解从NodeJS环境到npm环境的各个步骤,再到使用vue-cli脚手架快速生成项目,以及添加OpenLayers7地图库依赖,编写简单的xyz高德地图显示…

RuoYi-Vue前后端分离后台开发框架运行详细教程

一、官网下载代码 RuoYi-Vue是一款基于SpringBootVue的前后端分离极速后台开发框架。 若依官网&#xff1a;http://ruoyi.vip演示地址&#xff1a;http://vue.ruoyi.vip代码下载&#xff1a;https://gitee.com/y_project/RuoYi-Vue 下载之后解压&#xff0c;ruoyi-ui是前端代…

opencv学习二值分析

内容来源于《opencv4应用开发入门、进阶与工程化实践》 二值分析&#xff1a; 常见的二值化方法&#xff1a; 基于全局阈值&#xff08;threshold&#xff09;得到的二值图像&#xff1b;基于自适应阈值&#xff08;adaptiveThreshold&#xff09;得到的二值图像&#xff1…

JavaScript高级:构造函数

1 引言 构造函数是一种特殊的函数&#xff0c;主要用来初始化对象&#xff1b;常规的 {...} 语法允许创建一个对象&#xff0c;但是通过构造函数可以快速创建多个类似的对象 2 约定 1. 命名以大写字母开头&#xff1b; 2. 它们只能由 “new” 操作符来执行 <script>//…

【C++】filesystem

文章目录 1. 基本配置1.1. VS2019修改C标准1.2. filesystem的引入 2. 日常使用2.1. 认识2.2. 控制台输入路径并对路径进行基本操作 <filesystem>是C 17标准引入的标准库&#xff0c;主要用于处理文件系统的目录和文件操作&#xff0c;接下来总结该库的基本配置和日常使用…

BIGVGAN: A UNIVERSAL NEURAL VOCODER WITHLARGE-SCALE TRAINING——TTS论文阅读

笔记地址&#xff1a;https://flowus.cn/share/a16a61b3-fcd0-4e0e-be5a-22ba641c6792 【FlowUs 息流】Bigvgan 论文地址&#xff1a; BigVGAN: A Universal Neural Vocoder with Large-Scale Training Abstract 背景&#xff1a; 最近基于生成对抗网络&#xff08;GAN&am…

【第十八课】DFS:深度优先搜索( acwing-843 n-皇后问题 / c++代码 )

目录 错误写法(可跳 DFS-剪枝 代码 思路二&#xff1a; 原始解法 错误写法(可跳 看到这道题&#xff0c;我想这不还是n个数的全排列的问题么?也就是把数字变成了字符&#xff0c;一些输出格式上的变化。于是就在原有代码上修改一下应该就行。 我的思路就还是path存有可能…

跨站脚本攻击漏洞概述-XSS

什么是跨站脚本攻击 跨站脚本( Cross-site Scripting ) 攻击&#xff0c;攻击者通过网站注入点注入客户端可执行解析的payload(脚本代码)&#xff0c;当用户访问网页时&#xff0c;恶意payload自动加载并执行&#xff0c;以达到攻击者目的(窃取cookie、恶意传播、钓鱼欺骗等)。…