查看: 1958|回复: 0
打印 上一主题 下一主题

小弟初次尝试写gprs状态机,烦请坛友们留步帮忙看看

[复制链接]
跳转到指定楼层
沙发
发表于 2015-6-14 17:05:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小弟一直在学习状态机,无奈状态机太高深到现在还没入门,马上就要毕业了现在开始整毕业设计,于是乎就尝试用状态机来做毕业设计,下位机使用gprs通信与上位机通信,因为下位机只需发送数据给上位机,所以现在只写了gprs发送部分。
10ms扫描一次状态机,代码如下:
    switch(gprs.status){
        /******************************************************
        **连接
        ******************************************************/
        case CONNECT:
        {
            SIM900_SendCommand("AT+CIPCLOSE\r\n");
            SIM900_SendCommand("AT+CIPSHUT\r\n");
            SIM900_SendCommand("AT+CIPSTART=\"TCP\",\"www.cmcu.vicp.net\",\"2741\"\r\n");  
            at.recvIsOk     = FALSE;
            gprs.status     = CHECK_CONNECT_STATUS;
            gprs.timeout    = 0;
            gprs.errorCount = 0;
            SIM900_ClearAtBuf();
        }break;
        /*****************************************************
        **检查连接状态
        *****************************************************/
        case CHECK_CONNECT_STATUS:
        {
            if(TRUE == at.recvIsOk){
                at.recvIsOk  = FALSE;
                gprs.timeout = 0;
                if(strstr(at.buf,"CONNECT OK")||            //连接成功?
                    strstr(at.buf,"ALREADY CONNECT")){      //已经连接了?
                    gprs.status = IDLE;
                }
                else if(strstr(at.buf,"CONNECT FAIL")){
                    gprs.status = CONNECT;
                }
                else{
                    at.recvIsOk = FALSE;
                }
                SIM900_ClearAtBuf();
            }
            else{
                if(++gprs.timeout >= 3000){     //超时?
                    gprs.timeout = 0;
                    gprs.status  = CONNECT;       //长时间无响应,重新发送连接指令
                }
            }
        }break;
        /*****************************************************
        **i空闲状态
        *****************************************************/
        case IDLE:
        {
            if(strstr(at.buf,"CLOSED")){                 //远程主机关闭?
                gprs.status  = CONNECT;                  //
                gprs.timeout = 0;
                break;
            }
            if(FALSE == gprs.txBufIsEmpty){     //发送缓冲区有新数据?
                gprs.status     = SEND_DATA;
                gprs.timeout    = 0;
                gprs.errorCount = 0;
                break;
            }
            if(++gprs.timeout >= 3000){                    //到了30秒?
                gprs.status     = SEND_HEARTBEAT;
                gprs.timeout    = 0;
                gprs.errorCount = 0;
            }
        }break;
        /*****************************************************
        **发送数据
        *****************************************************/
        case SEND_DATA:
        {
            strcat(cmdBuf,"AT+CIPSEND\r\n");
            strcat(cmdBuf,gprs.txBuf);
            strcat(cmdBuf,"\r\n");
            strcat(cmdBuf,&endAscii);
            SIM900_SendCommand(cmdBuf);
            SIM900_ClearAtBuf();
            at.recvIsOk  = FALSE;
            gprs.timeout = 0;
            gprs.status  = CHECK_SEND_DATA_STATUS;

        }break;
        /*****************************************************
        **检查发送数据状态
        *****************************************************/
        case CHECK_SEND_DATA_STATUS:
        {
            if(TRUE == at.recvIsOk){
                at.recvIsOk = FALSE;
                if(strstr(at.buf,"SEND OK")){                      //send ok为发送成功时返回的指令,所以只查找返回的指令中是否有send ok
                    gprs.status = IDLE;
                    gprs.txBufIsEmpty = TRUE;
                    memset(gprs.txBuf,0,sizeof(gprs.txBuf));
                    SIM900_ClearAtBuf();
                }   
            }
            else{
                if(++gprs.timeout > 1000){            //到了10秒?
                    gprs.timeout = 0;
                    gprs.status = SEND_DATA;         //10秒内没有返回到send ok,重新发送
                    if(++gprs.errorCount > 3){         
                        gprs.status = CONNECT;        //发送三次后仍然没有返回send ok,调到连接状态,重新连接 服务器
                    }
                }
            }
        }break;
        /*****************************************************
        **发送心跳包
        *****************************************************/
        case SEND_HEARTBEAT:
        {
            strcat(cmdBuf,"AT+CIPSEND\r\n");
            strcat(cmdBuf,"heart\r\n");
            strcat(cmdBuf,&endAscii);
            SIM900_SendCommand(cmdBuf);
            SIM900_ClearAtBuf();
            at.recvIsOk  = FALSE;
            gprs.status  = CHECK_SEND_HEARTBEAT_STATUS;
            gprs.timeout = 0;
        }break;
        /*****************************************************
        **检查发送心跳包状态
        *****************************************************/
        case CHECK_SEND_HEARTBEAT_STATUS:
        {
            if(TRUE == at.recvIsOk){
                at.recvIsOk = FALSE;
                if(strstr(at.buf,"SEND OK")){
                    gprs.status = IDLE;
                    SIM900_ClearAtBuf();  
                }
            }
            else{
                if(++gprs.timeout > 1000){
                    gprs.timeout = 0;
                    gprs.status = SEND_HEARTBEAT;
                    if(++gprs.errorCount > 3){
                        gprs.status = CONNECT;
                    }
                }
            }
        }break;
        default :
        {

        }break;
    }
转载

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表