Part Number:CC2640R2FOther Parts Discussed in Thread: CC2640, SYSBIOS
void timerCallback1A(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {//int i;//i = GPTimerCC26XX_getValue(hTimer0A);j = GPTimerCC26XX_getValue(hTimer0A);GPTimerCC26XX_setLoadValue(hTimer0A, 0);printf("%d\n",j);GPIO_toggle(Board_GPIO_LED0);GPIO_toggle(Board_GPIO_LED1); } void timerCallback0A_cap(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {//static int j;if(j == 0xFFFF-1){j = 0;}j++;//i = GPTimerCC26XX_getFreeRunValue(hTimer0A);//printf("%d\n",i); } void *mainCAPTURE(void *arg0) {/* Open LED pins */ledPinHandle = PIN_open(&ledPinState, pinTable);if (ledPinHandle == NULL){while(1);}GPTimerCC26XX_Params params0A;GPTimerCC26XX_Params_init(¶ms0A);params0A.width= GPT_CONFIG_16BIT;params0A.mode= GPT_MODE_EDGE_COUNT;params0A.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;hTimer0A = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER0A, ¶ms0A);if(hTimer0A == NULL){while(1);}GPTimerCC26XX_registerInterrupt(hTimer0A, timerCallback0A_cap, GPT_INT_CAPTURE);GPTimerCC26XX_PinMux pinMux = GPTimerCC26XX_getPinMux(hTimer0A);PINCC26XX_setMux(ledPinHandle, IOID_0, pinMux);GPTimerCC26XX_setCaptureEdge(hTimer0A, GPTimerCC26XX_NEG_EDGE);//GPTimerCC26XX_setLoadValue(hTimer0A, 0xFFFF);//GPTimerCC26XX_setMatchValue(hTimer0A, 1);LED_Init();GPTimerCC26XX_Params params1A;GPTimerCC26XX_Params_init(¶ms1A);params1A.width= GPT_CONFIG_32BIT;params1A.mode= GPT_MODE_PERIODIC;params1A.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;hTimer1A = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER1A, ¶ms1A);if(hTimer1A == NULL){while(1);}GPTimerCC26XX_registerInterrupt(hTimer1A, timerCallback1A, GPT_INT_TIMEOUT);GPTimerCC26XX_setLoadValue(hTimer1A, 0x2DC6C00);GPTimerCC26XX_start(hTimer1A);GPTimerCC26XX_start(hTimer0A);while(1){Task_sleep(BIOS_WAIT_FOREVER);} }
这是我用于测试频率的2个中断处理函数以及主函数。
采用Timer0A用于采集下降沿并进行j++,采用Timer1A用于定时1S最后通过 j = GPTimerCC26XX_getValue(hTimer0A);。
最终打印数据:19955
39914
59871(测试20KHz的方波)
这几个值都相差19950左右的值,但并不准确。
且还存在以下几个问题:
①.在timerCallback1A()函数中,我想采用 GPTimerCC26XX_setLoadValue(hTimer0A, 0);将Timer0A中计数器的值进行归0,但并没有成功,我翻看了GPTimerCC26XX.h文件,最终只找到了setLoadValue与setMatchValue函数,setMatchValue应该不行,但setLoadValue也无法满足我的需求,我想知道哪个函数能将Timer0A中的COUNT清0。
②.因为STM32可以使用下降沿中断计数,并且打开定时器进行单独计时,当在一次下降沿中断中检测到例如if(TIM5->CCR1 > 1000000)(这里采用了84分频,所以1M代表1S)之后便直接将中断里用于计数的参数输出并清零,所以最开始我想在CC2640R2F中使用一个定时器将测频程序完成,但最后并没有成功。想请问是否能使用一个定时器完成测频操作,如果有的话请指出方法。谢谢!
③.在params0A.mode = GPT_MODE_EDGE_COUNT;, GPTimerCC26XX_registerInterrupt(hTimer0A, timerCallback0A_cap, GPT_INT_CAPTURE);配置下的32位定时器并不能设置params0A.width = GPT_CONFIG_32BIT;一旦设置为32位,程序将无法完成初始化。这点我不是很明白。
我现在还是个学生,接触CC2640没几天,可能提出的一些问题会太过简单,但我确实不明白,这两天我一直在调定时器想达到测频目的,但一直没实现。
还请工程师解答一下,谢谢了!!
zhi qiang liu:
数据手册中一句话Timer 0 is a general-purpose timer module(GPTM),which provides two 16-bits timers. The GPTM can be configured to operate as a single 32-bit timer, dual 16-bit timers or as a PWM module.
似乎可以解释我的问题③.只有用于定时器的时候才能作为32位。
,
Kevin Qiu1:
GPTimer 时钟取决于 MCU 系统时钟,如果需要非常高精度的输出,应使用外部 HF 晶振:
#include <ti/sysbios/family/arm/cc26xx/Power.h>
#include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
Power_setDependency (XOSC_HF);GPTimerCC26XX.h中没有直接对计数器清零的API,一般不直接对寄存器进行操作,选择相应的模式
2&3.
可以查看这里类似的问题https://www.ti2k.com/wp-content/uploads/2022/03/nput-square-wave-clock-source-of-10000hz-i-want-to-use-the-gpt_mode_edge_count-mode-in-the-gptimer-of-cc2640r2f-to-record-the-number-of-rising-edges-per-unit-time-of-my-square-wave-but-i-can-t-get-it-
,
zhi qiang liu:
Kevin你好,
TIRTOS默认使用的是内部高速时钟吗?
还有就是你给的这个函数关于XOSC_HF的宏定义,我的头文件检索不到,能告诉我它的具体值吗。
且关于头文件路径,我使用的simplelink SDK5_10中的TIRTOS例程只能#include <ti/drivers/Power.h>,#include <ti/drivers/power/PowerCC26XX.h>这样包含才能正常编译,你给的路径我用不了,使用如上的路径能正常打开在Power,h中的Power_setDependency 函数,不知这样是否有错误。
最后一个问题,因为我的设计需要满足尽量低的功耗,是否RTOS已将低功耗封装好,我只需要调用 Task_sleep(BIOS_WAIT_FOREVER);等函数即可完成对低功耗的操作,因为我担心仅这一个函数是否有能力将功耗降到足够低。我见论坛许多工程师都是说RTOS在无任务时都会自动进入低功耗,所以想跟你确认一下。
谢谢!
,
zhi qiang liu:
之前对GPTIMER不太熟悉,所以阅读了CC2640的技术手册,对GPTIMER有了一定理解,且现在EDGETIME模式采两个下降沿之间的周期反推频率没有任何问题。但是使用EDGECOUNT_MATCH模式对频率进行直接采样时,误差还是非常大。例如测试20KHZ的方波信号,第一次得到的值还算准确:19950,但是随后全都变成了17000左右,非常不准确。我的测试方法是 GPTimerCC26XX_setLoadValue(hTimer0A, 0x0b);GPTimerCC26XX_setMatchValue(hTimer0A, 0x01);当TIME0A采集到10个下降沿时,就中断进行计数+1,最后在TIME1A中进行1S的定时,最后取出计数*10,得到频率值。但是不够准确。
我最后还想问个问题,为何EDGECOUNT_MATCH无法从GPTimerCC26XX_getValue,GPTimerCC26XX_getFreeRunValue中取出位于0x0b到0x01中的计数值,我每次在1S定时完后取值都是0x0b,我想取出该值加到计数*10上提高精度,可是两个函数都取不出来。