13.07.2017, 17:51
|
|
Гражданин KAZUS.RU
Регистрация: 16.06.2005
Сообщений: 943
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от mike-y-k
|
Копирование может быть и не побайтным
|
Конечно. Но это сугубо "внутри" ядра процессора, на уровне ассемблера. Архитектуры-то разные, не во всех есть команды блочного копирования, не у всех есть дма, есть куча различных тонкостей. А вот на уровне С всё таки сводится к побайтному копированию. И когда тот же ГЦЦ портируют под новую архитектуру, никто не переписывает библиотеки под новое ядро ручками на асме.
|
|
|
|
13.07.2017, 17:51
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,503
Сказал спасибо: 401
Сказали Спасибо 2,217 раз(а) в 1,315 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Хех. Если для приема используете прерывания, то не парьтесь с повторным парсингом - сразу в прерывании и проверяйте принятый символ, только вручную, без встроенных функций, но по схожему принципу. Времени это занимает немного.
Отдельный парсинг целесообразен при приеме через ДМА или при очень высокой скорости относительно скорости МК (для чего опять же целесообразен ДМА), или когда у вас есть какая-то строка, фиг знает когда принятая, а разбирать ее начали только сейчас.
memcpy для этого не нужна. Надо через strstr.
Встроенная printf конечно весьма тяжела. Но зато работает с полным набором форматирования. Правда, именно printf сбрасывает результат в буфер stdout и это тянет за собой дофига сколько всякой фигни, не всегда нужной. Можно вместо нее использовать fprintf или sprintf совместно с функцией просмотра и вывода получившейся строки.
Либо, есть отдельная облегченная библиотека tiny printf, с урезанным форматированием и обработкой только целочисленных значений.
Вообще же, вместо (f,s,i)print не возбраняется использовать самописные функции вывода.
Последний раз редактировалось NewWriter; 13.07.2017 в 17:53.
|
|
|
|
13.07.2017, 17:54
|
|
Гражданин KAZUS.RU
Регистрация: 16.06.2005
Сообщений: 943
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от mike-y-k
|
А как реализованы функции в библиотеке - можно будет посмотреть или в отладчике или по дампу.
|
Так ты посмотришь конечный продукт работы компилятора. А исходники библиотек (речь про ГЦЦ) можно спокойно посмотреть - они открытые.
|
|
|
|
13.07.2017, 18:13
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Наверно я себе усложняю задачу как обычно... Мне нужно отправить команду в модуль, и получить от него ответ один из двух - шести возможных. Но помимо этого иногда еще приходят сообщения типа sms ready call ready типа такого... Я даташит читал но не доскнально. Вроде там есть команды о запросе статуса смс и звонков. Значит я просто получаю ответ из шести возможных, очищаю буфер весь, выполняю нужное действие и шлю след команду. И далее по кругу...? Наверно както так будет правильнее??? Зачем мне разбирать еще какието неожидаемые сообщения... Ну иногда проверять на RING и еще некоторые....
|
|
|
|
13.07.2017, 18:19
|
|
Модератор
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,246
Сказал спасибо: 11,165
Сказали Спасибо 3,854 раз(а) в 2,925 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Someone, исходники стандарта всегда стоит сравнить с конкретной реализацией.
Что там будет в объектном коде - лотерея.
Но это уже не совсем по теме .
miwutka, Правильнее таки обрабатывать (делать закладки на будущее) для всех вариантов. Некоторая избыточность кода, но потом будет проще, да и не залезать лишний раз в документацию (в комментариях все описать).
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
Последний раз редактировалось mike-y-k; 13.07.2017 в 18:24.
|
|
|
Сказали "Спасибо" mike-y-k
|
|
|
13.07.2017, 18:27
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от miwutka
|
да уж... прием данных и их расшифровка намного сложнее чем отправка ))
на команду ATE0 приходит то ОК то Call Ready SMS Ready.....
|
"Call Ready SMS Ready" (а перед ними еще строки "RDY", "CFUN:" с режимом, "CPIN:" с состоянием ввода ПИН) приходит не на АТЕ0, а само по себе в течение нескольких секунд при включении модема.
Причем приходят они только после того, как настроена скорость UART. По умолчанию стоит автоопределение скорости (модем ждет чего угодно, начинающегося на АТ и устанавливает скорость, на которой это пришло). Поэтому если вы включите модем, выждете секунд 5-10, и пошлете АТЕ0, получите ответ в виде двух строк ATE0 и ОК. Если включите и пошлете АТЕ0 сразу же после подачи питания, то ничего не получите. Если включите и пошлете АТЕ0 через секунду - получите остатки информационных сообщений модема, посылаемых им при включении.
Помимо АТЕ0 включите еще и ATV0 - вместо "ОК", "ERROR" и еще некоторых стандартных сообщений будет приходить одна цифра (ОК - "0", ERROR - "4), и между сообщениями будут только (CR), без (LF), проще осуществлять разбор пришедшего от модема в ответ на команду.
Имейте в виду, что модем вообще-то живет своей жизнью и в любой момент имеет полное право прислать строку, в том числе и когда вы ждете какого-то ответа на свою команду.
Изучайте подоскональнее даташит на модем и список его АТ-команд, всё это там есть.
Сделайте стандартный кольцевой буфер с указателями на записываемый и на считываемый символы. Заполняйте его в прерывании по приему символа по уарт (никакого приема с ДМА там вы на 030 не сделаете, не слушайте теоретиков). В основном цикле проверяйте его на появление непрочитанных символов и копируйте вновь поступившие (с инкрементом указателя на считываемый символ) в дополнительный буфер, пока не обнаружится конец строки. Получив в дополнительном буфере отдельную строку, парсите ее на предмет поиска совпадений с теми ответами модема, которые вам нужно обрабатывать.
Последний раз редактировалось AR_Favorit; 14.07.2017 в 09:05.
|
|
|
Сказали "Спасибо" AR_Favorit
|
|
|
13.07.2017, 18:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
AR_Favorit, значит как я и думал надо второй буффер.
PHP код:
|
char OK[]= "\x0D\x0A\x4F\x4B\x0D\x0A";//6 char SMS_OK[] = "\x0D\x0A\x2B\x43\x4D\x47\x53\x3A\x20\x31\x39\x37\x 0D\x0A\x0D\x0A\x4F\x4B\x0D\x0A"; char NET_STATUS_OK[]="\x0D\x0A\x2B\x43\x52\x45\x47\x3A\x20\x30\x2C\x31\x 0D\x0A\x0D\x0A\x4F\x4B\x0D\x0A";//20 char MODEM_STATUS_OK[]="\x0D\x0A\x2B\x43\x50\x41\x53\x3A\x20\x30\x0D\x0A\x 0D\x0A\x4F\x4B\x0D\x0A";//18 char MODEM_STATUS_RING[]="\x0D\x0A\x52\x49\x4E\x47\x0D\x0A\x0D\x0A\x2B\x43\x 4C\x49\x50\x3A\x20\x22\ x33\x37\x35\x32\x39\x31\x33\x32\x30\x33\x35\x39\x2 2\x2C\x31\x34\x35\x2C\ x2C\x2C\x22\x22\x2C\x30\x0D\x0A";//44 char PBREADY2[]= "x0D,x0A,x4F,x4B,x0D,x0A,x0D,x0A,x2B,x50,x42,x52,x4 5,x41"; char PBREADY[]= "x0D,x0A,x2B,x50,x42,x52,x45,x41,x44,x59,x0D,x0A,";//можно так char ATE0_OK[]= "\x0D\x0A\x41\x54\x45\x30\x0D\x0D\x0A\x4F\x4B\x0D\x 0A";//или так char smsPhoneOK[]="\x0D\x0A\x3E\x20";//4"..›" номер телефона отправлен можно отправлять текст смс char smsTextOk[]="\x0D\x0A\x2B\x43\x4D\x47\x53\x3A\x20\x31\x39\x37\x 0D\x0A\x0D\x0A\x4F\x4B\x0D\x0A";//20 //номер техт смс отправлен пошла отправка смс "..+CMGS: 197....OK.."
|
Ответы начинаются с \x0D\x0A и ими заканчиваются.Значит мне нужно в прерывании обнаружить эти два символа как начало посылки, потом начать копировать во второй буфер сам ответ "полезный" и потом если обнаружили опять эти два символа то значит прием ответа окончен и можно выполнить анализ принятого ответа?
|
|
|
|
13.07.2017, 18:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
ЗЫ отдельный буфер для разбираемой строки, разумеется, не обязателен (можно просто передавать функции, разбирающей строку, два указателя на кольцевой буфер - начало и конец разбираемой строки, "обрамленной" c обеих сторон парами символов (CR) (LF) при ATV1 или просто символами (CR) при ATV0, но использовать strstr и прочие стандартные строковые функции при этом уже не получится (им нужна строка, заканчивающаяся 0х00 - а при отдельном буфере мы, разумеется, сами запишем в него этот признак конца строки) и надо будет писать свои варианты этих функций. Просто с ним проще.
|
|
|
|
13.07.2017, 19:02
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от miwutka
|
Ответы начинаются с \x0D\x0A и ими заканчиваются.Значит мне нужно в прерывании обнаружить эти два символа как начало посылки, потом начать копировать во второй буфер сам ответ "полезный" и потом если обнаружили опять эти два символа то значит прием ответа окончен и можно выполнить анализ принятого ответа?
|
В прерывании ничего делать не надо, кроме как записать в кольцевой буфер принятый символ, инкрементировать указатель записи, проверить, не стал ли он равен указателю чтения (что означает, что буфер у нас переполнился) всё.
А вот в основной программе в постоянном цикле проверяем, равен ли указатель чтения указателю записи, если нет - значит у нас есть что-то новое принятое, читаем по указателю чтения символ, и делаем так:
если символ НЕ \x0D и НЕ \x0A - записываем его в текущую позицию дополнительного буфера и инкрементируем указатель этой самой позиции и указатель чтения кольцевого буфера;
- если символ \x0A - просто инкрементируем указатель чтения кольцевого буфера (игнорируем эти символы вообще, они нам не нужны, а при ATV0 их и не будет);
- если символ \x0D - смотрим, куда указывает указатель текущей позиции дополнительного буфера, если на начало (нулевую позицию), то есть, строка у нас только началась, опять же, просто инкрементируем указатель чтения кольцевого. В противном случае записываем в текущую позицию дополнительного буфера 0х00 (и у нас получается null-terminated строка), и отдаем дополнительный буфер функции, осуществляющей парсинг. По возврату из нее устанавливаем текущую позицию в ноль и продолжаем следить за появлением новых символов в кольцевом буфере.
Всю эту последовательность непрерывно повторяем в основном цикле.
Поскольку в дополнительном буфере у нас "чистые" строки без \x0D и \x0A, то и то, что мы ищем в нем, этих самых \x0D и \x0A содержать не должно, чтобы найти "ОК", именно "ОК" и ищем.
И еще - в вашем написании char OK[] и прочие массивы - все лежат в RAM. Объявляйте их как const.
Последний раз редактировалось AR_Favorit; 13.07.2017 в 19:05.
|
|
|
Сказали "Спасибо" AR_Favorit
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:55.
|
|