13.07.2017, 19:16
|
#31
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от AR_Favorit
|
Всю эту последовательность непрерывно повторяем в основном цикле.
|
Как бы не всегда такое возможно.
Посему, в прерывании полезно хотябы отслеживать символы \r и \n, как команды для последующего начала разбора строки. Это отнимает существенно меньше ресурсов. При этом, чтобы не потерять принятую строку, ее можно скопировать в отдельный буфер, там же, в прерывании.
И ничего страшного, если вы малость задержитесь в прерывании, ничего архиважного не пропустите
Последний раз редактировалось NewWriter; 13.07.2017 в 19:18.
|
|
|
|
13.07.2017, 19:38
|
#32
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,897
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от NewWriter
|
Как бы не всегда такое возможно.
Посему, в прерывании полезно хотябы отслеживать символы \r и \n, как команды для последующего начала разбора строки. Это отнимает существенно меньше ресурсов. При этом, чтобы не потерять принятую строку, ее можно скопировать в отдельный буфер, там же, в прерывании.
|
Такое тоже не всегда возможно, взять и во время выполнения критичной ко времени задачи прямо в прерывании бросить все и заняться парсингом строки, а если он громоздкий, а скорость обмена выставлена большая - еще и с риском пропустить следующий символ)))
И не вижу ничего полезного в выполнении ненужной работы в прерывании. Ресурсов отслеживание /r и /n в прерывании занимает ровно столько же, сколько и вне его (как я написал - \r отслеживается при выборке из кольцевого буфера, а \n вообще не нужен).
Если МК бывает занят так, что модем успевает забить до переполнения кольцевой буфер, надо использовать управление потоком, без вариантов.
А если МК только и занимается, что работой с модемом (думаю, у ТС именно это)), то любой вариант годен.
Вот так оно у меня в рабочем проекте (примененный модуль на SIM800L не имеет выведенных наружу ножек модема для управления потоком, зато дешевый))), сначала это:
Код:
|
if (u8_mode != MODE_WORK_ECONOM)
{
while ((__get_buffer_is_empty_flag)&&(u8_rx_counter › 0)) //
{
ch_tmp = getchar();
if (ch_tmp != '\n')
{
if ((ch_tmp == '›')&&(__get_wait_invitation_flag)) //
{
__set_gsm_answer_sms_invitation_flag;
__clear_wait_invitation_flag;
}
else if (ch_tmp == '\r')
{
if (u8_parse_wr_index)
{
__clear_buffer_is_empty_flag;
ch_parse_buffer[u8_parse_wr_index] = 0;
if (__get_sms_receiving_flag)
{
__set_sms_text_present_flag;
__clear_sms_receiving_flag;
}
else
{
__set_gsm_message_present_flag;
}
u8_parse_wr_index = 0;
}
}
else
{
if (u8_parse_wr_index ‹ (PARSE_BUFFER_SIZE-1)) ch_parse_buffer[u8_parse_wr_index++] = ch_tmp; else u8_parse_wr_index = 0;
}
}
} |
А затем вызов КА основной программы, которая ориентируется по выставленным этим участком флагам, и сама управляет им с помощью них.
|
|
|
|
13.07.2017, 19:41
|
#33
|
Модератор
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,260
Сказал спасибо: 11,170
Сказали Спасибо 3,860 раз(а) в 2,930 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Константы (как уже сказано было выше) стоит таки сделать константами.
Правильнее использовать для символьных строк ASCIIz нотацию (конец строки x00, как и принято в C).
Вариант с двумя буферами в прерывании конечно прожорливей в оперативной памяти, но проще в обработке. Содержимое записывается всегда в начало как минимум. Для выделения адреса использовать признак (индекс) буфера в списке адресов для загрузки указателя. Ну и вести признак наличия в буфере законченного сообщения при переключении.
Выкидывание CRLF просто экономит на памяти и обработке с использованием стандарта языка.
Обработка (даже пустая) всех сообщений - из разряда good practice в программировании. Иначе потом начнутся заморочки и вопросы отчего/почему, как следствие лени сегодня.
Собственно пока мы тут все ещё обсуждаем сферического коня, поскольку сам алгоритм обработки сильно зависит от ее цели (которая осталась за кадром).
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
|
|
|
|
13.07.2017, 19:45
|
#34
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
AR_Favorit, понял, спасибо. Всё очень доходчиво )) Буду кодить дальше и отлаживать.....
|
|
|
|
13.07.2017, 19:49
|
#35
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от AR_Favorit
|
бросить все и заняться парсингом строки
|
Нет, не полным парсингом, а только сравнением принятого символа на равенство \r или \n.
Ресурсов это занимает как раз таки меньше в прерывании, потому что нужно сравнить всего один байт, а не поочередно байты по всей длине строки. Вы же все равно в прерывании вручную записываете принятый символ в буфер, так что не о чем беспокоиться, одна операция не добавит беды. ..а если очень переживаете, сделайте ассемблерную вставку
И кстати, не помню сейчас на память, но по-моему, F030 умеет выставлять отдельный флаг прерывания при приеме определенного символа.
Последний раз редактировалось NewWriter; 13.07.2017 в 19:56.
|
|
|
|
13.07.2017, 20:01
|
#36
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,653
Сказал спасибо: 117
Сказали Спасибо 815 раз(а) в 592 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от NewWriter
|
Ресурсов это занимает как раз таки меньше в прерывании, потому что нужно сравнить всего один байт, а не поочередно байты по всей длине строки.
|
У F0 есть прерывание по приему определенного символа. Так что, при надежном приеме можно просто ожидать символа '\n', а в прерывании по его поступлению менять буферы приема и выставлять флаг готовности у заполненного буфера.
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
|
|
|
|
13.07.2017, 20:09
|
#37
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,897
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от NewWriter
|
Нет, не полным парсингом, а только сравнением принятого символа на равенство \r или \n.
Ресурсов это занимает как раз таки меньше в прерывании, потому что нужно сравнить всего один байт, а не поочередно байты по всей длине строки. Вы же все равно в прерывании вручную записываете принятый символ в буфер, так что не о чем беспокоиться, одна операция не добавит беды. ..а если очень переживаете, сделайте ассемблерную вставку
|
А беспокоиться не из-за проверки символа на равенство \r или \n, а из-за того, что по результату предлагается сразу же и заняться парсингом, который может съесть куда больше времени. А если этого не делать, то и проверять окончание строки в прерывании бессмысленно. Даже ее копирование вместо полного парсинга сразу бессмысленно, следующая строка придет и затрет имеющуюся там, укда мы скопировали.
Вариант Эдди - еще понятно.
Сообщение от NewWriter
|
И кстати, не помню сейчас на память, но по-моему, F030 умеет выставлять отдельный флаг прерывания при приеме определенного символа.
|
Вроде как F031 умеет, а 030 нет, Изирайдер, помнится, об это спотыкался.
В моем случае неважно, у меня вообще STM8L)
Последний раз редактировалось AR_Favorit; 13.07.2017 в 20:21.
|
|
|
|
13.07.2017, 20:15
|
#38
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,897
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от eddy
|
У F0 есть прерывание по приему определенного символа. Так что, при надежном приеме можно просто ожидать символа '\n', а в прерывании по его поступлению менять буферы приема и выставлять флаг готовности у заполненного буфера.
|
и чем сильнее может быть занят проц, тем больше иметь буферов, чтоб не случилось беды)
|
|
|
|
13.07.2017, 21:06
|
#39
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,653
Сказал спасибо: 117
Сказали Спасибо 815 раз(а) в 592 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от AR_Favorit
|
чтоб не случилось беды
|
Всегда есть какой-то предел, когда насрать, что пропустили часть данных.
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
|
|
|
|
13.07.2017, 21:55
|
#40
|
Вид на жительство
Регистрация: 10.06.2007
Сообщений: 429
Сказал спасибо: 34
Сказали Спасибо 51 раз(а) в 47 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
AR_Favorit, а вот я уже устал объяснять, что кольцевой буфер даёт больший запас(или, в худшем случае, такой же) чем два или более отдельных буфера того же суммарного размера. И что в прерывании, как правило, нет смысла что-либо парсить(по крайней мере при работе с модемом). И ещё - Ваши советы хороши(и сам так советовал, пока не надоело), но чтобы ими воспользоваться нужно писать всю программу в стиле автоматного программирования - без тупых ожиданий. А то какой-нибудь while("ждём второго пришествия какого-то флага в регистре IO") или delay("дохрена времени") запросто всё испортит, может даже в виде трудноуловимого гейзенбага. Думаю - не будет лишним об этом упомянуть.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 23:13.
|
|