注:函数库见前文。
一般的延时可以采用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 (mBroadcastTimeoutFlag>0) {
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[132];
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 (mBroadcastTimeoutFlag>0) {
mBroadcastTimeoutFlag = 0;
//发消息
sendMsg();
//toggle LED2
modSetLedState(1,2);
}
//RF收到消息
if (mRfRxPktSize > 1) {
//按照第2字节内容控制LED1
if (mRfRxBuffer[0] == 0x01) { //LED0 control command
modSetLedState(0, mRfRxBuffer[1]);
}
//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[10];
int16 iValue;
pTxData[0] = 0x02; //cmd: sensor report
//get temperature
iValue = modAdcSampleSingle(ADC_REF_1_25_V, ADC_7_BIT, ADC_TEMP_SENS);
pTxData[1] = (iValue>>8)&0x07F;
//get voltage
iValue = modAdcSampleSingle(ADC_REF_1_25_V, ADC_7_BIT, ADC_VDD_3);
pTxData[2] = (iValue>>8)&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[vSize]=vRssi>>8;
mRfRxBuffer[vSize+1]=vRssi&0x0FF;
//设置mRfRxPktSize作为标志
mRfRxPktSize = vSize+2;
return 0;
}
/**
* timeout Callback
*/
int8 myTimeoutCallbackFunction(uint8 vCallbackIndex) {
mBroadcastTimeoutFlag = 1; //indicate main loop to send broadcast
return 0;
};i++)>
sunce_464022046 2013-8-31 15:09