搜索
bottom↓
回复: 54
打印 上一主题 下一主题

CC430与GSM SIM900通讯的状态机

  [复制链接]

出0入0汤圆

跳转到指定楼层
1
发表于 2011-11-9 17:45:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是最近给水文项目做的其中一个状态机。
这里只奉上SIM900通讯的状态机,CC430短距通讯采用时分,最大可以连接32路端机;
命令包括了AT、短信功能、GPRS功能;IP SEND DATA部分没有加入函数,有需要用的自己加入发送函数;
先上原理图

出0入0汤圆

2
 楼主| 发表于 2011-11-9 17:49:35 | 只看该作者
点击此处下载 ourdev_693544N18HMD.pdf(文件大小:125K) (原文件名:GSM.pdf)

出0入0汤圆

3
 楼主| 发表于 2011-11-9 17:50:39 | 只看该作者
贴上代码:
typedef enum
{
        AT_STATE_IDLE=0,
        AT_STATE_CHECK_GSM,
        AT_STATE_START_GSM,
        AT_STATE_START_GSM_DELAY,
        AT_STATE_CLOSE_GSM,
        AT_STATE_ATE0,
        AT_STATE_AT,
        AT_STATE_CMGF,
        AT_STATE_CREG,
        //AT_STATE_CIPCLOSE,
        AT_STATE_START,
        AT_STATE_CHECKAT,
        AT_STATE_IPSTART,
        AT_STATE_IPSTART_1,
        AT_STATE_IPSTART_2,
        AT_STATE_IPSEND,
        AT_STATE_IPSEND_DATA,
        AT_STATE_IPSEND_1,
        AT_STATE_IPSEND_DATA_1,
        AT_STATE_IPSEND_2,
        AT_STATE_IPSEND_DATA_2,
        AT_STATE_IPCLOSE,
        AT_STATE_IPCLOSE_1,
        AT_STATE_IPCLOSE_2,
        AT_STATE_MSG_TEXT,
        AT_STATE_MSG_PDU,
        AT_STATE_MSG_SEND,
        AT_STATE_MSG_SEND_DATA,
        AT_STATE_CIPSEND_WAITSTART,
        AT_STATE_CIPSEND_SEND,
        AT_STATE_CIPSEND_SENDOVER,
        AT_STATE_READ_MSG,
        AT_STATE_HANDLE_MSG,
        AT_STATE_DELETE_MSG,
        AT_STATE_SLEEP,
        AT_STATE_WAKEUP,
        AT_STATE_CIPMUX,
        AT_STATE_QUERY_IPMUX,
        AT_STATE_CSTT,
        AT_STATE_CIICR,
        AT_STATE_CIFSR,
        AT_STATE_CSQ,
        AT_STATE_WAITTIME,
}at_sta_type;

extern unsigned char m_Receive_MSG_Flag;

typedef enum{
        IDLE_MSG=0,
SEND_MSG,
RECEIVE_MSG,
READ_MSG,
READING_MSG,
READ_MSG_OVER,
DELETE_MSG,
}msg_sta_type;

extern unsigned char m_Receive_Data_Finish_Flag;

typedef enum
{
        AT_NO_RESULT,
        AT_INPUT,
        AT_SUCCEED,
        AT_FAILED,
}at_result;

typedef struct
{
        at_sta_type AT_STA;
        at_sta_type AT_STA_PRE;
        at_sta_type AT_STA_NEXT;
        at_sta_type AT_STA_FAIL;
        at_sta_type AT_STA_SUCCESS;
        at_result AT_RESULT;
        uint16_t Wait_Time;
        unsigned char Time_Out_Flag;
        unsigned char m_MSG_Index;
        msg_sta_type m_Receive_MSG_Flag;
}state_mechine;

#define No_Wait_Time 0

#define Wait_Time_20ms 1
#define Wait_Time_40ms 2
#define Wait_Time_60ms 3
#define Wait_Time_80ms 4
#define Wait_Time_100ms 5

#define Wait_Time_200ms 10
#define Wait_Time_400ms 20
#define Wait_Time_500ms 25
#define Wait_Time_800ms 40
#define Wait_Time_600ms 30

#define Wait_Time_1second 50
#define Wait_Time_2second 100
#define Wait_Time_3second 150
#define Wait_Time_4second 200
#define Wait_Time_5second 250
#define Wait_Time_6second 300
#define Wait_Time_7second 350
#define Wait_Time_8second 400
#define Wait_Time_9second 450
#define Wait_Time_10second 500
#define Wait_Time_11second 550
#define Wait_Time_12second 600
#define Wait_Time_13second 650
#define Wait_Time_14second 700
#define Wait_Time_15second 750

#define INPUT_Length 4
#define OK_Length 2
#define ERROR_Length 5
#define CONNECT_OK_Length 10//and CREG_Length
#define CONNECT_FAIL_Length 12
#define ALREADY_CONNECT_Length 15
#define ERROR_ALREADY_CONNECT_Length 24
#define ERROR_CONNECT_OK_Length 19
#define ERROR_CONNECT_FAIL_Length 21
#define SEND_OK_Length 7
#define SEND_OK_AND_REC_DATA_Length 20//大于20个;
#define SEND_FAIL_Length 9

#define RECEIVE_MSG_1 13
#define RECEIVE_MSG_2 14
#define MUTI_CONNECT_OK 13

#define MUTI_ALREADY_CONNECT 18
#define MUTI_CONNECT_FAIL_Length 15
#define MUTI_ERROR_ALREADY_CONNECT_Length 30
#define MUTI_ERROR_CONNECT_OK_Length 22
#define MUTI_ERROR_CONNECT_FAIL_Length 24

#define FIRST_COMMA                1
#define SECOND_COMMA        2
#define THIRD_COMMA                3
#define FOURTH_COMMA        4
#define FIFTH_COMMA                5
#define SIXTH_COMMA                6
#define SEVENTH_COMMA        7
#define EIGHTH_COMMA        8
#define NINTH_COMMA        9
#define MSG_1_CONFIG_ADDR 0x1900
#define MSG_3_CONFIG_ADDR_1 0x1880
#define MSG_3_CONFIG_ADDR_2 0x1900
#define MSG_4_CONFIG_ADDR 0x1880
#define MSG_5_CONFIG_ADDR 0x1880
#define MSG_D_CONFIG_ADDR 0x1900

extern state_mechine STATE_MECHINE;

unsigned char Get_Length(unsigned char *ptr);
void GSM_init(void);

void AT_STATE_MECHINE(void);
void Uart_Handle(void);

出0入0汤圆

4
 楼主| 发表于 2011-11-9 17:51:27 | 只看该作者
const unsigned char AT_CIPSTART[]={"AT+CIPSTART=1,\"TCP\",\"xxx.xxx.xxx.xxx\",9899\r"};
const unsigned char AT_CIPSTART_1[]={"AT+CIPSTART=1,\"TCP\",\"xxx.xxx.xxx.xxx\",10808\r"};
const unsigned char AT_CIPSTART_2[]={"AT+CIPSTART=2,\"TCP\",\"xxx.xxx.xxx.xxx1\",10808\r"};

const unsigned char AT_ATE0[]={"ATE0&W\r"};                                //关闭回显
const unsigned char AT_CIPSEND[]={"AT+CIPSEND\r"};                //发送IP数据
const unsigned char AT_CIPSEND_1[]={"AT+CIPSEND=1\r"};                //发送IP数据
const unsigned char AT_CIPSEND_2[]={"AT+CIPSEND=2\r"};                //发送IP数据
const unsigned char AT_CIPHEAD1[]={"AT+CIPHEAD=1\r"};       //
const unsigned char ATD[]={"ATDxxxxxxxxx \r"};
const unsigned char AT_CIPCLOSE[]={"AT+CIPCLOSE=1\r"};
const unsigned char AT_CIPCLOSE_1[]={"AT+CIPCLOSE=2\r"};

const unsigned char AT_CIPSHUT[]={"AT+CIPSHUT\r"};       
const unsigned char AT_CIMI[]={"AT+CIMI\r"};                                //查询IMSI
const unsigned char AT_AT[] = {"AT\r"};
const unsigned char AT_CREG[] = {"AT+CREG?\r"};             //查询注_册信息

const unsigned char AT_CIPMUX[]={"AT+CIPMUX=1\r"};//IP多路连接;
const unsigned char AT_QCIPMUX[]={"AT+CIPMUX?\r"};//IP多路连接;
const unsigned char AT_CMGF[]={"AT+CMGF=1\r"};

const unsigned char AT_SENDMSA2[]={"AT+CSCS=\"GSM\"\r"};
const unsigned char AT_SENDMSA3[]={"AT+CMGS=\"xxxxxxxx\"\r"};
//unsigned char AT_SENDMSA4[128]={"this is the test."};

const unsigned char AT_CALL[]={"ATDxxxxxxxxxxx;\r"};
const unsigned char AT_HANGCALL[]={"ATH\r"};

const unsigned char AT_CSQ[]={"AT+CSQ\r"};//GSM RSSI

const unsigned char AT_ATE0_RSP[]={"\r\nOK\r\n"};
const unsigned char AT_CREG_RSP[]={"\r\n+CREG: 0,1\r\n"};//\r\nOK\r\n"};
const unsigned char AT_IPSEND_RSP[]={"\r\n> "};
const unsigned char AT_SEND_OK_RSP[]={"\r\nSEND OK\r\n"};
const unsigned char AT_SEND_FAIL_RSP[]={"\r\nSEND FAIL\r\n"};
const unsigned char AT_CONNECT_FAIL_RSP[]={"\r\nCONNECT FAIL\r\n"};

const unsigned char AT_CANCLE_CSCLK[]={"AT+CSCLK=0\r"};
const unsigned char AT_ENTER_CSCLK[]={"AT+CSCLK=2\r"};
const unsigned char AT_WAKE_UP[]={"\r\r"};

const unsigned char AT_CLOSE_GSM[]={"AT+CPOWD=0\r"};

const unsigned char AT_READ_MSG[]={"AT+CMGR="};
const unsigned char AT_DELETE_MSG[]={"AT+CMGD=1,3\r"};
const unsigned char AT_GET_BAUD[]={"AT+IPR?"};

unsigned char m_Receive_Data_Finish_Flag=false;//0,未结束,1,结束;

state_mechine STATE_MECHINE;

unsigned char m_Send_MSG_Enable=0;//default 0,not send msg;1, send msg
const unsigned char WAKE_UP[]={"\r\r"};
__no_init unsigned char m_MSG_Phone_Num[11];

unsigned char Get_Length(unsigned char *ptr)
{
        unsigned char i=0;
        while(*ptr!=0)
        {
                i++;
                ptr++;
        }
        return i;
}


void GSM_init(void)
{
        CONFIG_GSM_STA;
        CONFIG_GSM_RST;
        CONFIG_GSM_ON_OFF;
        STATE_MECHINE.m_Receive_MSG_Flag=IDLE_MSG;
        STATE_MECHINE.Time_Out_Flag=false;
        STATE_MECHINE.AT_STA_FAIL=AT_STATE_IDLE;
        STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_IDLE;
        STATE_MECHINE.AT_STA_NEXT=AT_STATE_IDLE;
        STATE_MECHINE.AT_STA_PRE=AT_STATE_IDLE;
    STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
        if (READ_GSM_STA!=GSM_WORK)
        {
                GSM_ON_OFF_L;
                STATE_MECHINE.AT_STA_PRE=AT_STATE_START_GSM;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_CHECK_GSM;
                STATE_MECHINE.AT_STA_NEXT=AT_STATE_CHECK_GSM;
                STATE_MECHINE.Wait_Time=Wait_Time_500ms;
                //Timer1_A0_restart();
        }
        else
        {
                STATE_MECHINE.AT_STA=AT_STATE_CHECK_GSM;
                uart0.Rx_Length=0;
                STATE_MECHINE.Wait_Time=0;
               
        }
}

出0入0汤圆

5
 楼主| 发表于 2011-11-9 17:51:55 | 只看该作者
void AT_STATE_MECHINE(void)
{
        //        if (STATE_MECHINE.Wait_Time==0)
        //        {
        switch(STATE_MECHINE.AT_STA)
        {
        case AT_STATE_IDLE:
                if (STATE_MECHINE.m_Receive_MSG_Flag==RECEIVE_MSG)
                {
                        STATE_MECHINE.m_Receive_MSG_Flag=IDLE_MSG;
                        STATE_MECHINE.AT_STA=AT_STATE_READ_MSG;                               
                }
                break;
        case AT_STATE_CHECK_GSM:
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_CMGF;//AT_STATE_IDLE;//AT_STATE_QUERY_IPMUX;//AT_STATE_CREG; start;
                STATE_MECHINE.Wait_Time=Wait_Time_200ms;
                STATE_MECHINE.AT_STA_PRE=AT_STATE_CHECK_GSM;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                uart0.Tx_Length=Get_Length((unsigned char*)AT_AT);
                memcpy(uart0.Tx_Buf,AT_AT,uart0.Tx_Length);
                uart_send_byte(uart0.Tx_Buf,uart0.Tx_Length);
                //Timer1_A0_restart();
                break;       
        case AT_STATE_START_GSM:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_START_GSM;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_CHECK_GSM;
                STATE_MECHINE.Wait_Time=Wait_Time_600ms;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                GSM_ON_OFF_L;
                //Timer1_A0_restart();
                break;
        case AT_STATE_START_GSM_DELAY:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_CHECK_GSM;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_CHECK_GSM;
                STATE_MECHINE.Wait_Time=Wait_Time_10second;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                //Timer1_A0_restart();
                break;
        case AT_STATE_CLOSE_GSM:
                GSM_ON_OFF_L;
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_IDLE;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_IDLE;
                STATE_MECHINE.Wait_Time=Wait_Time_600ms;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                //Timer1_A0_restart();
                break;
        case AT_STATE_AT:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_AT;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_IPSTART;
                STATE_MECHINE.Wait_Time=Wait_Time_400ms;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                uart0.Tx_Length=Get_Length((unsigned char*)AT_AT);
                memcpy(uart0.Tx_Buf,AT_AT,uart0.Tx_Length);
                uart_send_byte(uart0.Tx_Buf,uart0.Tx_Length);
                //Timer1_A0_restart();
                break;
        case AT_STATE_CMGF:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_CHECK_GSM;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_QUERY_IPMUX;//AT_STATE_IDLE;//
                STATE_MECHINE.Wait_Time=Wait_Time_500ms;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                uart0.Tx_Length=Get_Length((unsigned char*)AT_CMGF);
                memcpy(uart0.Tx_Buf,AT_CMGF,uart0.Tx_Length);
                uart_send_byte(uart0.Tx_Buf,uart0.Tx_Length);
                break;
        case AT_STATE_ATE0:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_START_GSM;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_CHECK_GSM;
                STATE_MECHINE.Wait_Time=Wait_Time_200ms;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                uart0.Tx_Length=Get_Length((unsigned char*)AT_AT);
                memcpy(uart0.Tx_Buf,AT_AT,uart0.Tx_Length);
                uart_send_byte(uart0.Tx_Buf,uart0.Tx_Length);
                //Timer1_A0_restart();
                break;
        case AT_STATE_CREG:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_CREG;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_IPSTART;
                STATE_MECHINE.Wait_Time=Wait_Time_8second;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                //Timer1_A0_restart();
                break;
        case AT_STATE_CSQ:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_START_GSM;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_IDLE;
                STATE_MECHINE.Wait_Time=Wait_Time_400ms;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                uart0.Tx_Length=Get_Length((unsigned char*)AT_CSQ);
                memcpy(uart0.Tx_Buf,AT_CSQ,uart0.Tx_Length);
                uart_send_byte(uart0.Tx_Buf,uart0.Tx_Length);
                break;
        case AT_STATE_IPSTART:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_CHECK_GSM;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_IDLE;//AT_STATE_IPSTART_1;
                STATE_MECHINE.Wait_Time=Wait_Time_6second;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                uart0.Tx_Length=Get_Length((unsigned char*)AT_CIPSTART);
                memcpy(uart0.Tx_Buf,AT_CIPSTART,uart0.Tx_Length);
                uart_send_byte(uart0.Tx_Buf,uart0.Tx_Length);
                break;
        case AT_STATE_IPSTART_1:
                STATE_MECHINE.AT_STA_FAIL=AT_STATE_CHECK_GSM;
                STATE_MECHINE.AT_STA_SUCCESS=AT_STATE_IPSTART_2;
                STATE_MECHINE.Wait_Time=Wait_Time_6second;
                STATE_MECHINE.AT_STA_PRE=STATE_MECHINE.AT_STA;
                STATE_MECHINE.AT_STA=AT_STATE_WAITTIME;
                STATE_MECHINE.AT_RESULT=AT_NO_RESULT;
                uart0.Tx_Length=Get_Length((unsigned char*)AT_CIPSTART_1);
                memcpy(uart0.Tx_Buf,AT_CIPSTART_1,uart0.Tx_Length);
                uart_send_byte(uart0.Tx_Buf,uart0.Tx_Length);
                break;
        case AT_STATE_IPSTART_2:
                STATE_MECHINE.AT_STA_FAIL=

出0入0汤圆

6
 楼主| 发表于 2011-11-9 17:52:30 | 只看该作者
串口处理函数

void Uart_Handle(void)
{
        if (uart0.Rx_Length>=3)
        {
                if ((uart0.Rx_Buf[2]=='>')&&(uart0.Rx_Buf[3]==' '))
                {
                        STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                        uart0.Rx_Length=0;
                        //Timer1_A0_stop();
                        return;
                }
                if((uart0.Rx_Buf[0]=='#')&&(uart0.Rx_Buf[2]=='('))
                {
                        if((uart0.Rx_Buf[uart0.Rx_Length-2]==0x0d)&&(uart0.Rx_Buf[uart0.Rx_Length-1]==0x0a))
                        {
                                STATE_MECHINE.AT_STA=AT_STATE_HANDLE_MSG;
                                uart0.Rx_Length=0;
                                return;
                        }
                }
                if ((uart0.Rx_Buf[0]==0x0d)&&(uart0.Rx_Buf[1]==0x0a))
                {
                        if ((uart0.Rx_Buf[uart0.Rx_Length-2]==0x0d)&&(uart0.Rx_Buf[uart0.Rx_Length-1]==0x0a))
                        {
                                switch((uart0.Rx_Length-4))
                                {
                                case OK_Length:
                                        if (strncmp(uart0.Rx_Buf,AT_ATE0_RSP,uart0.Rx_Length)==0)
                                        {
                                                switch (STATE_MECHINE.AT_STA_PRE)
                                                {
                                                case AT_STATE_CHECK_GSM:
                                                case AT_STATE_CMGF:
                                                case AT_STATE_CIPMUX:
                                                        STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                                        break;
                                                case AT_STATE_CSTT:
                                                case AT_STATE_CIICR:
                                                        STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                                        break;
                                                case AT_STATE_DELETE_MSG:
                                                        STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                                        break;
                                                }
                                        }
                                        break;
                                case ERROR_Length:
                                        break;
                                case CONNECT_OK_Length://creg_length
                                        if (strncmp(uart0.Rx_Buf,AT_CREG_RSP,uart0.Rx_Length)==0)
                                        {
                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                        }
                                        else
                                        {
                                                if (strncmp(uart0.Rx_Buf,"\r\nCONNECT OK\r\n",uart0.Rx_Length)==0)
                                                {
                                                        STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                                }
                                                else
                                                {
                                                        if (strncmp(uart0.Rx_Buf,"\r\n+CIPMUX: 1\r\n",uart0.Rx_Length)==0)
                                                        {
                                                                //STATE_MECHINE.AT_RESULT=AT_SUCCEED;
                                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                                        }
                                                        else
                                                        {
                                                                if (strncmp(uart0.Rx_Buf,"\r\n+CIPMUX: 0\r\n",uart0.Rx_Length)==0)
                                                                {
                                                                        STATE_MECHINE.AT_STA=AT_STATE_CIPMUX;
                                                                }
                                                                else
                                                                {
                                                                        if (strncmp(uart0.Rx_Buf,"\r\nCall Ready\r\n",uart0.Rx_Length)==0)
                                                                        {
                                                                                STATE_MECHINE.AT_STA=AT_STATE_CHECK_GSM;
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                        break;
                                case ALREADY_CONNECT_Length:
                                        if (strncmp(uart0.Rx_Buf,"\r\nALREADY CONNECT\r\n",uart0.Rx_Length)==0)
                                        {
                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                        }
                                        break;
                                case CONNECT_FAIL_Length:
                                        if (strncmp(uart0.Rx_Buf,"\r\nCONNECT FAIL\r\n",uart0.Rx_Length)==0)
                                        {
                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_FAIL;
                                        }
                                        break;
                                case MUTI_CONNECT_OK://RECEIVE_MSG_1
                                        if (strncmp(uart0.Rx_Buf,"\r\n1, CONNECT OK\r\n",uart0.Rx_Length)==0
                                                ||strncmp(uart0.Rx_Buf,"\r\n2, CONNECT OK\r\n",uart0.Rx_Length)==0)
                                        {
                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                        }
                                        else
                                        {
                                                if (strncmp(uart0.Rx_Buf,"\r\n+CMTI: \"SM\",",14)==0)
                                                {
                                                        STATE_MECHINE.m_Receive_MSG_Flag=RECEIVE_MSG;
                                                        STATE_MECHINE.m_MSG_Index=uart0.Rx_Buf[14]-0x30;
                                                        //STATE_MECHINE.AT_STA=AT_STATE_READ_MSG;
                                                }
                                        }
                                        break;
                                case MUTI_ALREADY_CONNECT:
                                        if (strncmp(uart0.Rx_Buf,"\r\n1, ALREADY CONNECT\r\n",uart0.Rx_Length)==0
                                                ||strncmp(uart0.Rx_Buf,"\r\n2, ALREADY CONNECT\r\n",uart0.Rx_Length)==0)
                                        {
                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                        }
                                        break;
                                case SEND_OK_Length:
                                        if (strncmp(uart0.Rx_Buf,"\r\nSEND OK\r\n",uart0.Rx_Length)==0)
                                        {
                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
                                        }
                                case SEND_FAIL_Length:
                                        if (strncmp(uart0.Rx_Buf,"\r\nSEND FAIL\r\n",uart0.Rx_Length)==0)
                                        {
                                                STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_FAIL;
                                        }
                                        break;
                                case RECEIVE_MSG_2:
                                        if (strncmp(uart0.Rx_Buf,"\r\n+CMTI: \"SM\",",14)==0)
                                        {
                                                STATE_MECHINE.m_Receive_MSG_Flag=RECEIVE_MSG;
                                                STATE_MECHINE.m_MSG_Index=(uart0.Rx_Buf[14]-0x30)*10+(uart0.Rx_Buf[15]-0x30);
                                                //STATE_MECHINE.AT_STA=AT_STATE_READ_MSG;
                                        }
                                        break;
                                default:
                                        if ((uart0.Rx_Length>40)&&(STATE_MECHINE.AT_STA_PRE==AT_STATE_READ_MSG))
                                        {
                                                unsigned char i;
                                                for(i=10;i<256;i++)
                                                {
                                                        if((uart0.Rx_Buf=='"')&&(uart0.Rx_Buf[i+1]=='+'))
                                                        {
                                                                memcpy(m_MSG_Phone_Num,uart0.Rx_Buf+i+4,11);
                                                                break;
                                                        }
                                                }
                                                //STATE_MECHINE.AT_STA=AT_STATE_HANDLE_MSG;
                                        }
                                        break;
                                }
                                uart0.Rx_Length=0;
                                //Timer1_A0_stop();
                        }
                }
        }
}

出0入0汤圆

7
 楼主| 发表于 2011-11-9 17:56:08 | 只看该作者
需要注意的是AT命令的超时处理;超时是wait_time;
// Timer1_A0 Interrupt Vector (TAIV) handler
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
        TA1CCR0 += 655;//20ms中断,用于GSM工作;
        if (STATE_MECHINE.Wait_Time!=0)
        {
                STATE_MECHINE.Wait_Time--;       
                if (STATE_MECHINE.Wait_Time==0)
                {
                        STATE_MECHINE.Time_Out_Flag=true;
                }
        }

}

/**********************************************************************
初始化定时器1,A1,开启中断,复位计数器,选择时钟源,不启动计数
参数:无
返回:无
**********************************************************************/
void Timer1_A0_init(void)
{
        TA1CTL = TASSEL_1 + MC__STOP + TACLR ;  // ACLK, contmode, clear TAR
        TA1CCTL0 &=~CCIFG;
        TA1CCTL0 |= CCIE;               // CCR1 toggle, interrupt enabled
        TA1CCR0 = 655;//CCR_CRN_Slot_ARRAY[0];
}

/**********************************************************************
启动定时器1,A1
参数:无
返回:无
**********************************************************************/
void Timer1_A0_start(void)
{
        TA1CTL |= MC__CONTINOUS;
}

/**********************************************************************
重新启动定时器1,A1
参数:无
返回:无
**********************************************************************/
void Timer1_A0_restart(void)
{
        unsigned int i=TA1R;
        TA1CCTL0 &=~CCIFG;
        TA1CCTL0 |= CCIE;               // CCR1 toggle, interrupt enabled
        TA1CCR0 = i+655;//CCR_CRN_Slot_ARRAY[0];
}

/**********************************************************************
停止定时器1,A1计数;
参数:无
返回:无
**********************************************************************/
void Timer1_A0_stop(void)
{
        //TA1CTL = TASSEL_1 + MC__STOP + TACLR ;  // ACLK, contmode, clear TAR
        TA1CCTL0 &= ~CCIE;               // CCR1 toggle, interrupt enabled
}

/**********************************************************************
清除计数器1,A1
参数:无
返回:无
**********************************************************************/
void Timer1_A0_clear(void)
{
        TA1R=0;  // ACLK, contmode, clear TAR
}

出0入0汤圆

8
 楼主| 发表于 2011-11-9 17:57:05 | 只看该作者
串口初始化;波特率19200
void uart_init(void)
{
        PMAPPWD = 0x02D52;                        // Get write-access to port mapping regs  
        P1MAP5 = PM_UCA0RXD;                      // Map UCA0RXD output to P1.5
        P1MAP6 = PM_UCA0TXD;                      // Map UCA0TXD output to P1.6
        PMAPPWD = 0;                              // Lock port mapping registers  
        P1SEL |= BIT5 + BIT6;                     // Select P1.5 & P1.6 to UART function

        UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
        UCA0CTL1 |=  UCSSEL_2;//UCSSEL_1;//                    // CLK = SMCLK
    UCA0BR0 = 0x80;//0x03;//                           // 32kHz/9600=3.41 (see User's Guide)
    UCA0BR1 = 0x02;//0x00;                           //
    UCA0MCTL = 0x00;//UCBRS_3+UCBRF_0;// 0xda;//              // Modulation UCBRSx=3, UCBRFx=0
        UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
        UCA0IE |= UCTXIE + UCRXIE;                // Enable USCI_A0 TX/RX interrupt
        UCA0IFG &= ~(UCTXIFG + UCRXIFG);          // Enable USCI_A0 TX/RX interrupt
}

出0入0汤圆

9
 楼主| 发表于 2011-11-9 18:00:03 | 只看该作者
还有一个特别注意的地方:电路中430的TXD与GSM——RXD有一330的电阻,经过测试330欧姆的电阻会导致进入GSM_RXD的数据成乱码。但是RXD和GSM_TXD没问题,所以要把那个330欧姆的电阻换成22的或者之间短路。
最后建议连接SIM900 RI、工作STA、CTS管脚

出0入0汤圆

10
 楼主| 发表于 2011-11-9 21:57:27 | 只看该作者
操作时只需要对以下变量赋值就行:
STATE_MECHINE.AT_STA_FAIL//=AT_STATE_CHECK_GSM;
STATE_MECHINE.AT_STA_SUCCESS//=AT_STATE_IPSTART_2;
STATE_MECHINE.Wait_Time//=Wait_Time_6second;
STATE_MECHINE.AT_STA_PRE//=STATE_MECHINE.AT_STA;
STATE_MECHINE.AT_STA//=AT_STATE_WAITTIME;

还有串口中断:
void uart_send_byte(unsigned char *buf,unsigned char length)
{
        uart0.Tx_Length=length;
        uart0.Tx_Pos=0;
        UCA0TXBUF=*buf;
}

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
    switch(__even_in_range(UCA0IV,4))
        {
                case 0: break;                          // Vector 0 - no interrupt
                case 2:                                 // Vector 2 - RXIFG
                uart0.Rx_Buf[uart0.Rx_Length] = UCA0RXBUF;                    // RXBUF1 to TXBUF1
                uart0.Rx_Length++;
                Uart_Handle();
                break;
                case 4:// Vector 4 - TXIFG
                if(uart0.Tx_Length)
                {
                        uart0.Tx_Pos++;
                        if(uart0.Tx_Pos<uart0.Tx_Length)
                                UCA0TXBUF = uart0.Tx_Buf[uart0.Tx_Pos];
                }
                uart0.Rx_Length=0;
                break;
                default: break;
        }
}

出0入0汤圆

11
发表于 2011-12-4 15:44:53 | 只看该作者
mark

出0入0汤圆

12
发表于 2012-2-20 23:16:51 | 只看该作者
mark

出0入0汤圆

13
发表于 2012-2-20 23:29:47 | 只看该作者
mark

出0入0汤圆

14
发表于 2012-2-20 23:33:00 | 只看该作者
这个好好学习下。

出0入0汤圆

15
发表于 2012-2-21 10:47:37 | 只看该作者
ding
头像被屏蔽

出0入0汤圆

16
发表于 2012-2-27 08:56:23 | 只看该作者
mark

出0入0汤圆

17
发表于 2012-2-27 11:44:15 | 只看该作者
有没有汇编的资料啊

出0入147汤圆

18
发表于 2012-4-19 10:34:02 | 只看该作者
34071417 发表于 2011-11-9 17:56
需要注意的是AT命令的超时处理;超时是wait_time;
// Timer1_A0 Interrupt Vector (TAIV) handler
#pragma  ...

请问楼主这个超时标志位置位后是如何处理的?另外在网页上看代码实在费劲,能否打包一下传上来?
STATE_MECHINE.Time_Out_Flag=true;

出0入0汤圆

19
 楼主| 发表于 2012-4-19 17:34:15 | 只看该作者
dreampet 发表于 2012-4-19 10:34
请问楼主这个超时标志位置位后是如何处理的?另外在网页上看代码实在费劲,能否打包一下传上来?
STATE_M ...

waittime在一个20ms的定时中断中自减,如果等于0,表明time_out.。每次执行一次AT命令都将会对wait_time赋值

出0入0汤圆

20
发表于 2012-5-11 08:07:21 | 只看该作者
整成一个附件吧......

出0入0汤圆

21
发表于 2012-5-11 08:57:16 | 只看该作者
Mark   SIM900

出0入0汤圆

22
发表于 2012-5-11 09:02:58 | 只看该作者
Mark   SIM900

出0入0汤圆

23
发表于 2012-6-13 09:00:04 | 只看该作者
看一看,顶起

出0入0汤圆

24
发表于 2012-7-21 18:49:03 | 只看该作者
标记一下

出0入0汤圆

25
发表于 2012-8-3 18:59:53 | 只看该作者
好帖关注。

出0入0汤圆

26
发表于 2012-9-25 17:21:03 | 只看该作者
学习一下。

出0入0汤圆

27
发表于 2012-9-25 17:23:30 | 只看该作者
好贴~赞一个

出0入0汤圆

28
发表于 2012-9-25 17:26:59 | 只看该作者
mark收藏

出0入0汤圆

29
发表于 2012-9-26 13:39:35 | 只看该作者
收藏。。。。。。

出0入0汤圆

30
发表于 2012-9-28 12:18:59 | 只看该作者
mark一下~~

出0入0汤圆

31
发表于 2012-9-29 16:08:43 | 只看该作者
你好!我是个即将毕业的大四学生,最近在做毕业设计,因为用到了GSM,但是我觉得女孩子写程序真的挺难的,一直弄不出来,您能指导指导我吗?

出0入0汤圆

32
发表于 2012-9-29 17:54:54 | 只看该作者
你好!我是个即将毕业的大四学生,最近在做毕业设计,因为用到了GSM,但是我觉得女孩子写程序真的挺难的,一直弄不出来,您能指导指导我吗?


我可指点你一二

出0入0汤圆

33
发表于 2012-10-3 13:45:14 | 只看该作者
学习了,谢楼主分享

出0入0汤圆

34
发表于 2013-1-22 19:09:28 来自手机 | 只看该作者
不错,mark一下

出0入0汤圆

35
发表于 2013-3-27 09:16:33 | 只看该作者
mark,这个太棒了。

出0入0汤圆

36
发表于 2013-3-28 15:00:18 | 只看该作者
mark一下!

出1070入962汤圆

37
发表于 2013-3-28 15:15:53 | 只看该作者
老帖又翻上来了,状态机不错,只是那个接收GSM模块返回信息的串口中断函数好恐怖!


这是在stm32上实现的GPRS DTU接收GSM模块返回信息的串口中断函数
void USART2_IRQHandler(void)
{
        u8 data;
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
        {
                /* Read one byte from the receive data register */
                data = USART_ReceiveData(USART2);
                /* 如果收到0x0d,说明一行完整的AT指令返回已经在缓冲区中了,行计数器++*/
                if (data == 0x0d) recvlines++;  
                rx_buffer2[rx_wr_index2]=data;
                if (++rx_wr_index2 == RX_BUFFER_SIZE2) rx_wr_index2=0;
                if (++rx_counter2 == RX_BUFFER_SIZE2)
                {
                        rx_counter2=0;
                        rx_buffer_overflow2=1;
                }
        }
        if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET)
    {
        USART_ClearFlag(USART2,USART_FLAG_ORE);        //读SR
        USART_ReceiveData(USART2);                     //读DR
    }
}


出1070入962汤圆

38
发表于 2013-3-28 15:18:49 | 只看该作者
如果6楼贴的不是串口中断函数,就请无视第37楼吧,呵呵

出0入0汤圆

39
发表于 2013-3-28 15:31:53 | 只看该作者
Appcat 发表于 2013-3-28 15:18
如果6楼贴的不是串口中断函数,就请无视第37楼吧,呵呵

苹果猫请问,嵌入式系统中调用C标准库中的函数执行效率会不会不高啊?如printf  strcmp等函数,

楼主的6楼的代码跳转太多了,看晕了都

出1070入962汤圆

40
发表于 2013-3-28 15:39:10 | 只看该作者
使用了标准库里边的这些函数,单从执行效率来说确实是低了。但是看你什么平台,追求的是什么。89S51,那就追求执行效率吧,CM3内核,还是追求开发效率更靠谱些。

状态机的程序代码看起来非常晕的,但凡是状态机的开发,一定会有一张有限状态机图,真正有价值的就是这张图,读懂了这张图,源代码不看也罢。

出0入0汤圆

41
发表于 2013-4-9 17:51:03 | 只看该作者
Appcat 发表于 2013-3-28 15:15
老帖又翻上来了,状态机不错,只是那个接收GSM模块返回信息的串口中断函数好恐怖!

苹果猫,能给我看看你的sim900处理流程吗? 最近在搞这个,总是想不到好的处理方法。缓冲区的处理也不太明白。求大侠指教,

出1070入962汤圆

42
发表于 2013-4-9 20:08:12 | 只看该作者
我没用SIMCOM的产品,所以也无从帮你。

出0入0汤圆

43
发表于 2013-8-12 11:25:06 来自手机 | 只看该作者
mark……
顶一个…

出0入0汤圆

44
发表于 2013-8-12 11:31:53 | 只看该作者
不错  学习了

楼主搞水文产品,具体什么产品呢?

出0入0汤圆

45
发表于 2013-8-19 10:25:15 | 只看该作者
make gsm zhuangtaiji

出0入0汤圆

46
发表于 2013-8-19 18:26:09 | 只看该作者
膜拜啊,学习中

出0入0汤圆

47
发表于 2013-8-24 16:12:49 | 只看该作者
Appcat 发表于 2013-3-28 15:15
老帖又翻上来了,状态机不错,只是那个接收GSM模块返回信息的串口中断函数好恐怖!

这样处理的话,,判断AT响应岂不是很麻烦,,一行判断没有,,接一行。。而且还要copy,,reset数据。

出0入0汤圆

48
发表于 2013-8-26 11:27:29 | 只看该作者
这个要顶,在没有操作系统的情况下,这个办法是可行的。

出0入0汤圆

49
发表于 2014-3-29 11:40:23 | 只看该作者
fcmer 发表于 2013-8-26 11:27
这个要顶,在没有操作系统的情况下,这个办法是可行的。

那如果采用嵌入式操作系统的话,状态机也是最优选择吗?
在操作系统下,我的实现方式是:
串口接收中断每接收到1个字节,就入FIFO缓冲区,
然后一个定时器来判断一帧数据接收超时(取值80ms),超时则认为一帧数据接收完毕,则发送一个信号量,
子任务1在收到该信号量后,将FIFO缓冲区的该帧数据入modem接收消息队列,
而在子任务2中定期轮询该modem接收消息队列,有消息则取出并进行解析,判断是IP数据包,还是SMS数据,还是AT指令应答。
这种方式是不是效率太低了点儿?
用状态机,我觉得不同的modem型号,对应的AT指令也不同,每换一种modem,就得修改状态机,不够通用的感觉。
例如:
SIM900A在接收到IP数据时,数据头和实际的数据是一起发来的:IPD:....
而MG323在接收到IP数据时,只是给出一个提示:"\r\n^SISR: 0, 1\r\n"
真实的数据还需要我发送指令"AT^SISR=0,512"来读取,
两种modem,对应的读取方式就不同。

敬请指教!

出0入0汤圆

50
发表于 2014-4-10 15:14:43 | 只看该作者
有点儿晕晕的

出0入0汤圆

51
发表于 2014-4-10 16:03:43 | 只看该作者
谢谢楼主

出0入0汤圆

52
发表于 2014-4-10 16:11:43 | 只看该作者
mark,字数补丁

出0入0汤圆

53
发表于 2014-4-10 18:09:03 | 只看该作者
手机党马克下            

出0入0汤圆

54
发表于 2018-6-21 11:19:50 | 只看该作者
学习! 学习!

出0入0汤圆

55
发表于 2020-9-9 11:26:27 | 只看该作者

学习! 学习!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 00:44

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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