热度 13
2013-8-27 15:14
3333 次阅读|
1 个评论
注:函数库见前文。 一般的延时可以采用modDelay()方法实现。 但是在一些场合,比如需要精确定时的任务,或者需要主程序不断调用某些函数(不允许阻塞延时)的时候,可以采用modTimer.h中提供的定时任务机制。 modTimer机制支持多定时任务,目前实现支持6个定时任务。 它利用了CC2530的Timer3定时器来计算时间,因此延时比较精确。 该机制以回调方式执行用户的定时任务函数。 程序初始化时,先调用modTimerInit()函数进行初始化(只需调用一次)。 当需要设置定时任务时,调用modTimerAddTimeoutCallback()提交定时任务,参数中指明延时多久,时间到时执行哪个函数,是否循环调用。 当时间到时,系统会自动调用用户指定的函数。 如果需要取消该任务,则调用modTimerRemoveTimeoutCallback()函数。 延时单位:毫秒。 modTimerAddTimeoutCallback()是非阻塞型的函数,也就是说,该函数完成设置后就返回,不用等到延时完成才返回。 当时间到时,用户定义的回调函数是在Timer3中断处理函数中调用,因此不能进行长时间的处理,应及时返回。 === 一个例子: 每5秒触发一次任务。定时回调函数只设置标志,任务在主程序中执行。 与定时任务相关的代码段包括: uint8 mBroadcastTimeoutIndex = 0; //定时任务句柄,取消任务时作为输入参数。 uint8 mBroadcastTimeoutFlag = 0; //定时回调函数和主循环之间的信号。 int8 myTimeoutCallbackFunction(uint8 vCallbackIndex); //定时任务回调函数 初始化: void init(){ ... //定时任务初始化 modTimerInit(); modTimerAddTimeoutCallback(5000, myTimeoutCallbackFunction, 1, mBroadcastTimeoutIndex); } 回调函数: /** * timeout Callback */ int8 myTimeoutCallbackFunction(uint8 vCallbackIndex) { mBroadcastTimeoutFlag = 1; //indicate main loop to send broadcast return 0; } 主循环: while (1) { //定时任务 if (mBroadcastTimeoutFlag0) { mBroadcastTimeoutFlag = 0; //发消息 sendMsg(); //toggle LED2 modSetLedState(1,2); } ... } /*+********************************************************************************** Filename: main.c Description: ZH_SimpleStack_2530.r51使用演示例程。 定时采集芯片温度和电压,发送给网关。 收到网关发送的消息时: * 根据第1字节控制LED0的亮灭,0: off, 1: on, 2: toggle * 将消息和RSSI回送给网关; 主要演示内容: * 通过2.5GHz射频发送接收消息; * A/D数据采集; * 定时任务机制; Modification: 2012.10.03 creation by Zheng Hui **********************************************************************************-*/ #include "modSys.h" #include "modHwExt.h" #include "modRf.h" #include "modAdc.h" #include "modTimer.h" /** * 配置参数 */ // 射频参数 #define RF_CHANNEL 25 #define PAN_ID 0x1111 #define TERMINAL_ADDR 0x0101 #define CONTROLLER_ADDR 0x0100 /** * 全局变量定义 */ uint8 mRfRxBuffer ; uint8 mRfRxPktSize = 0; uint8 mBroadcastTimeoutIndex = 0; uint8 mBroadcastTimeoutFlag = 0; /** * 函数声明 */ void init(); void sendMsg(); int8 myRxCallback(uint16 vSourceId, uint16 vDestId, uint8 vSize, uint8* vPacket, int16 vRssi); //RF Rx 回调函数 int8 myTimeoutCallbackFunction(uint8 vCallbackIndex); //定时任务回调函数 /** * 主函数 */ void main(void) { //init init(); //set LED1 on modSetLedState(0,1); while (1) { //定时任务 if (mBroadcastTimeoutFlag0) { mBroadcastTimeoutFlag = 0; //发消息 sendMsg(); //toggle LED2 modSetLedState(1,2); } //RF收到消息 if (mRfRxPktSize 1) { //按照第2字节内容控制LED1 if (mRfRxBuffer == 0x01) { //LED0 control command modSetLedState(0, mRfRxBuffer ); } //send it back //modRfSendPkt(CONTROLLER_ADDR, mRfRxPktSize,mRfRxBuffer); //toggle LED2 modSetLedState(1,2); // mRfRxPktSize=0; } } } /** * 初始化 */ void init(){ modMcuInit(); modLedInit(); //RF init modRfSetRxCallback(myRxCallback); //设置RF收到消息的回调函数 modRfInit(TERMINAL_ADDR, PAN_ID, RF_CHANNEL, TRUE, FALSE, NULL); //初始化节点ID、PAN_ID、信道,要求消息确认。 modRfStartRx(); //开始接收 //定时任务初始化 modTimerInit(); modTimerAddTimeoutCallback(5000, myTimeoutCallbackFunction, 1, mBroadcastTimeoutIndex); } /** * 发送数据 */ void sendMsg(){ uint8 pTxData ; int16 iValue; pTxData = 0x02; //cmd: sensor report //get temperature iValue = modAdcSampleSingle(ADC_REF_1_25_V, ADC_7_BIT, ADC_TEMP_SENS); pTxData = (iValue8)0x07F; //get voltage iValue = modAdcSampleSingle(ADC_REF_1_25_V, ADC_7_BIT, ADC_VDD_3); pTxData = (iValue8)0x07F; //send packet modRfSendPkt(CONTROLLER_ADDR,3,pTxData ); //发送两个字节payload的消息到CONTROLLER_ADDR } /** * 收到分组的处理 */ int8 myRxCallback(uint16 vSourceId, uint16 vDestId, uint8 vSize, uint8* vPacket, int16 vRssi){ uint8 i; //将消息复制到缓冲区 //保存消息 for (i=0;i mRfRxBuffer = vPacket ; } //保存接收信号强度 mRfRxBuffer =vRssi8; mRfRxBuffer =vRssi0x0FF; //设置mRfRxPktSize作为标志 mRfRxPktSize = vSize+2; return 0; } /** * timeout Callback */ int8 myTimeoutCallbackFunction(uint8 vCallbackIndex) { mBroadcastTimeoutFlag = 1; //indicate main loop to send broadcast return 0; };i++)