因为论文上需要,自己改编的程序,完全是按照自己的想法理解的,自己也知道存在很多问题。希望道友能够给与指点。所谓旁观者清。
/****************************************************************************
程序名称:1石油钻井平台监控系统_坐岗室_节点2_20090527_Coordinator
程序编写:唐爱明
编写日期:20090527
使用模块:Coordinator
使用协议:802.15.4
程序备注:管理6个Router
****************************************************************************/
/****************************************************************************/
/*** 头文件 ***/
/****************************************************************************/
#include <jendefs.h>//变量类型定义
#include <AppHardwareApi.h>//应用硬件API
#include <AppQueueApi.h>//应用对队列API
#include <mac_sap.h>//mac_sap
#include <mac_pib.h>//mac_pib
#include <string.h>//绑定
#include <AppApi.h>//应用API
#include "config.h"//网络参数
#include "serialq.h"//串口队列
#include "uart.h"//通用异步收发报机
#include "serial.h"//串口
#include "LedControl.h"//灯控
/****************************************************************************/
/*** 类定义 ***/
/****************************************************************************/
/* 协调器5状态*/
typedef enum
{
E_STATE_INIT,//初始化状态
E_STATE_START_ENERGY_SCAN,//开始能量扫描状态
E_STATE_ENERGY_SCANNING, //能量扫描中状态
E_STATE_START_COORDINATOR,//启动协调器状态
E_STATE_RUNNING_UART_APP//网络建立好状态
} teState;
typedef struct
{
uint32 u32ExtAddrLo;//节点地址低字节
uint32 u32ExtAddrHi;//节点地址高字节
uint16 u16ShortAddr;//节点短地址
} tsAssocNodes;
typedef struct
{
struct
{
tsAssocNodes asAssocNodes[MAX_UART_NODES];// 联网节点
uint8 u8AssociatedNodes;//已联网节点
} sNode;
struct
{
teState eState;
uint8 u8Channel; //通道
} sSystem;
} tsCoordData;
/****************************************************************************/
/*** 全局变量 ***/
/****************************************************************************/
PRIVATE tsCoordData sCoordData;//协调器数据变量转换
PRIVATE uint8 u8TxFrameHandle = 0;//发送帧数
PRIVATE uint8 u8RxFrameHandle = 0;//接受帧数
PRIVATE void *pvMac;//MAC
PRIVATE MAC_Pib_s *psPib;//PIB
/****************************************************************************/
/*** 函数声明 ***/
/****************************************************************************/
PRIVATE void vWUART_Init(void);//初始化
PRIVATE void vWUART_TxData(void);// 往Router发送数据
PRIVATE void vProcessEventQueues(void);//事件队列
PRIVATE void vStartCoordinator(void);//启动协调器,启动个域网
PRIVATE void vHandleNodeAssociation(MAC_MlmeDcfmInd_s *psMlmeInd);//节点联网
PRIVATE void vTickTimerISR(uint32 u32Device, uint32 u32ItemBitmap);//定时中断函数
PRIVATE void vStartEnergyScan(void);//开始能量扫描
PRIVATE void vHandleEnergyScanResponse(MAC_MlmeDcfmInd_s *psMlmeInd);//能量扫描响应
PRIVATE void vProcessIncomingMlme(MAC_MlmeDcfmInd_s *psMlmeInd);//管理实体
PRIVATE void vProcessIncomingData(MAC_McpsDcfmInd_s *psMcpsInd);//数据实体
PRIVATE void vProcessIncomingHwEvent(AppQApiHwInd_s *psAHI_Ind);//硬件事件
/****************************************************************************
* NAME: AppColdStart
* DESCRIPTION:
****************************************************************************/
PUBLIC void AppColdStart(void)
{
vWUART_Init();
while(1)
{
vProcessEventQueues();
switch (sCoordData.sSystem.eState)
{
case E_STATE_INIT://初始化状态
sCoordData.sSystem.u8Channel = CHANNEL_MIN;//协调器选用通道
sCoordData.sSystem.eState = E_STATE_START_ENERGY_SCAN;//进入启动能量扫描状态
break;
case E_STATE_START_ENERGY_SCAN://能量扫描
vStartEnergyScan();//启动能量扫描
sCoordData.sSystem.eState = E_STATE_ENERGY_SCANNING;//进入能量扫描中状态
break;
case E_STATE_ENERGY_SCANNING://正在扫描状态
break;
case E_STATE_START_COORDINATOR://启动协调器状态
vStartCoordinator();//启动协调器
sCoordData.sSystem.eState = E_STATE_RUNNING_UART_APP;//网络建立好状态
break;
case E_STATE_RUNNING_UART_APP://网络建立好状态
break;
}
}
}
/****************************************************************************
* NAME: AppWarmStart
* DESCRIPTION:
****************************************************************************/
PUBLIC void AppWarmStart(void)
{
AppColdStart();
}
/****************************************************************************
* NAME: vWUART_Init
* DESCRIPTION:
****************************************************************************/
PRIVATE void vWUART_Init(void)
{
vLedInitRfd();
vLedInitFfd();
vLedControl(0,0);
vLedControl(1,0);
sCoordData.sNode.u8AssociatedNodes = 0;
(void)u32AppQApiInit(NULL, NULL, NULL);//初始化应用队列
(void)u32AHI_Init();//初始化协议
pvMac = pvAppApiGetMacHandle();//设置MAC
psPib = MAC_psPibGetHandle(pvMac);//设置PIB
MAC_vPibSetPanId(pvMac, PAN_ID);
MAC_vPibSetShortAddr(pvMac, COORD_ADDR);
psPib->bAssociationPermit = 1;//允许节点联网
MAC_vPibSetRxOnWhenIdle(pvMac, 1, FALSE);//空闲模式下是否打开接收器,非常重要
vSerial_Init();//串口初始化
/* 初始化10ms定时器*/
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE);
vAHI_TickTimerWrite(0);
vAHI_TickTimerInit(vTickTimerISR);
vAHI_TickTimerInterval(TICK_PERIOD_COUNT);
vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_RESTART);
vAHI_TickTimerIntEnable(TRUE);
}
/****************************************************************************
* NAME: vProcessEventQueues
* DESCRIPTION:
****************************************************************************/
PRIVATE void vProcessEventQueues(void)
{
MAC_MlmeDcfmInd_s *psMlmeInd;
MAC_McpsDcfmInd_s *psMcpsInd;
AppQApiHwInd_s *psAHI_Ind;
do
{
psMlmeInd = psAppQApiReadMlmeInd();
if (psMlmeInd != NULL)
{
vProcessIncomingMlme(psMlmeInd);
vAppQApiReturnMlmeIndBuffer(psMlmeInd);
}
} while (psMlmeInd != NULL);
do
{
psMcpsInd = psAppQApiReadMcpsInd();
if (psMcpsInd != NULL)
{
vProcessIncomingData(psMcpsInd);
vAppQApiReturnMcpsIndBuffer(psMcpsInd);
}
} while (psMcpsInd != NULL);
do
{
psAHI_Ind = psAppQApiReadHwInd();
if (psAHI_Ind != NULL)
{
vProcessIncomingHwEvent(psAHI_Ind);
vAppQApiReturnHwIndBuffer(psAHI_Ind);
}
} while (psAHI_Ind != NULL);
}
/****************************************************************************
* NAME: vProcessIncomingMlme
* DESCRIPTION:
****************************************************************************/
PRIVATE void vProcessIncomingMlme(MAC_MlmeDcfmInd_s *psMlmeInd)
{
switch(psMlmeInd->u8Type)
{
case MAC_MLME_IND_ASSOCIATE://联网状态
if (sCoordData.sSystem.eState == E_STATE_RUNNING_UART_APP)//如果网络建立好
{
vHandleNodeAssociation(psMlmeInd);//节点联网
}
break;
case MAC_MLME_DCFM_SCAN://扫描状态
if (psMlmeInd->uParam.sDcfmScan.u8Status == MAC_ENUM_SUCCESS)//联网成功
{
if (psMlmeInd->uParam.sDcfmScan.u8ScanType == MAC_MLME_SCAN_TYPE_ENERGY_DETECT)//能量检测
{
if (sCoordData.sSystem.eState == E_STATE_ENERGY_SCANNING)//能量扫描中
{
vHandleEnergyScanResponse(psMlmeInd);//找出最安静的通道
sCoordData.sSystem.eState = E_STATE_START_COORDINATOR;//置协调器为启动协调器状态
}
}
}
break;
}
}
/****************************************************************************
* NAME: vProcessIncomingData
* DESCRIPTION:
****************************************************************************/
PRIVATE void vProcessIncomingData(MAC_McpsDcfmInd_s *psMcpsInd)
{
MAC_RxFrameData_s *psFrame;
MAC_Addr_s *psAddr;
uint16 u16NodeAddr;
uint8 i;
psFrame = &psMcpsInd->uParam.sIndData.sFrame;//数据帧
psAddr = &psFrame->sSrcAddr;//节点地址
if (psMcpsInd->u8Type == MAC_MCPS_IND_DATA)//如果是数据帧
{
u16NodeAddr = psAddr->uAddr.u16Short;//读取节点地址
//################################################################################
if (u16NodeAddr == sCoordData.sNode.asAssocNodes[0].u16ShortAddr )//如果来自节点1
{
if (psFrame->au8Sdu[0] == u8RxFrameHandle)//如果没有丢帧且有新帧
{
u8RxFrameHandle++;//帧数自增
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] > u8RxFrameHandle)//如果丢帧了
{
u8RxFrameHandle = psFrame->au8Sdu[0] + 1;//帧数修正
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] < u8RxFrameHandle)//如果是旧帧
{
}
}
//################################################################################
else if (u16NodeAddr == sCoordData.sNode.asAssocNodes[1].u16ShortAddr )//如果来自节点2
{
if (psFrame->au8Sdu[0] == u8RxFrameHandle)//如果没有丢帧且有新帧
{
u8RxFrameHandle++;//帧数自增
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] > u8RxFrameHandle)//如果丢帧了
{
u8RxFrameHandle = psFrame->au8Sdu[0] + 1;//帧数修正
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] < u8RxFrameHandle)//如果是旧帧
{
}
}
//################################################################################
else if (u16NodeAddr == sCoordData.sNode.asAssocNodes[2].u16ShortAddr )//如果来自节点3
{
if (psFrame->au8Sdu[0] == u8RxFrameHandle)//如果没有丢帧且有新帧
{
u8RxFrameHandle++;//帧数自增
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] > u8RxFrameHandle)//如果丢帧了
{
u8RxFrameHandle = psFrame->au8Sdu[0] + 1;//帧数修正
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] < u8RxFrameHandle)//如果是旧帧
{
}
}
//################################################################################
if (u16NodeAddr == sCoordData.sNode.asAssocNodes[3].u16ShortAddr )//如果来自节点4
{
if (psFrame->au8Sdu[0] == u8RxFrameHandle)//如果没有丢帧且有新帧
{
u8RxFrameHandle++;//帧数自增
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] > u8RxFrameHandle)//如果丢帧了
{
u8RxFrameHandle = psFrame->au8Sdu[0] + 1;//帧数修正
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] < u8RxFrameHandle)//如果是旧帧
{
}
}
//################################################################################
else if (u16NodeAddr == sCoordData.sNode.asAssocNodes[4].u16ShortAddr )//如果来自节点5
{
if (psFrame->au8Sdu[0] == u8RxFrameHandle)//如果没有丢帧且有新帧
{
u8RxFrameHandle++;//帧数自增
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] > u8RxFrameHandle)//如果丢帧了
{
u8RxFrameHandle = psFrame->au8Sdu[0] + 1;//帧数修正
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] < u8RxFrameHandle)//如果是旧帧
{
}
}
//################################################################################
else if (u16NodeAddr == sCoordData.sNode.asAssocNodes[5].u16ShortAddr )//如果来自节点6
{
if (psFrame->au8Sdu[0] == u8RxFrameHandle)//如果没有丢帧且有新帧
{
u8RxFrameHandle++;//帧数自增
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] > u8RxFrameHandle)//如果丢帧了
{
u8RxFrameHandle = psFrame->au8Sdu[0] + 1;//帧数修正
for (i = 1; i < psFrame->u8SduLength; i++)
{
vSerial_TxChar(psFrame->au8Sdu);//PC机显示数据
}
}
else if (psFrame->au8Sdu[0] < u8RxFrameHandle)//如果是旧帧
{
}
}
//###############################################################################
else
{
}
}
}
/****************************************************************************
* NAME: vProcessIncomingHwEvent
* DESCRIPTION:
****************************************************************************/
PRIVATE void vProcessIncomingHwEvent(AppQApiHwInd_s *psAHI_Ind)
{
if (psAHI_Ind->u32DeviceId == E_AHI_DEVICE_UART0)//如果是来自串口0的事件
{
if ((psAHI_Ind->u32ItemBitmap & 0x000000FF) == E_AHI_UART_INT_RXDATA)//如果接收到数据
{
vUART_RxCharISR((psAHI_Ind->u32ItemBitmap & 0x0000FF00) >> 8);//处理串口接收中断
}
else if (psAHI_Ind->u32ItemBitmap == E_AHI_UART_INT_TX)//如果发送数据
{
vUART_TxCharISR();//处理串口发送中断
}
}
}
/****************************************************************************
* NAME: vTickTimerISR
* DESCRIPTION:
****************************************************************************/
PRIVATE void vTickTimerISR(uint32 u32Device, uint32 u32ItemBitmap)
{
static uint8 u8ToggleCount;
/* 闪烁LED1以示成活 */
if (u8ToggleCount++ & 0x40)//??????????
{
vLedControl(0,1);//开LED1
}
else
{
vLedControl(0,0);//关LED1
}
if (sCoordData.sSystem.eState == E_STATE_RUNNING_UART_APP)//如果协调器进入网络建好状态
{
vWUART_TxData();
}
}
/****************************************************************************
* NAME: vHandleNodeAssociation
* DESCRIPTION:
****************************************************************************/
PRIVATE void vHandleNodeAssociation(MAC_MlmeDcfmInd_s *psMlmeInd)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
uint16 u16ShortAddress;
uint8 u8AssocStatus = 2;//联网状态被拒绝
u16ShortAddress = 0xffff;//初始化短地址,广播地址
/* Check that the device only wants to use a short address */
if (psMlmeInd->uParam.sIndAssociate.u8Capability & 0x80)//?????????????????????
{
if (sCoordData.sNode.u8AssociatedNodes < MAX_UART_NODES)//如果节点数在允许范围内
{
u16ShortAddress = UART_NODE_ADDR_BASE + sCoordData.sNode.u8AssociatedNodes;//分配短地址
sCoordData.sNode.asAssocNodes[sCoordData.sNode.u8AssociatedNodes].u16ShortAddr = u16ShortAddress;//存储地址
sCoordData.sNode.u8AssociatedNodes++;//节点数自增
u8AssocStatus = 0;//联网状态成功
vLedControl(1,1);//开LED2表示联网成功
}
}
/* 创建联网响应 */
sMlmeReqRsp.u8Type = MAC_MLME_RSP_ASSOCIATE;//联网响应
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeRspAssociate_s);//联网请求实体长度
sMlmeReqRsp.uParam.sRspAssociate.sDeviceAddr.u32H = psMlmeInd->uParam.sIndAssociate.sDeviceAddr.u32H;//地址高字节
sMlmeReqRsp.uParam.sRspAssociate.sDeviceAddr.u32L = psMlmeInd->uParam.sIndAssociate.sDeviceAddr.u32L;//地址低字节
sMlmeReqRsp.uParam.sRspAssociate.u16AssocShortAddr = u16ShortAddress;//节点短地址
sMlmeReqRsp.uParam.sRspAssociate.u8Status = u8AssocStatus;//联网状态
sMlmeReqRsp.uParam.sRspAssociate.u8SecurityEnable = FALSE;//没有安全设置
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);//管理实体请求,节点联网请求
}
/****************************************************************************
* NAME: bStartCoordinator
* DESCRIPTION:创建个域网
****************************************************************************/
PRIVATE void vStartCoordinator(void)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
/* 创建PAN */
sMlmeReqRsp.u8Type = MAC_MLME_REQ_START;//启动请求
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqStart_s);//启动请求长度
sMlmeReqRsp.uParam.sReqStart.u16PanId = PAN_ID;//设置PAN_ID
sMlmeReqRsp.uParam.sReqStart.u8Channel = sCoordData.sSystem.u8Channel;//设置系统通道
sMlmeReqRsp.uParam.sReqStart.u8BeaconOrder = 0x0f; /* No beacons *///信标
sMlmeReqRsp.uParam.sReqStart.u8SuperframeOrder = 0x0f;//超帧
sMlmeReqRsp.uParam.sReqStart.u8PanCoordinator = TRUE;//PAN协调器?????????????
sMlmeReqRsp.uParam.sReqStart.u8BatteryLifeExt = FALSE;//电池电压
sMlmeReqRsp.uParam.sReqStart.u8Realignment = FALSE;//Realignment ???????????
sMlmeReqRsp.uParam.sReqStart.u8SecurityEnable = FALSE;//没有安全设置
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);//启动协调器请求
}
/****************************************************************************
* NAME: vTxUARTData
* DESCRIPTION:
****************************************************************************/
PRIVATE void vWUART_TxData(void)
{
MAC_McpsReqRsp_s sMcpsReqRsp;
MAC_McpsSyncCfm_s sMcpsSyncCfm;
uint8 *pu8Payload, i = 0;
int16 i16RxChar;
i16RxChar = i16Serial_RxChar();//接收来自PC机的命令
if (i16RxChar >= 0)//如果有命令
{
/* 创建帧传输请求*/
sMcpsReqRsp.u8Type = MAC_MCPS_REQ_DATA;//请求类型
sMcpsReqRsp.u8ParamLength = sizeof(MAC_McpsReqData_s);//请求长度
/* 设置句柄 */
sMcpsReqRsp.uParam.sReqData.u8Handle = 1;//设置句柄
/*使用源短地址 */
sMcpsReqRsp.uParam.sReqData.sFrame.sSrcAddr.u8AddrMode = 2;//16位短地址模式
sMcpsReqRsp.uParam.sReqData.sFrame.sSrcAddr.u16PanId = PAN_ID;//PAN_ID
sMcpsReqRsp.uParam.sReqData.sFrame.sSrcAddr.uAddr.u16Short = COORD_ADDR;//协调器地址
/* 使用目标短地址 */
sMcpsReqRsp.uParam.sReqData.sFrame.sDstAddr.u8AddrMode = 2;//16位短地址模式
sMcpsReqRsp.uParam.sReqData.sFrame.sDstAddr.u16PanId = PAN_ID;//PAN_ID
sMcpsReqRsp.uParam.sReqData.sFrame.sDstAddr.uAddr.u16Short = 0xffff;//广播
/* 有ack ,但没有 security, indirect transmit or GTS */
sMcpsReqRsp.uParam.sReqData.sFrame.u8TxOptions = MAC_TX_OPTION_ACK;//发送操作
pu8Payload = sMcpsReqRsp.uParam.sReqData.sFrame.au8Sdu;//数据载荷指针指向发送数据实体
pu8Payload[i++] = u8TxFrameHandle++;//数据载荷【0】为0
pu8Payload[i++] = (uint8)i16RxChar;//数据载荷【1】
while ((i16RxChar >= 0) && (i < MAX_DATA_PER_FRAME))//数据载荷长度在64字节内
{
i16RxChar = i16Serial_RxChar();//读取PC机命令
if (i16RxChar >= 0)
{
pu8Payload[i++] = (uint8)i16RxChar;//数据载荷【2...】
}
}
sMcpsReqRsp.uParam.sReqData.sFrame.u8SduLength = i;//设置帧长
vAppApiMcpsRequest(&sMcpsReqRsp, &sMcpsSyncCfm);//管理实体请求,传输请求
}
}
/****************************************************************************
* NAME: vStartEnergyScan
* DESCRIPTION:
****************************************************************************/
PRIVATE void vStartEnergyScan(void)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
/* 创建能量检测扫描*/
sMlmeReqRsp.u8Type = MAC_MLME_REQ_SCAN;//扫描请求
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqStart_s);//管理实体请求长度
sMlmeReqRsp.uParam.sReqScan.u8ScanType = MAC_MLME_SCAN_TYPE_ENERGY_DETECT;//能量检测
sMlmeReqRsp.uParam.sReqScan.u32ScanChannels = SCAN_CHANNELS;//扫描通道
sMlmeReqRsp.uParam.sReqScan.u8ScanDuration = ENERGY_SCAN_DURATION;//扫描时间
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);//能量扫描请求
}
/****************************************************************************
* NAME: vHandleEnergyScanResponse
* DESCRIPTION:
****************************************************************************/
PRIVATE void vHandleEnergyScanResponse(MAC_MlmeDcfmInd_s *psMlmeInd)
{
uint8 i = 0;
uint8 u8MinEnergy;
u8MinEnergy = (psMlmeInd->uParam.sDcfmScan.uList.au8EnergyDetect[0]) ;//设置最通道1为最安静通道
/* 寻找最安静的通道*/
while (i < psMlmeInd->uParam.sDcfmScan.u8ResultListSize)//当通道数在允许范围内时
{
if ((psMlmeInd->uParam.sDcfmScan.uList.au8EnergyDetect) < u8MinEnergy)//如果其他通道小于最安静通道
{
u8MinEnergy = (psMlmeInd->uParam.sDcfmScan.uList.au8EnergyDetect);//将其他通道赋给最安静通道
sCoordData.sSystem.u8Channel = i + CHANNEL_MIN;//设置系统通道
}
i++;
}
}
/****************************************************************************/
/*** 文件结束 ***/
/****************************************************************************/
用户377235 2012-4-19 20:24