庆科的wifi模块采用AT指令来通讯。AT指令相对于固定帧头的帧显得有些麻烦。但是又有其规律。"AT+"是给wifi模块发送的指令头,同时也是wifi模块回显的头。“+”是wifi模块主动发起的数据。还有“OK","ERROR"这两个反馈。所有的指令都以‘\r’回车符作为结束。"OK","ERROR"还以'\r'开头。根据它们的特点我做以下处理。
首先定义了全局变量:
//接收结构体
typedef struct
{
u8 stepReciveATPlus; //用于接收AT+指令
u8 stepRecivePlus; //用于接收+指令
u8 stepOK; //用于接收OK反馈
u8 stepERROR; //用于接收ERROR反馈
u8 downloadBuf[150]; //用于接收+指令数据
u8 getPlusFramFlag; //true:接收到+P帧
u8 getOKFlag; //true:收到"OK"包
u8 getERRORFlag; //true:收到"ERROR"包
}typeWifiReceive;
//wifi结构体
typedef struct
{
u8 powflag; //true: 上电完成状态, false:上电状态
u8 onlineflag; //true: 在线状态, false:离线状态
typeWifiReceive receiveStr; //接收结构体
}typeWifi;
//定义变量
typeWifi WifiStruct;
先是“OK” 和"ERROR"的处理。
//========================================================================================================
//函数名: FixedStrFlowReturnReceive()
//参 数: fixstr:目标字符,len:目标字符长度,step:接收状态,input:输入的字符
//返 回: false:没有收到目标字符,true:收到目标字符
//说 明: 固定字符加回车的接收
//========================================================================================================
u8 FixedStrFlowReturnReceive(const char* fixstr,u8 len, u8* step, u8 input)
{
if('\r' == input) //等待回车结束符
{
if(*step != len)
{
*step = 0;
return false;
}
else
{
*step = 0;
return true; //收到指定字符串
}
}
if((fixstr[*step] == input) && (len >*step))//字符段的比较
{
*step += 1;
}
else
{
*step = 0;
}
return false;
}
下面是"AT+"和"+"的处理
//========================================================================================================
//函数名: ATPlusAndPlusFlowReturnReceive()
//参 数: input 输入字符
//返 回: false 未收到"+"字符串,true 收到"+"字符串
//说 明: AT+和+字符串接收
//========================================================================================================
u8 ATPlusAndPlusFlowReturnReceive(u8 input)
{
//AT+数据帧接收,AT+开始 '\n'结束 回显数据
switch(WifiStruct.receiveStr.stepReciveATPlus)
{
case 0: if('A' == input) WifiStruct.receiveStr.stepReciveATPlus++; break;
case 1: if('T' == input) WifiStruct.receiveStr.stepReciveATPlus++;
else WifiStruct.receiveStr.stepReciveATPlus = 0; break;
case 2: if('+' == input) {
WifiStruct.receiveStr.stepReciveATPlus++;
WifiStruct.receiveStr.stepRecivePlus = 0;
}
else
WifiStruct.receiveStr.stepReciveATPlus = 0;
break;
default: if((0 != WifiStruct.receiveStr.stepReciveATPlus)&&('\r' == input))
{
WifiStruct.receiveStr.stepReciveATPlus = 0;
}
break;
}
//+数据帧接收,+开始 '\n'结束,下发数据
if((0 == WifiStruct.receiveStr.stepReciveATPlus)//如果"AT+"在接收则认为不是"+"帧
&& ('+' == input))
{
WifiStruct.receiveStr.stepRecivePlus++;
WifiStruct.receiveStr.downloadBuf[0] = input;
}
else if(0 != WifiStruct.receiveStr.stepRecivePlus)
{
if(WifiStruct.receiveStr.stepRecivePlus < sizeof(WifiStruct.receiveStr.downloadBuf))
WifiStruct.receiveStr.downloadBuf[WifiStruct.receiveStr.stepRecivePlus++] = input;
else
WifiStruct.receiveStr.stepRecivePlus = 0;
if('\r' == input)
{
WifiStruct.receiveStr.downloadBuf[WifiStruct.receiveStr.stepRecivePlus] = '\0';
WifiStruct.receiveStr.stepRecivePlus = 0;
WifiStruct.receiveStr.getPlusFramFlag = true;
return true;
}
}
return false;
}
在代码主循环中从环形缓冲区读取数据并分析,并做超时处理。
//========================================================================================================
//函数名: AnalyzeAppData()
//参 数:
//返 回:
//说 明: 解析App下发数据
//========================================================================================================
void AnalyzeAppData(void)
{
u8 temp;
static u8 step = 0; //接收状态机
switch(step)
{
case 0: //初始状态
SetTimer(T_APP_ANALYZE,0); //设置超时定时器为0用以把基础信息清除
step++;
break;
case 1:
if(0 == GetTimer(T_APP_ANALYZE))//超时定时器到清除信息
{
WifiStruct.receiveStr.stepERROR = 0;
WifiStruct.receiveStr.stepOK = 0;
WifiStruct.receiveStr.stepReciveATPlus = 0;
WifiStruct.receiveStr.stepRecivePlus = 0;
SetTimer(T_APP_ANALYZE,MS_500);
}
if(FALSE == GetRXData(&temp)) //缓冲区为空则不往下执行
{
break;
}
SetTimer(T_APP_ANALYZE,MS_500); //收到数据则复位超时定时器
do
{
//OK字符串口判断
if(FixedStrFlowReturnReceive(str_OK, 2, &WifiStruct.receiveStr.stepOK,temp))
{
WifiStruct.receiveStr.getOKFlag = true;
}
//ERROR字符串口判断
if(FixedStrFlowReturnReceive(str_ERROR, 5, &WifiStruct.receiveStr.stepERROR,temp))
{
WifiStruct.receiveStr.getERRORFlag = true;
}
if(ATPlusAndPlusFlowReturnReceive(temp))
{
step = 2;
break;
}
if(0 == GetTimer(T_APP_ANALYZE))//如果超时则退出循环
break;
}
while (GetRXData(&temp)); //如果缓冲区还有数据则继续处理
break;
case 2:
step = 1;
WifiStruct.receiveStr.getPlusFramFlag = false;
//对'+'指令处理
break;
}
}