2014-07-23 37 views
1

我想從STM32VLDiscovery(STM32F100X4)的USART1中獲取字符串,並從USART1收到的字符串中寫入AT命令解析器。如何在C中創建AT命令解析器以從USART1獲取傳入的字符串?

以下是我開發的概念,但我不確定它是否正確。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#include "dosomethinga.h" 

void dosomethingB(); 
void GET_AT_COMMAND(char*); 
void takecommand(char *, char *); 
int quit; 


int main() 
{ char buff[15]; 
    char command = '\0'; 
    quit = 0; 

    while(!quit) 
    { 
     printf("Enter your command: "); 
     scanf("%s", &buff); 

     if (buff[0] == 'A' && buff[1] == 'T' && buff[2] == '+') 
     { 
      GET_AT_COMMAND(buff); 
     } 

    } 
} 

void dosomethingB() 
{ 
    printf("dosomethingB called \n"); 
} 

void GET_AT_COMMAND(char *text) 
{ 
    int command; 
    char temp[10] = ""; 

    /*if(text[3] == 'A') 
      command = 1; 

    else if(text[3] == 'B') 
     command = 2; 

    else if(text[3] == 'Z') 
     command = 3; 
    */ 

    takecommand(text,temp); 

    if (strcmp(temp, "CALLA") == 0) 
     command = 1; 

    if (strcmp(temp, "CALLB") == 0) 
     command = 2; 

    if (strcmp(temp, "Z") == 0) 
     command = 3; 

    switch(command) 
    { 
     case 1: 
      dosomethingA(); 
      break; 

     case 2: 
      printf("herehere.... \n"); 
      dosomethingB(); 
      break; 

     case 3: 
      printf("Exiting program.... \n"); 
      quit = 1; 
      break; 


     default: 
      printf("Nothing to do here \n"); 
    } 
} 

void takecommand(char *mycmd, char *hold) 
{ 
    int i; 
    for(i = 0; i < 10 ; i++) 
    { 
     hold[i] = mycmd[i+3]; 
    } 
} 

任何人都可以解釋我應該做的步驟嗎?謝謝。

+0

我不知道AT命令什麼,但我敢打賭,你可以刮掉一些代碼行將'switch'語句的'case'塊移動到指定的函數,並在'if-else'塊中調用它們。 'if(strcmp(temp,「CALLA」)== 0)dosomenthingA(); else if(...)dosomethingB(); ...'。 –

+0

也許更好的代碼審查?你有一個錯誤:'scanf(「%s」,&buff)'buff是一個數組,可以直接使用,你應該關心輸入長度:'scanf(「%。14s」,buff)'。 'takecommand'包含一個* magic *'10';如果你必須改變命令的大小,你將不得不在很多地方修復它。而strncpy或memcpy已經做好了。 (只有第一視線分析...) –

回答

2

基本上,您應該從輸入等待注意「AT」,並忽略它之前的任何內容。 例如,輸入「XYZATZ \ r」和「AaatZ \ r」應作爲「ATZ」命令處理。 'A'和'T'(以及所有其他命令字符)之間也可能存在短暫停頓,因爲人類可能會鍵入這些命令。

默認情況下,所有命令都以「\ r」結尾。

從ITU-T文檔查看更多關於AT命令的信息。例如從V.250標準。

可能有很多替代方法來實現它。最好的選擇取決於你的需求。如果你要實現移動終端的所有AT命令,那麼你應該花更多的時間用於解析器。如果你想爲一些命令做一些測試應用程序,那麼你的實現可以像你提供的那樣簡單。

+1

請注意,A + T字符必須是大寫或小寫(例如'ATZ','ATz','atZ'或'atz'都是有效的,但是'AtZ'例如不是)。 – hlovdal

1

我開發了這個AT命令解析器,這可以作爲參考。

當你從UART1數據只是調用這個方法at_wait_msg()解析AT消息

#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 

static const char *AT_HEADER = "AT"; 
static const char *AT_DEVICE_PROFILE = "DR"; 
static const char *AT_SET_DEVICE = "SD"; 

static const char AT_EOF = '\r'; 

typedef enum { 
    DeviceProfile, 
    SetDevice, 
    Error 
} AT_Msg_Type; 

typedef struct { 
    char header[3]; 
    char command[3]; 
    char data[128]; 
} AT_Msg_Data; 

static void at_wait_msg(char text); 
static void at_wait_msg_complete(char *text); 
static void at_parse_msg(AT_Msg_Data *data); 
static AT_Msg_Type at_check_format(AT_Msg_Data *data); 

static char _rx_data[512]; 
static uint16_t _rx_index = 0; 

int main() 
{ 
    //example data getting from UART1 
    char text[] = "ATDR\rATSD123456abchelloworld\r1123ATssa\r"; 

    for (int i = 0; i < strlen(text) + 1; i++) { 
     //to simulate getting data from UART1 byte per byte 
     at_wait_msg(text[i]); 
    } 

    return 0; 
} 

static void at_wait_msg(char text) 
{ 
    _rx_data[_rx_index++] = text; 

    if (text == AT_EOF) { 
     at_wait_msg_complete(_rx_data); 

     _rx_index = 0;  
    } 
} 

static void at_wait_msg_complete(char *text) 
{ 
    AT_Msg_Data data; 

    int result = sscanf_s(_rx_data, "%2s%2s%s\r", 
     data.header, sizeof(data.header), 
     data.command, sizeof(data.command), 
     data.data, sizeof(data.data)); 

    if (result >= 2) { 
     at_parse_msg(&data); 
    } 
} 

static void at_parse_msg(AT_Msg_Data *data) 
{ 
    AT_Msg_Type type = at_check_format(data); 

    switch (type) { 
    case DeviceProfile: 
     printf("device profile\r\n"); 
     break; 
    case SetDevice: 
     printf("settings %s\r\n", data->data); 
     break; 
    case Error: 
    default: 
     printf("Error\r\n"); 
     break; 
    } 
} 

static AT_Msg_Type at_check_format(AT_Msg_Data *data) 
{ 
    if (strcmp(data->header, AT_HEADER) != 0) { 
     return Error; 
    } 

    if (strcmp(data->command, AT_DEVICE_PROFILE) == 0) { 
     return DeviceProfile; 
    } 

    if (strcmp(data->command, AT_SET_DEVICE) == 0) { 
     return SetDevice; 
    } 

    return Error; 
} 
相關問題