首页 技术 正文
技术 2022年11月18日
0 收藏 755 点赞 2,417 浏览 2283 个字

该讲介绍51822的Timer/Counter模块工作在timer模式下(定时器模式,还可以工作为计数器模式) 如何操作

51822的Timer/Counter结构如下图所示
nrf51822裸机教程-硬件timer

Timer模块从PCLK16M/PCLK1M 处获得时钟源,然后经分频后得到的时钟作为timer模块的时钟 ( 上图Ftimer)。当timer模块选择为timer模式时,Counter会在Ftimer的每个tick 计数一次当计数值与cc[n](n为0,1,2,3)寄存器中的值相等时就会触发对应的Compare[n]事件,如果我们设置了compare[n]事件产生时触发中断(关于事件与中断看前一篇GPIOTE),那么就可以在counter计数到与 cc[n]寄存器中的值相等时触发中断,也就能实现我们需要的定时器功能了

所以根据上面的模块结构图和说明想要实现定时器,我们需要做如下几个步骤:

1    选择Timer/Countermo模块为timer模式,并设置bitmode(8,16,,2,32位)

2    通过设置分屏来设置timer的时钟

3    设置cc[n](后面我们的例子选择使用cc0),来设置计数到多少产生compares[n]事件(当计数值技术到cc[n]的值时对应产生compare[n]事件)

4    设置compare事件产生时触发中断。

5     通过NVIC函数启动MCU 的timer中断

6    最后启动timer就可以了。

通过查看 数据手册看以看到

1

设置模式 通过 寄存器MODE 设置 0为timer模式 1为counter模式。

2

设置timer的时钟  通过以下公式设置

fTIMER = 16 MHz / (2^PRESCALER)

这里可能有个疑问,上面的图解中不是有两个时钟源 16M和1M吗,怎么这个公式只能通过16M来分频获得timer时钟。 这是因为51822为了降低功耗内部自动 做了时钟源切换,当Ftimer <= 1M时会自动切换成1M时钟源

举两个例子解释下

如果需要timer的时钟为 4M,那么4 = Ftimer = 16M/2^2

即我们只需设置分频寄存器 PRESCALER为2,就能或得4M的时钟给timer了

当需要timer的时钟为500Khz时,根据公式 我们设置PRESCALER寄存器的值为5, 500kHZ = Ftimer = 16M/2^5。 这个时候Ftimer<=1M,所以51882内部会自动切换成1M的时钟源然后分频后获得500K的timer时钟。 不过这些都是51822自动切换的了

也就是说设置timer时钟只要根据上面的公式设置就可以了,时钟源的切换是51822自动完成的

3

设置cc[n]寄存器的值,定时就是通过这个值来设置的。 下面的例子会做一个一秒定时亮灯/灭灯的程序, 我们设置timer时钟为1M,即分频寄存器PRESCALER写值为4。 1M的时钟源则一个tick为1us,所以要定时1s,则cc[0]的值我们填入 1000000就行了。(这里也可以选择cc[1],cc[2],或cc[3],只要下面对应的compare事件产生中断设置成对应的就可以了)

4

通过寄存器INTENSET 第16bit位设置compare[0]事件产生时触发中断。

5

通过NVIC的功能函数NVIC_EnableIRQ 来使能MCU的Timer0中断

6

最后通过Timer/Counter模块的 START 启动timer。 

 

注意:这里裸板例子代码我们用的是timer0,如果跑了协议栈就不能用timer0,可以使用timer1和timer2

新建一个工程选择自己的芯片型号

nrf51822裸机教程-硬件timer

下面的代码我们不使用nrf提供的库函数,而按照上面说明的顺序直接设置寄存器来使用timer0,因为没用别的功能。所以下面勾选一个core和startup。因为用到了点灯所以勾选一下nrf_drivers下的Nrf_gpio

nrf51822裸机教程-硬件timer

下面是源代码,为了更好理解模块,都是直接操作寄存器

Main.c

#include "nrf51.h"#include "nrf_gpio.h"//定义自己板子上的LED灯#define LED  22int main(){    nrf_gpio_cfg_output(LED);    //NRF_TIMER0定义在nrf51.h中,该指针指向timer0中的寄存器组    NRF_TIMER0->PRESCALER  = ;     //2^4   16分频得到1M timer时钟    NRF_TIMER0->MODE = ;           //timer模式    NRF_TIMER0->BITMODE = ;        // 设置32bit    NRF_TIMER0->CC[] = ;    //一个tick是1us,1000000代表1s    NRF_TIMER0->INTENSET = <<;//设置compare[0]事件产生时触发中断    //该设置使timer模块中的conter计数到cc[0]值时会自动清零,以带到重//新计数的目的    NRF_TIMER0->SHORTS = ;    //启动timer模块    NRF_TIMER0->TASKS_START = ;    //开启MCU的timer0中断    NVIC_SetPriority(TIMER0_IRQn, );    NVIC_ClearPendingIRQ(TIMER0_IRQn);    NVIC_EnableIRQ(TIMER0_IRQn);    );    ;}//中断函数中翻转灯状态void TIMER0_IRQHandler(){    ] == ){       NRF_TIMER0->EVENTS_COMPARE[] = ;     //清除事件,不然会导致一                                              //直产生中断       nrf_gpio_pin_toggle(LED);    }}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,580
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918