您好,目前我在使用CC2640R2F读取传感器数据。传感器数据由于没有起始位,这导致我只能通过两个上升沿之间的脉冲间隔来判断数据是否为同一包数据。但是由于要使用低功耗设计,这就导致我无法使用定时器来实现这个功能。目前我的方案是使用RTC来进行计时,从而能够正确读取传感器的数据。我在使用过程中遇到如下问题:
将断点打在if(ClkNum >= 28){}代码里面的ClkNum = 0位置,程序是进不去的,一直进if(edgeTimingCurrectValue > 0x1000){}这个函数。进一步调试,将断点打在if(edgeTimingCurrectValue > 0x1000)处,edgeTimingCurrectValue的值很小,但是如果将断点打在if(edgeTimingCurrectValue > 0x1000)()函数里面的 ClkNum = 0处,edgeTimingCurrectValue值又会很大。请问是怎么回事?下面是中断处理函数的部分代码,具体整个文件的配置代码和传感器协议见文件0525.gpio.c8357.量表通讯口协议.doc
CLKedgeTimingCurrCLKedgeTimingCurrectValue[1] = AONRTCCaptureValueCh1Get();
AONRTCEventClear(AON_RTC_CH1);
if(CLKedgeTimingCurrectValue[1] >= CLKedgeTimingCurrectValue[0])
edgeTimingCurrectValue = CLKedgeTimingCurrectValue[1] – CLKedgeTimingCurrectValue[0];
else
edgeTimingCurrectValue = CLKedgeTimingCurrectValue[1] +(0xFFFFFFFF – CLKedgeTimingCurrectValue[0]);
if(edgeTimingCurrectValue > 0x1000){ //大约62ms
ClkNum = 0;
uiDataTemp = 0;
}
CLKedgeTimingCurrectValue[0] – CLKedgeTimingCurrectValue[1];
ClkNum += 1;
if(ClkNum >= 28){
ClkNum = 0;
…..
}
Kevin Qiu1:
两个脉冲的最小间隔是多少,太小中断可能来不及处理
梦与远方:
回复 Kevin Qiu1:
从我上面发的协议来看,脉冲间隔在150~200us之间
Kevin Qiu1:
回复 梦与远方:
这个间隔用GPIO连续中断来捕获可能不行,最好还是用定时器来做
YiKai Chen:
回复 梦与远方:
可以使用 Clock_getTicks,但最小單位是10us,可以參考一下 sunmaysky.blogspot.com/…/how-to-detect-buttont-hold-in-cc26x2.html
梦与远方:
回复 YiKai Chen:
您好,您发的链接我这边无法打开
梦与远方:
回复 Kevin Qiu1:
定时器的话就没办法使MCU处于睡眠模式了,这样功耗会很大
YiKai Chen:
回复 梦与远方:
為什麼用Clock_getTicks 就没办法使MCU处于睡眠模式?不会的吧
梦与远方:
回复 YiKai Chen:
定时器是没办法使MCU处于睡眠模式的,至于Clock_getTicks()我还没有试,今天试一下
YiKai Chen:
回复 梦与远方:
所提供的方式是在GPI interrupt callback function裡面去調用Clock_getTicks 取得us的時間去處理,我認為MCU沒有不能处于睡眠模式的問題
梦与远方:
回复 YiKai Chen:
您好,我昨天尝试使用了Clock_getTicks函数来获取两个上升沿之间的间隔,在实际测试中发现仍旧无法准确的获取一包完整的数据(即完整读取28个上升沿时的脉冲数据),经常是读取几个上升沿脉冲之后就会出现两个上升沿时间间隔过大(计算是112ms左右,这恰好是两包数据间的间隔)而重新计算。所以我怀疑仍旧存在丢包的现象,我把代码发上来,您帮我看一下Clock_getTicks函数是否使用正确。
//头文件#include "BLESDKCommDef.h"#include "BleSDKManager.h"#include "gpio.h"#include "systemclock.h"
//GPIO宏定义#define DATA_GPIO IOID_26#define CLK_GPIO IOID_27
//GPIO配置管理PIN_Config GPIOConfig[] = { DATA_GPIO | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLDOWN, CLK_GPIO | PIN_GPIO_OUTPUT_DIS| PIN_INPUT_EN | PIN_PULLUP, PIN_TERMINATE};
//变量参数static PIN_State GPIOPinState;static PIN_Handle hGPIOPinsHandle;
static u8 ClkNum = 0; //CLK中断计数器
//内部调用函数static void CLK_GPIOIsrCallback(PIN_Handle handle, PIN_Id pinId);
//——————————————————————————//【函 数】 void GPIO_Init(void)//【概 述】 位移计GPIO及RTC时钟初始化//【入口参数】 无//【返回参数】 无//【说 明】 无//——————————————————————————void GPIO_Init(void){ BleSDKManagerInfo_t err; // 状态返回 err = DriverIOOpen(&hGPIOPinsHandle,&GPIOPinState,(const PIN_Config *)GPIOConfig); //创建IO设置 if(err != MANAGER_INFO_REQUEST_IO_SUCCESS){ //一个IO组打开成功 现在这个组里没有IO return; } err = DriverIORegisterIntCallBack(&hGPIOPinsHandle,CLK_GPIOIsrCallback); //注册一个io中断回调函数 if(err != MANAGER_INFO_CONTROL_IO_SUCCESS){ return; } err = DriverIOSetConfig(&hGPIOPinsHandle,PIN_BM_IRQ,CLK_GPIO | PIN_IRQ_POSEDGE);//配置CLK_GPIO的中断功能 if(err != MANAGER_INFO_CONTROL_IO_SUCCESS){ return; }// //#ifdef POWER_SAVING //如果系统开启了省电功能 则还需要为此io配置唤醒功能(即使其具备从睡眠状态通过中断唤醒mcu的功能)// err = DriverIOSetConfig(&hGPIOPinsHandle,PINCC26XX_BM_WAKEUP,CLK_GPIO | PINCC26XX_WAKEUP_NEGEDGE);//配置CLK_GPIO的中断唤醒功能// // if(err != MANAGER_INFO_CONTROL_IO_SUCCESS){ // return;// }//#endif }
//——————————————————————————//【函 数】 CLK_GPIOIsrCallback(PIN_Handle handle, PIN_Id pinId)//【概 述】 io中断回调函数//【入口参数】 无//【返回参数】 无//【说 明】 无//——————————————————————————static void CLK_GPIOIsrCallback(PIN_Handle handle, PIN_Id pinId){ static u32 uiDataTemp = 0; static u32 CLKedgeTimingCurrectValue[2] = {0}; u32 edgeTimingCurrectValue = 0; g_uiShutDownClk = 0; //shutdown模式计时器清零 if(ClkNum == 0){ CLKedgeTimingCurrectValue[0] = Clock_getTicks(); //Clock_getTicks将以10us为单位返回计数值 } else{ CLKedgeTimingCurrectValue[1] = Clock_getTicks(); //Clock_getTicks将以10us为单位返回计数值 if(CLKedgeTimingCurrectValue[1] > CLKedgeTimingCurrectValue[0]){ edgeTimingCurrectValue = CLKedgeTimingCurrectValue[1] – CLKedgeTimingCurrectValue[0]; } else{ edgeTimingCurrectValue = CLKedgeTimingCurrectValue[1] + (0xFFFFFFFF – CLKedgeTimingCurrectValue[0]); } if(edgeTimingCurrectValue > 10000){ ClkNum = 0; uiDataTemp = 0; } CLKedgeTimingCurrectValue[0] = CLKedgeTimingCurrectValue[1]; }
if(1 == DriverIOGetInputValue(DATA_GPIO)) uiDataTemp = uiDataTemp + (1 << ClkNum); ClkNum += 1; if(ClkNum >= 28){ //数据读取完成 ClkNum = 0; g_uiData = uiDataTemp; g_cDataFinsh = 1; }}