15.07.2017, 17:30
|
#51
|
Вид на жительство
Регистрация: 10.06.2007
Сообщений: 429
Сказал спасибо: 34
Сказали Спасибо 51 раз(а) в 47 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
AR_Favorit, да, нагляднее, но больше возни с безопасной синхронизацией между обработчиком и программой, а пользы мало. Хотя... может у меня просто паранойя
Последний раз редактировалось H4LF; 15.07.2017 в 17:32.
|
|
|
|
16.07.2017, 16:58
|
#52
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Глянте плиз у кого есть чуток времени. Вот набросал инит первой команды. Шлет команду, в ответ получает ОК, проверяет и изменяет step_init на соотв номер.
это в основном цикле.
PHP код:
|
switch(step_init) { case 0: break; case 1: send_str("ATE0\r"); Delay_ms(10000); break; } if (Receive_C › 0) { if (step_init == 1) { temp = strncmp("\x41\x54\x45\x30\x0D", Receive_buf,5); //ATE0 иногда эта команда возвращается при подаче питания if (temp == 0) { step_init = 2; temp = strncmp(OK, Receive_buf+5,6); // OK if (temp == 0) { Receive_W -= 11; Receive_C -= 11; step_init = 3; }; } else { temp = strncmp(OK, Receive_buf,6); if (temp == 0) { Receive_W -= 6; Receive_C -= 6; step_init = 4; }; // OK } } // Receive_R++; // Receive_C--; }
|
это прерывание
PHP код:
|
void USART1_IRQHandler(void) { if((USART1-›ISR & USART_ISR_RXNE)!=0) {
Receive_buf[Receive_W] = USART1-›RDR;
Receive_W++; Receive_C++;
USART1-›CR1 |= USART_ISR_RXNE; } }
|
Первое что хочу - это распознавание ДТМФ и управление по ним.
Последний раз редактировалось miwutka; 16.07.2017 в 18:18.
|
|
|
|
16.07.2017, 22:09
|
#53
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
сделал конечный автомат через switch. В нем проверяю и на error и на ok. Пока прописываю инит. Потом буду отлаживать уже на входящие звонки, ДТМФ....
|
|
|
|
17.07.2017, 04:53
|
#54
|
Гражданин KAZUS.RU
Регистрация: 22.07.2007
Адрес: Владивосток
Сообщений: 984
Сказал спасибо: 435
Сказали Спасибо 375 раз(а) в 197 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Надо перед strncmp делать проверку длины входящей строки.
И проверку на переполнение буфера, раз он не кольцевой.
А раз буфер не кольцевой, то двух переменных не нужно.
Можно легко сделать кольцевой обращаясь к буферу
так Receive_buf[Receive_W & 0xF] (буфер на 16 байт).
Но тогда strncmp не подходит.
И я бы не суетился пока не получен ограничитель строки \n или \r.
А потом бы определил что получено. И записал код полученного
ответа в переменную. Ну типа 'OK' = 1, 'ERROR' = 2.
Ибо как сейчас - лишние сравнения:
buf=='E' -› buf != 'ERROR'
buf=='ER' -› buf != 'ERROR'
buf=='ERR' -› buf != 'ERROR'
итд
А уж если получено что-то неожиданное процесс ожидания знакомой строки
будет длиться до бесконечности.
buf=='васявасяERROR...' никогда не станет равен ничему знакомому.
И коды состояний лучше оформить в виде enum.
А вообще да, как-то так.
Последний раз редактировалось ampy; 17.07.2017 в 05:11.
|
|
|
|
17.07.2017, 10:53
|
#55
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от ampy
|
Надо перед strncmp делать проверку длины входящей строки.
|
это strlen для этого пойдет?
Сообщение от ampy
|
А раз буфер не кольцевой, то двух переменных не нужно.
Можно легко сделать кольцевой обращаясь к буферу
так Receive_buf[Receive_W & 0xF] (буфер на 16 байт).
Но тогда strncmp не подходит.
|
у меня буфер ограничен переменной char чтобы после 255 обнулялось. Я несообразил как сделать кольцевой буфер пока. Не старался...
Понял что можно поупрощать сравнения. Сделаю упрощения позже. Спасибо.
|
|
|
|
17.07.2017, 12:06
|
#56
|
Гражданин KAZUS.RU
Регистрация: 22.07.2007
Адрес: Владивосток
Сообщений: 984
Сказал спасибо: 435
Сказали Спасибо 375 раз(а) в 197 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от miwutka
|
это strlen для этого пойдет?
|
Не совсем, т.к. в буфере нет нуля в конце строки.
Длина принятой строки в буфере - Receive_C (или _W, не знаю)
Длина константной строки известна, но можно, наверное и strlen...
Не факт что компилятор ее не будет вычислять каждый раз заново.
Расходы...
Можно такую функцию определить
int strnmiw (const char * str, int n) {
if (Receive_C != n) return -1;
return strncmp(Receive_buf, str, n);
}
и пользоваться ей вместо strncmp.
Сообщение от miwutka
|
у меня буфер ограничен переменной char чтобы после 255 обнулялось. Я несообразил как сделать кольцевой буфер пока. Не старался...
|
Ну это тоже вариант... Но сложный.
|
|
|
|
17.07.2017, 13:25
|
#57
|
Вид на жительство
Регистрация: 10.06.2007
Сообщений: 429
Сказал спасибо: 34
Сказали Спасибо 51 раз(а) в 47 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
miwutka, отмечу только дикую вопиющесть(возможно): Delay_ms(10000), если это блокирующее ожидание, не нужен. Это что, вся программа (кроме прерываний) будет стоять и тупить целых 10 секунд?
Советую освоить программные таймеры, чтобы отмерять время без блокирования, мне лично понравилась такая реализация: http://we.easyelectronics.ru/Soft/sa...yy-taymer.html
В остальном согласен с ampy.
У Вас уже почти кольцевой буфер, если индекс uint8_t (беззнаковый).
http://microsin.net/programming/avr/ring-buffer.html
читать всё, в том числе UPD100920.
Библиотечные нельзя не только потому что там не нультерминированные строки(есть функции которые работают по длине), а потому что они не умеют работать с кольцевым буфером и будут выезжать за его границу (а не ходить по кольцу, как требуется).
|
|
|
|
17.07.2017, 15:07
|
#58
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
|
|
|
|
17.07.2017, 16:09
|
#59
|
Вид на жительство
Регистрация: 10.06.2007
Сообщений: 429
Сказал спасибо: 34
Сказали Спасибо 51 раз(а) в 47 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
miwutka, ну если просто для отладки(не окончательной, а для тестирования идей) и блокировка на это время не мешает(понимаете что делаете) то ничего страшного. А заблокировать выполнение программы можно и на Systick и на других аппаратных таймерах - доказано.
|
|
|
|
17.07.2017, 16:59
|
#60
|
Гражданин KAZUS.RU
Регистрация: 02.06.2003
Адрес: Челябинск
Сообщений: 545
Сказал спасибо: 10
Сказали Спасибо 341 раз(а) в 202 сообщении(ях)
|
Re: SIM800 + stm030 как правильно принимать по USART?
Сообщение от Someone
|
Конечно. Но это сугубо "внутри" ядра процессора, на уровне ассемблера. Архитектуры-то разные, не во всех есть команды блочного копирования, не у всех есть дма, есть куча различных тонкостей. А вот на уровне С всё таки сводится к побайтному копированию. И когда тот же ГЦЦ портируют под новую архитектуру, никто не переписывает библиотеки под новое ядро ручками на асме.
|
Не о том речь. 16-разрядный процессор может копировать не побайтно, а пословно, т.е. по 2 байта зараз. Но при этом нужно учитывать четность количества копируемых байт. Если число байт нечетно, то сначала копируется 1 байт, а все остальные копируются словами.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 16:42.
|
|