您的位置:首页 > 其它

nrf51822学习之PPI裸板程序之对于定时器0计数方式的疑惑

2016-05-21 07:54 507 查看
总体功能:

有两种方式来使能或者关掉PPI频道:通过定时器2比较事件来触发定时器0

开始计数。通过

定时器1比较事件来触发定时器0

停止计数。整个过程不需要
CPU
参与,和中断触发类型有点相

似。

定时器初始化:

定时器0的设置比较简单了设置为普通的计数模式,依次计数。BITMODE设置为

24bit.定时器1和定时器2

的设置类似,区别就是为了错开比较事件的时间,也就是通过PPI设置的定时器0

的打开计数和关闭时间,因此
CC
寄存器的预设值有区别:

void
timer0_init(void)

{

NRF_TIMER0->MODE = TIMER_MODE_MODE_Counter; //设置定时器位计数模式.

NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_24Bit; // 24-bit模式.

}

定时器2的CC

寄存器预设值设为了
0x7FFF,通过之前所讲的定时器设置,这个比较触发的时间大概是1s,定时器1的CC

寄存器预设值设为了
0xFFFF,这个比较触发的时间大概是2s,因此定时器0的开始任务与结束任务时间大概是1S,因为定时器1和2对本文没有多大帮助,故这里不列出。

下来看看ppi的配置:

void ppi_init(void)

{

// 通道 0 的 EFP 和 TEP 设置

//把定时器 1 的比较事件作为事件,定时器 0 的停止作为任务

//通过定时器 1 比较事件来触发定时器 0 停止

NRF_PPI->CH[0].EEP = (uint32_t)(&NRF_TIMER1->EVENTS_COMPARE[0]);

NRF_PPI->CH[0].TEP = (uint32_t)(&NRF_TIMER0->TASKS_STOP);

// 通道 1 的 EFP 和 TEP 设置

//把定时器 2 的比较事件作为事件,定时器 0 的开始作为任务

//通过定时器 2 比较事件来触发定时器 0 开始

NRF_PPI->CH[1].EEP = (uint32_t)(&NRF_TIMER2->EVENTS_COMPARE[0]);

NRF_PPI->CH[1].TEP = (uint32_t)(&NRF_TIMER0->TASKS_START);

// 使能 PPI 通道 1 和通道 0

NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos) |

(PPI_CHEN_CH1_Enabled << PPI_CHEN_CH1_Pos);

}

PPI实际上提供了一种直连的机制,这种机制可以把一个外设发生的事件(event)来触发另一个外设的任务(task)
,整个过程不需要
CPU
进行参与。因此一个任务(task)通过PPI通道和事件(event)进行互连。PPI通道由两个终点寄存器组成,分别为:

事件终点寄存器(EEP)和任务终点寄存器

(TEP)。

可以把外设任务(task)通过任务寄存器的地址与任务终点寄存器(TEP)进行赋值。同理,也可以把外设事件通过事件(event)寄存器的地址与事件终点寄存器(EEP)进行赋值


我的疑惑如下:

定时器初始化为技术模式,那么触发技术的应该是count任务,在手册里也是这样说明的:



In
counter mode, the TIMER's internal Counter register is incremented by one each time the COUNT task is triggered, that is, the timer frequency
and the prescaler are not utilized in counter mode. Similarly, the COUNT task has no effect in Timer mode.

也就是应该触发COUNT
task任务,而本例程里触发的确实start和stop任务,为什么呢?

本例程是这样设置ppi的:

NRF_PPI->CH[0].TEP
= (uint32_t)(&NRF_TIMER0->TASKS_STOP);

NRF_PPI->CH[1].TEP
= (uint32_t)(&NRF_TIMER0->TASKS_START);

而且本例程实验还成功了,我更加的疑惑!!!!????

这里上传青风写的例程说明文档:
http://download.csdn.net/detail/chengdong1314/9527113
例程:实验9:ppi的使用
http://download.csdn.net/detail/chengdong1314/9527773
经过和淘宝客服讨论,我发现了一个我犯了一个致命的错误,原例程中的PPI的功能只是打开TIM0,而不是增加TIM0的计数器,我一直误解为PPI是增加计数器,而忽略了主函数while循环中的至关重要的一句话:NRF_TIMER0->TASKS_COUNT = 1;

原例程的while循环如下:



机制是这样的:

定时器1比较事件 ->PPI ->打开计数器0

主循环NRF_TIMER0->TASKS_COUNT = 1; -》计数器0加1

定时器2比较事件 ->PPI ->关闭计数器0

为了验证我的想法,我这样改主函数,把while循环里的延时关掉,将可以看到,我们的等将是一直闪烁的,起码不是本来的现象,修改后的主函数如下:



下载程序后可以看所有的灯都是亮的,最少有两个灯同时在亮,说明在一次TIM1比较事件和TIM2比较事件之间,原来的程序做到了while循环只是循环了一次。

这时候我就很纳闷,TIM1比较事件和TIM2比较事件之间的时间是1s,应该计数器会增加10次才对,所以可以猜测这里的波形一定是不规则的,LED管脚不行如下:



波形确实是不规则的。

如果去掉延时那么波形就应该是规则的,波形如下:



波形是规则的,这幅图从宏观上来看应该是有变换的,其中部分是while循环的周期,短周期形成的长周期就是TIM1比较事件和TIM2比较事件之间的时间,没有短周期的就是TIM1未溢出的时间,如下:



波形分析完毕!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: