ATNEL tech-forum https://forum.atnel.pl/ |
|
Atmega328 - Odbieranie danych przez UART https://forum.atnel.pl/topic18994.html |
Strona 1 z 1 |
Autor: | kamilo0 [ 14 sie 2017, o 16:54 ] |
Tytuł: | Atmega328 - Odbieranie danych przez UART |
Witam. Piszę sobie program do komunikacji z modułem sim800L. Chcę wysyłać do niego, a także odbierać z niego dane. Napisałem sobie już całą obsługę tego modułu, ale mam jeden problem. Komunikacja z modułem zwykle działa dobrze, ale od czasu do czasu podczas przesyłania danych ATMega resetuje się . Używam dosyć popularnej biblioteki uart dostępnej na tej stronie: http://homepage.hispeed.ch/peterfleury/avr-software.html Bibliotekę tą zmodyfikowałem dla własnych potrzeb tak, abym mógł odbierać całe stringi W pliku uart.c dopisałem sobie taką funkcję wzorując się na poradniku YT pana Mirka: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Zmienna ascii_line inkrementowana jest w przerwaniu od odbioru danych uarta, gdy odebrany znak = 13 (ENTER). W ten sposób funkcja uart_get_str jest informowana, że dostępna jest linijka do odebrania. Wydaje mi się, że funkja uart_get_str jest tutaj problemem, ponieważ gdy ją usunę i ręcznie wysyłam z komputera dane do mikrokontrolera, resetów nie ma. Gdy funkcja jest włączona, podczas wysłania większej ilości danych następuje reset. |
Autor: | andrews [ 14 sie 2017, o 17:53 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
Spróbowałbym przed instrukcją ascii_line--; wyłączyć przerwania instrukcją cli();, a po instrukcji ascii_line--; włączyć przerwania instrukcją sei(); |
Autor: | TomekTomek55 [ 14 sie 2017, o 21:14 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
Moja rada jest taka zrób sobie podsłuch taki to odbiera atmega poprzez terminal w kompie tzn. podlacz sie pod pin RX atmegi jakims konwerterem rs na usb i wyswietlaj co otrzymuje atmega. Moim zdaniem masz zle zbudowany program odbierajacy ale nie w tej czesci co przedstawiles tylko juz w tym gdzie rozpatrujesz odebrane linie. mam tu na mysli nadchodzacy ciag danych o zbyt wielkim rozmiarze w porownaniu do zadeklarownaj zmiennej. Powodje to nadpisywanie innych zmiennych z ramu i w konsekwencji reset przypadkowy. |
Autor: | andrews [ 15 sie 2017, o 08:54 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
TomekTomek55 napisał(a): Moim zdaniem masz zle zbudowany program odbierajacy ale nie w tej czesci co przedstawiles W tej części, którą autor przedstawił, też jest błąd mogący powodować nieporządane efekty. Polega on na braku atomowości dostępu do zmiennej globalnej ascii_line i pokazałem sposób, jak ten błąd naprawić. Nie wykluczam oczywiście błędów w innych miejscach programu i nie neguję całkowicie tego co napisałeś, jednak niezależnie od wszystkiego akurat w tym miejscu zmiana jest niezbędna, jeśli program ma pracować stabilnie.
|
Autor: | kamilo0 [ 15 sie 2017, o 10:52 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
@andrews A możesz powiedzieć, dlaczego przerwania z ascii_line mogą powodować problemy? |
Autor: | kamilo0 [ 15 sie 2017, o 14:45 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
Zmodyfikowałem sobie funkcję uart_get_str, tak aby niemożliwe było zapisanie do bufora wiecej bajtów niż posiada bufor UART (oraz mój bufor z odebraną linijką w programie). język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Teraz wygląda, że jest ok. Narazie nie zauważyłem resetów. Wie ktoś, dlaczego tak się działo? Przecież jeśli przerwanie inkrementowało zmienną ascii_line, to znaczy, że w buforze był znak Enter (13), a widocznie pętla while nie "zauważała" tego znaku i zapisywała więcej danych niż rozmiar mojego bufora. |
Autor: | andrews [ 15 sie 2017, o 14:58 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
Szczerze mówiąc chciałem tego uniknąć, bo to trochę pisania jest... Liczyłem, że po prostu spróbujesz czy to pomoże, nie wnikając w szczegóły. No ale spróbuję w miarę możliwości krótko. Zmienna globalna ascii_line jest modyfikowana zarówno w programie głównym, jak i w procedurze obsługi przerwania. Operacja ascii_line--; nie odbywa się w jednym takcie zegara, ponieważ jest zapisana w pamięci RAM, a nie mikrokontroler nie może wykonywać operacji bezpośrednio na komórkach pamięci. Wymagane więc jest:
Prawdopodobieństwo "trafienia" nie jest wprawdzie duże, ale jakieś jest, dlatego program może przez jakiś czas pozornie pracować prawidłowo, a czas ten będzie losowy, choć w pewnej mierze zależny np. od częstotliwości i długości przesyłanych pakietów danych (u Ciebie ciągów znaków oddzielonych znakiem '\r', jeśli dobrze rozumiem). Im więcej krótkich pakietów w jednostce czasu, tym ryzyko problemów będzie większe. EDIT: kamilo0 napisał(a): Bibliotekę tą zmodyfikowałem dla własnych potrzeb tak, abym mógł odbierać całe stringi ... Zmodyfikowałem sobie funkcję uart_get_str, tak aby niemożliwe było zapisanie do bufora wiecej bajtów niż posiada bufor UART. ... Teraz wygląda, że jest ok. Narazie nie zauważyłem resetów. Wie ktoś, dlaczego tak się działo? By można było odpowiedzieć na to pytanie musiałbyś pokazać więcej kodu, szczególnie tego dotyczącego obsługi buforów. Bardzo istotne jest np. to, co tak na prawdę zwraca funkcja uart_getc(), bo nie jestem pewien, czy Twoja pętla odczytu bufora działa prawidłowo. |
Autor: | andrews [ 15 sie 2017, o 18:34 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
roske napisał(a): Dlatego, że w tej bibliotece uart_getc, przy braku znaków do pobrania zwraca całkiem coś innego niż Ci się wydaje. Przepraszam, a skąd kolega wie, co zwraca funkcja uart_getc(), skoro "biblioteka" była modyfikowana. Poza tym, nawet jeśli autor wątku nie jest jakiś biegły w programowaniu i popełnia błędy, to komentarze czy sformułowania w stylu "recepta na uzyskanie pierwszorzędnej popeliny" nie są raczej na tym forum mile widziane. Wydaje mi się oczywiste, że na forum pytania zadają Ci, którzy wiedzą mniej. Ci, którzy wiedzą więcej, pomagają z zachowaniem kultury osobistej lub wcale. Błąd można równie dobrze wskazać, nie używając tego typu zwrotów. roske napisał(a): A nawet jak się ma o niej pojęcie to nadal jest to bzdura (nie będę tłumaczył dlaczego). A dlaczego nie będzie kolega tłumaczył? Ja na przykład chciałbym wiedzieć, bo w swojej nieświadomości kilka razy już popełniłem ten błąd (i jakoś nie przestały działać, a nawet działały lepiej czy też były bardziej zgodne z moimi oczekiwaniami). Aż tu nagle okazuje się, że to "bzdura"... |
Autor: | kamilo0 [ 17 sie 2017, o 16:49 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
Nie denerwujcie się tak Panowie. Nie każdy ma za sobą kilkanaście lat doświadczenia w programowaniu uC. Ja nie mam, więc zdarzają się czasem takie błędy. Ważne, że w jakiś sposób udało mi się osiągnąć to, na czym mi zależało, a że w nie do końca dobry sposób, dlatego zapytałem na forum Biblioteka nie jest modyfikowana, dołożyłem do niej tylko tą jedną flagę (ascii_line) w obsłudze przerwania, i dopisałem sobie tą funkcję do odbierania stringu. Dzięki za porady, w wolnym czasie je przetestuję i mam nadzieję, że problem już nie będzie występował. @andrews Dziękuję za dokładne wyjaśnienie problemu przerwań |
Autor: | andrews [ 17 sie 2017, o 17:08 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
kamilo0 napisał(a): Nie denerwujcie się tak Panowie. Tak to wyglądało? Zapewniam, że ja akurat jestem zupełnie spokojny. Chciałem tylko delikatnie zwrócić na coś uwagę. Nie miałem zamiaru być agresywny czy nieuprzejmy, ale wygląda na to, że chyba zostało to odebrane inaczej |
Autor: | SunRiver [ 17 sie 2017, o 19:15 ] |
Tytuł: | Re: Atmega328 - Odbieranie danych przez UART |
<proszę autora o umieszczenie kodów w znacznikach syntax> |
Strona 1 z 1 | Strefa czasowa: UTC + 1 |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |