Как создать AT Commands Parser в C, чтобы получить входящую строку из USART1?

Вопрос: Я хочу получить строку из USART1 из STM32VLDiscovery (STM32F100X4) и написать AT Parser из строки, полученной из USART1. Ниже приведена концепция, которую я разработал, но я не уверен, правильна она или нет. #include #include #include #include "dosomethinga.h" void dosomethingB(); void GET_AT_COMMAND(char*); void takecommand(char *, char *); int quit; int main() {

Вопрос:

Я хочу получить строку из USART1 из STM32VLDiscovery (STM32F100X4) и написать AT Parser из строки, полученной из 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 = ‘’; 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]; } }

Может ли кто-нибудь объяснить шаги, которые я должен сделать? Благодарю.

Лучший ответ:

В основном вы должны ждать внимания “AT” от входа и игнорировать что-либо перед ним. Например, входы “XYZATZr” и “AaatZr” должны обрабатываться как команда “ATZ”. Также может быть короткая пауза между “A” и “T” (и всеми остальными символами команд), потому что человек может набирать эти команды.

По умолчанию все команды заканчиваются символом “ r”.

Подробнее о командах AT из документации ITU-T. Например, из стандарта V.250.

Вероятно, есть много альтернативных способов реализации этого. Лучшая альтернатива зависит от ваших потребностей. Если вы собираетесь внедрять все AT-команды мобильного терминала, вам следует потратить больше времени на парсер. Если вы хотите сделать несколько тестовых приложений для нескольких команд, ваша реализация может быть простой, как и ваша.

Ответ №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[] = «ATDRrATSD123456abchelloworldr1123ATssar»; 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%sr», 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 profilern»); break; case SetDevice: printf(«settings %srn», data->data); break; case Error: default: printf(«Errorrn»); 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; }

Оцените статью
Добавить комментарий