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

51822的Timer/Counter结构如下图所示

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

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

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

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

Main.c

#include "nrf51.h"
#include "nrf_gpio.h"

//定义自己板子上的LED灯
#define LED  22

int 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);
    }
}

nrf51822裸机教程-硬件timer的更多相关文章

  1. nrf51822裸机教程-PWM

    先简单介绍一下PWM的原理. 原理很简单. 假设COUNTER是个从0开始递增的计数器.  我们设置两个值 counter0 和counter1 在 COUNTER 计数到counter0的值时候翻转 ...

  2. nrf51822裸机教程-IIC

    关于IIC总线的核心有以下几点: :时钟线高电平期间必须保持数据线不变. :时钟线低电平期间可以改变数据. :时钟线和数据线上都要接上拉电阻,以使总线不工作时,两根线的电平都处于高电平状态. :每个传 ...

  3. nrf51822裸机教程-UART

    art硬件模块通常都有内置的硬件接收buff,比如51822的硬件uart模块图如下 因为通常接收到uart数据时都会做一些处理.比如保存到数据,或者对数据做一些判断之类的. 如果uart的波特率设置 ...

  4. nrf51822裸机教程-RTC

    RTC0被协议栈使用了.所以在跑蓝牙程序的情况下.RTC0不能使用. RTC相关寄存器如下: EVTEN,EVTENSET,EVTENCLR. 这三个寄存器用来设置是否使能某个事件.(TICK,OVR ...

  5. nrf51822裸机教程-PPI

    Programmable Peripheral Interconnect即可编程外设互联 系统,该模块是51822 提供的一个特性. 目的是为了让51822 的外围模块可以不通过处理器而自动相互作用. ...

  6. nrf51822裸机教程-GPIOTE

    GPIO通常都会具有中断功能,上一讲的GPIO中并没有涉及到中断的相关寄存器. 51822将GPIO的中断相关做成了一个单独的模块GPIOTE,这个模块不仅提供了GPIO的中断功能,同时提供了 通过t ...

  7. nrf51822裸机教程-SPI(主)

    关于SPI总线的介绍这里就不细说了,网上有很多介绍SPI总线时序的. SPI总线的本质就是一个环形总线结构,在时钟驱动下两个双向移位寄存器进行数据交换. 所以SPI总线的特色就是:传输一字节数据的同时 ...

  8. nrf51822裸机教程-GPIO

    首先看看一下相关的寄存器说明 Out寄存器 输出设置寄存器 每个比特按顺序对应每个引脚,bit0对应的就是 引脚0 该寄存器用来设置 引脚作为输出的时候的 输出电平为高还是低. 与输出设置相关的 还有 ...

  9. 迅为4412开发板Linux驱动教程/硬件知识及原理图的使用

    视频教程下载地址:http://pan.baidu.com/s/1pJwxUfL 嵌入式研发流程介绍 • PCB研发流程介绍 – 方案,原理图(网表) – layoutproject师(gerber文 ...

随机推荐

  1. 针对mysql中分表批量添加字段

    项目中有用到这种类似的分表,如果要添加一个字段的话,该怎么办呢? dba表示弄 一个脚本批量处理就行了,卧槽,这我哪会啊,于是硬着头皮又继续问dba,dba给一个脚本,一看是这样的. #!/bin/b ...

  2. POJ1511 Invitation Cards(多源单汇最短路)

    边取反,从汇点跑单源最短路即可. #include<cstdio> #include<cstring> #include<queue> #include<al ...

  3. Week,Month, Year 日期区间辅助类

    我们在做一些业务系统的时候,经常会用到一些获取时间段的情况.比如要统计某一周.某月.某年 这样一些时间区间内的一些业务数据.这时候我们就需要获取当前时间段内的一些起止日期.这里分享一个通用的日期辅助类 ...

  4. BZOJ3682 : Phorni

    后缀平衡树+线段树. $O(1)$比较大小的标号法真是强大. #include<cstdio> #include<cmath> #define N 300010 #define ...

  5. 生成跨语言的类型声明和接口绑定的工具(Djinni )

    Djinni 是一个用来生成跨语言的类型声明和接口绑定的工具,主要用于 C++ 和 Java 以及 Objective-C 间的互通. 示例接口定义文件: # Multi-line comments ...

  6. pygame系列_原创百度随心听音乐播放器_完整版

    程序名:PyMusic 解释:pygame+music 之前发布了自己写的小程序:百度随心听音乐播放器的一些效果图 你可以去到这里再次看看效果: pygame系列_百度随心听_完美的UI设计 这个程序 ...

  7. JAVA操作COOKIE

    JAVA操作COOKIE 1.设置Cookie Cookie cookie = new Cookie("key", "value"); cookie.setMa ...

  8. 关于SparkMLlib的基础数据结构 Spark-MLlib-Basics

    此部分主要关于MLlib的基础数据结构 1.本地向量 MLlib的本地向量主要分为两种,DenseVector和SparseVector,顾名思义,前者是用来保存稠密向量,后者是用来保存稀疏向量,其创 ...

  9. 在vs2013中配置openGL(绝对可靠 !)

    首先要下载glut.h glut32.dll glut32.lib.(这个在glut-3.7.6-bin的包里面,可以直接下载 ) 然后: glut.h:放到 D:\vs2013\VC\include ...

  10. jQuery.qrcode.js客户端生成二维码,支持中文并且可以生成LOGO

    描述: jquery.qrcode.js 是一个能够在客户端生成矩阵二维码QRCode 的jquery插件 ,使用它可以很方便的在页面上生成二维条码.此插件是能够独立使用的,体积也比较         ...