|
|
  |
Обработка ответов от модема SIM900 |
|
|
|
Jan 24 2012, 09:31
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 3-06-06
Пользователь №: 17 742

|
Всем доброго времени суток!
Начал разбираться с модемом SIM900 и сейчас нахожусь на стадии написания кода для обмена данными. Интересует, как с технической точки зрения правильно организовать анализ данных, поступающих от модема.
Если бы работа с модемом велась только в формате запрос-ответ, проблем нет - отправил команду, подождал ответ, разобрал его и пошел дальше. Но часть команд приходит асинхронно (звонок, смс и т.п.). Получается, необходимо организовать непрерывный прием и разбор принимаемых данных?
Существует ли где-то перечень команд, которые модем может отправлять по собственной инициативе?
Или может быть их можно игнорировать, пользуясь только линией RI?
Как у вас организовано общение с модемом? Хотя бы в общих словах.
Спасибо!
--------------------
Good News Everyone!
|
|
|
|
|
Jan 24 2012, 11:12
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
Если же вы прямо в векторе приема по уарту будете проверять что приходит и парсить то грешно это.
сделал так: уарт складывает принимаемые данные в свой кольцевой буфер (Б1) Приложение, ответсвенное за модем, имеет собсвенный линейный буфер (Б2) и проверяет наличие данных в приемном буфере и забирает по одному. Как только поймали '\n' то обработка приема Б2 и указать что складывать данные в начале Б2.
по \n стоит парсер на флаги то есть:
if( memcmp( rx_buff, "OK\r\n", 4 ) == 0 ) { history_flag( mdm_tx_ok, set ); return; } if( memcmp( rx_buff, "ERROR\r\n", 6 ) == 0 ) { history_flag( mdm_tx_error, set ); return; } if( memcmp( rx_buff, "+CME ERROR:", 11 ) == 0 ) { history_flag( mdm_tx_error_cme, set ); return; } if( memcmp( rx_buff, "+CMS ERROR:", 11 ) == 0 ) { history_flag( mdm_tx_error_cms, set ); return; } if( memcmp( rx_buff, "#CGSN: ", 7 ) == 0 ) { history_flag( mdm_tx_cgsn_imei, set ); extract_add_func( mdm_tx_cgsn_imei ); return; } if( memcmp( rx_buff, "+CLIP:", 6 ) == 0 ) { history_flag( mdm_tx_clip, set ); extract_add_func( mdm_tx_clip ); return; } if( memcmp( rx_buff, "+CMTI:", 6 ) == 0 ) { history_flag( mdm_tx_cmti, set ); extract_add_func( mdm_tx_cmti ); return; }
флаги это биты в u32
и весь алгоритм тупо
if( retval == at_ok ) retval = at_send( SET_CMD_ECHO_MODE_EXEC_OFF, mdm_tx_ok, mdm_tx_error, 1000, 10, 1000 ); if( retval == at_ok ) retval = at_send( SET_FIXED_LOCAL_RATE_115200 ); if( retval == at_ok ) retval = at_send( SET_REPORT_MOBILE_ERROR ); if( retval == at_ok ) retval = at_send( SELECT_INTERFACE_STYLE );
всё что выше от что для симкома что для телита.
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
Jan 24 2012, 12:43
|
Знающий
   
Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954

|
Очень просто. Примерно так-же как описал megajohn только с маленькой поправкой. В потоке который читает порт обрабатываем только необходимые незапрашиваемые коды и стандартные ответы, для обработки ответов спецефических для консретной команды добавляем указатель на функцию обработчик. В итого получаем примерно так: Код void *p_data = NULL; void (*p_func)(char*, void*) = NULL; BOOL buffer[BUFFER_SIZE+1];
void Parcer(char *buff) { if(strcmp(buf, "OK")==0){....} else if(strcmp(buf, "ERROR")==0){....} else if(strncmp(buf, "+CME ERROR", 10)==0){....} ........................................................ else if(p_func)if(p_func(buf, p_data)) p_func = NULL;//Тут обрабатываем спецефические ответы }
BOOL csq_cb(char *buf, void *p) { int *res = (int*)p; if(strncmp(buf, "+CSQ", 4) {//Обрабатываем ответ +CSQ..... ..................... res=xxxx; return TRUE; } return FALSE; }
int GetCSQ() { int res = -1; p_data = &res; p_func = csq_cb; if(PutCommand("AT+CSQ", 1000)==OK_RES)//Отправляем команду AT+CSQ и ждем ответа OK или ERROR { p_func = NULL; return res; } p_func = NULL; return -1; }
|
|
|
|
|
Jan 25 2012, 06:11
|
Знающий
   
Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163

|
Цитата В итого получаем примерно так: А зачем так хитро делать? Почему бы +CSQ всё время не ловить?
|
|
|
|
|
Jan 25 2012, 14:36
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Romashki @ Jan 25 2012, 13:42)  Когда абонент отбил приходит 7\r\n или когда нет связи придет 3\r\n Как настраивали, что модуль даёт такие ответы? Цитата(Romashki @ Jan 25 2012, 13:42)  но вдруг это придет в тот момент когда МК будет давать другие запросы модулю (уровень сигнала, температуры и т.д.). Запрашивать самому нужные статусы, когда это нужно.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|