将本页加入收藏夹

EFR32MG21(Series 2)定时器作为频率信号发生器

EFR32MG21(Series 2)定时器作为频率信号发生器

 

关键词:

ZigBee, EmberZnet, TIMER, Frequency, 频率,定时器,MG21, EFR32, ONE-SHOT, PWM

 

在我司项目研发中,偶然发现EFR32MG21(本文称为MG21)这款ZigBee芯片的性能和配置都特别好,而我们项目刚好用到定时器来进行电机控制,灯光调色等,于是认真的去了解这个芯片定时器的功能,发现有30个多工作模式可以用,经过仔细了解,对于我们会使用到的工作方式作一个说明。也欢迎同行进行开发交流。由于这个定时器工作方式实在太多,我们仅仅会将用到的功能单独成文。这里先介绍的是定时器作为信号发生器。

 

MG21的定时器功能特别强大和复杂,也可以用来给其他设备提供时钟,为了降低设备对时钟晶振和芯片的需要,也可以直接使用它给其他设备提供时钟。一个稍为复杂的设备可能会用到多个时钟,如果对时钟的要求不是十分严格,则可参考本法。

 

频率范围

首先要说明的是时钟的频率是有限制的,而且不会十分的精准,我们在使用zigbee协议之后,MG21的高频时钟也就是38.4MHZ的晶振,本文的时钟信号发生器也会是在这个时钟基础上进行分频所得。

 

MG21定时器频率计算公式为:

 

 

                                   [ ftimer = fclk / (2^(perscale+1) x (top + 1)) ]

 

       因此在不改变分频数prescale的条件下,可以配置的频率为 292.96Hz~19.2Mhz。每个定时器还可以通过对时钟进行最高1024次分频,从面得到频率0.2861Hz的信号,这相当于一个周期的时间为3.495秒的信号。这里是用于时钟信号,因此可以认为理论都是50%占空比的方波,但实际上会略有偏差,实测也有可能会是52%。

 

测试工具和方法

       经过理论上的计算之后,我们可以对开发板进行编码测试,测试时可以使用示波器,也可以使用梦源制作的USB逻辑分析仪(型号DSLogic Plus)。用它可以进行测试信号,然后在电脑软件上可以直接显示出信号的数字波型。 它的最大采样速率为400MHz,所以也满足了这次的测量的要求。

 

为了能够测试结果是否可行,我还们还要让EFR32MG21输出信号,使用一个开发板,在任何一个Zigbee工程当中,增加代码让他输出信号到指定的引脚,(注意避开协议栈默认会占用的引脚),将逻辑分析仪的表笔接到开发板对应引脚上,即可开始测量。开发板可以选择官方的SLWSTK6006A或者我们公司新一信息的NEWBIT-ZDK-2。以官方的为例,接线如下:

图2  逻辑分析与ZigBee开发板的连接方法

 

 

测量的结果

       下载程序并测量信号,所目标设置为1M时,得到的图3的波形。结果显示是1.01MHz, 计算其误差在1%。对寄存器进行修改,经过测试大致得到如下的规律:

 

表1

TOP值

0

1

10

100

65535

输出频率

19.05MHz

9.52Mhz

1.75Mhz

190.11KHz

292.93Hz

 

上表反映的测量的读数,与理论值并没有完全相符,但差别非常小,对于时钟精准度要求不那么高的话,可以直接使用。

 

 

图3 定时器输出设置为1MHz的输出波形

 

 

测试的代码

       定时器的代码不多,而且也不需要Simplicity studio v4进行配置,为方便大家的测试和使用,我们将所用的代码开源于https://gitee.com/newbitcode/efr32mg_peri。部分代码如下:

 

// timer configuration

void nb_timer_init(void)

{

 uint32_t timerFreq = 0;

  // Initialize the timer

  TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;

  // Configure TIMER0 Compare/Capture for output compare

  TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;

 

  timerInit.prescale = timerPrescale1;

  timerInit.enable = false;

  timerCCInit.mode = timerCCModeCompare;

  timerCCInit.cmoa = timerOutputActionToggle;

 

  // configure, but do not start timer

  TIMER_Init(TIMER0, &timerInit);

 

  // Route Timer0 CC0 output to PC3

  GPIO->TIMERROUTE[0].ROUTEEN  = GPIO_TIMER_ROUTEEN_CC0PEN;

 

  GPIO->TIMERROUTE[0].CC0ROUTE = (TIMER0_GPIO_PORT << _GPIO_TIMER_CC0ROUTE_PORT_SHIFT)

                                                                                     | (TIMER0_GPIO_PIN << _GPIO_TIMER_CC0ROUTE_PIN_SHIFT);

 

  TIMER_InitCC(TIMER0, 0, &timerCCInit);

 

  // Set Top value

  // Note each overflow event constitutes 1/2 the signal period

  timerFreq = CMU_ClockFreqGet(cmuClock_TIMER0)/(timerInit.prescale + 1);

  int topValue =  timerFreq / (2*OUT_FREQ) - 1;

  TIMER_TopSet (TIMER0, topValue);

 

  /* Start the timer */

  TIMER_Enable(TIMER0, true);

}

 

有关Simplicity Studio软件安装请进页面,搭建EFR32 ZigBee开发环境>>  

。在开发和测试的过程中,感谢世强元件的工程师给予的支持。

 

posted on 2019-11-15 09:40  Newbit  阅读(1769)  评论(0编辑  收藏  举报

< p> Copyright ©2015 Newbit