CC430与GSM SIM900通讯的状态机
这是最近给水文项目做的其中一个状态机。这里只奉上SIM900通讯的状态机,CC430短距通讯采用时分,最大可以连接32路端机;
命令包括了AT、短信功能、GPRS功能;IP SEND DATA部分没有加入函数,有需要用的自己加入发送函数;
先上原理图 点击此处下载 ourdev_693544N18HMD.pdf(文件大小:125K) (原文件名:GSM.pdf) 贴上代码:
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); 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={"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;
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;
}
} 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= 串口处理函数
void Uart_Handle(void)
{
if (uart0.Rx_Length>=3)
{
if ((uart0.Rx_Buf=='>')&&(uart0.Rx_Buf==' '))
{
STATE_MECHINE.AT_STA=STATE_MECHINE.AT_STA_SUCCESS;
uart0.Rx_Length=0;
//Timer1_A0_stop();
return;
}
if((uart0.Rx_Buf=='#')&&(uart0.Rx_Buf=='('))
{
if((uart0.Rx_Buf==0x0d)&&(uart0.Rx_Buf==0x0a))
{
STATE_MECHINE.AT_STA=AT_STATE_HANDLE_MSG;
uart0.Rx_Length=0;
return;
}
}
if ((uart0.Rx_Buf==0x0d)&&(uart0.Rx_Buf==0x0a))
{
if ((uart0.Rx_Buf==0x0d)&&(uart0.Rx_Buf==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-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-0x30)*10+(uart0.Rx_Buf-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=='+'))
{
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();
}
}
}
} 需要注意的是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;
}
/**********************************************************************
启动定时器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;
}
/**********************************************************************
停止定时器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
} 串口初始化;波特率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
} 还有一个特别注意的地方:电路中430的TXD与GSM——RXD有一330的电阻,经过测试330欧姆的电阻会导致进入GSM_RXD的数据成乱码。但是RXD和GSM_TXD没问题,所以要把那个330欧姆的电阻换成22的或者之间短路。
最后建议连接SIM900 RI、工作STA、CTS管脚 操作时只需要对以下变量赋值就行:
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 = 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.Rx_Length=0;
break;
default: break;
}
} mark mark mark 这个好好学习下。 ding mark 有没有汇编的资料啊 34071417 发表于 2011-11-9 17:56 static/image/common/back.gif
需要注意的是AT命令的超时处理;超时是wait_time;
// Timer1_A0 Interrupt Vector (TAIV) handler
#pragma...
请问楼主这个超时标志位置位后是如何处理的?另外在网页上看代码实在费劲,能否打包一下传上来?
STATE_MECHINE.Time_Out_Flag=true;
dreampet 发表于 2012-4-19 10:34 static/image/common/back.gif
请问楼主这个超时标志位置位后是如何处理的?另外在网页上看代码实在费劲,能否打包一下传上来?
STATE_M ...
waittime在一个20ms的定时中断中自减,如果等于0,表明time_out.。每次执行一次AT命令都将会对wait_time赋值 整成一个附件吧...... Mark SIM900 Mark SIM900 看一看,顶起 标记一下 好帖关注。 学习一下。 好贴~赞一个 mark收藏 收藏。。。。。。 mark一下~~ 你好!我是个即将毕业的大四学生,最近在做毕业设计,因为用到了GSM,但是我觉得女孩子写程序真的挺难的,一直弄不出来,您能指导指导我吗? 你好!我是个即将毕业的大四学生,最近在做毕业设计,因为用到了GSM,但是我觉得女孩子写程序真的挺难的,一直弄不出来,您能指导指导我吗?
我可指点你一二 学习了,谢楼主分享 不错,mark一下 mark,这个太棒了。 mark一下! 老帖又翻上来了,状态机不错,只是那个接收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=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
}
}
如果6楼贴的不是串口中断函数,就请无视第37楼吧,呵呵 Appcat 发表于 2013-3-28 15:18 static/image/common/back.gif
如果6楼贴的不是串口中断函数,就请无视第37楼吧,呵呵
苹果猫请问,嵌入式系统中调用C标准库中的函数执行效率会不会不高啊?如printfstrcmp等函数,
楼主的6楼的代码跳转太多了,看晕了都 使用了标准库里边的这些函数,单从执行效率来说确实是低了。但是看你什么平台,追求的是什么。89S51,那就追求执行效率吧,CM3内核,还是追求开发效率更靠谱些。
状态机的程序代码看起来非常晕的,但凡是状态机的开发,一定会有一张有限状态机图,真正有价值的就是这张图,读懂了这张图,源代码不看也罢。 Appcat 发表于 2013-3-28 15:15 static/image/common/back.gif
老帖又翻上来了,状态机不错,只是那个接收GSM模块返回信息的串口中断函数好恐怖!
苹果猫,能给我看看你的sim900处理流程吗? 最近在搞这个,总是想不到好的处理方法。缓冲区的处理也不太明白。求大侠指教, 我没用SIMCOM的产品,所以也无从帮你。 mark……
顶一个… 不错学习了
楼主搞水文产品,具体什么产品呢? make gsm zhuangtaiji 膜拜啊,学习中 Appcat 发表于 2013-3-28 15:15 static/image/common/back.gif
老帖又翻上来了,状态机不错,只是那个接收GSM模块返回信息的串口中断函数好恐怖!
这样处理的话,,判断AT响应岂不是很麻烦,,一行判断没有,,接一行。。而且还要copy,,reset数据。 这个要顶,在没有操作系统的情况下,这个办法是可行的。 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,对应的读取方式就不同。
敬请指教!
有点儿晕晕的 谢谢楼主{:loveliness:} mark,字数补丁 手机党马克下 学习! 学习!
学习! 学习!{:smile:}
页:
[1]