Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 6 mar 2025, o 19:43


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 
Autor Wiadomość
PostNapisane: 3 kwi 2016, o 11:41 
Offline
Nowy

Dołączył(a): 13 kwi 2015
Posty: 8
Pomógł: 0

Witajcie, może mi ktoś podpowiedzieć co robię źle , że ten prosty program nie działa jak należy ?

Otóż mam pilota który nadaje RS-em wolniutko, zaledwie 300 bodów kilka kodów ASCII (zwykłe pojedyncze znaki). Tu wszystko działa, Hyper Terminal te znaki pięknie rozpoznaje i jest OK. Pilot nadaje dla pewności po trzykroć każdy znak. Czyli nadaje np. "AAA" lub "BBB". HyperTerminal bezbłędnie to wyświetla

No a w drugiej części projektu (inny kontroler , inna płyteczka, część odbiorcza) chcę te znaki odbierać i odpowiednio interpretować. Obie platformy na tym samym zegarze (1MHz internal co przy tych prędkościach transmisji jest w zupełności wystarczające), oba z tymi samymi kontrolerami (Atmega16). Ze względu na to że część odbiorcza będzie miała coś do roboty w pętli oczekiwania , odbieranie nadlatującego znaku z ASCII muszę mieć poprzez mechanizm przerwań , nadlatujący znak po odebraniu zgłasza przerwanie i ma nastąpić obsługa przerwania z prostym zainterpretowaniem co to za znak przybył. No niby zadanie proste ale mimo to nie chce mi to ruszyć , widać że kontroler włazi w przerwanie ale nie interpretuje mi niczego co do niego wysyłam, mimo już kilkukrotnych analizach inicjalizacji USART w części odbiorczej. Części nadawczej się nie czepiam , skoro nadaje i robi to dobrze.

Zerknijcie proszę w mój kod i podpowiedzcie mi czy ja już czegoś nie widzę czy co ?

Oto kod :

Inicjalizacja UART :

Kod:
void USART_Init(uint16_t baud)
{
   UBRRH = (uint8_t)(baud>>8);               /* Set baud rate */
   UBRRL = (uint8_t)baud;
   UCSRA = (1<<RXC);
   UCSRB = (1<<RXEN)|(1<<RXCIE);            //włącz odbiornik i zezwól na generowanie przerwania przy odbiorze danych
   UCSRC = (1<<URSEL)|(3<<UCSZ0);            //ustalenie ramki na 8 bitów danych, 1 bit stopu
}


Przykłądowa pętelka oczekiwania na znak:
Kod:
   USART_Init(300);                     //inicjalizacja USART
   sei();
for(;;)                                 //pętla nieskończona
{
   wdt_reset();                     //reset psa
//   odbierz_dane_NRF();                  //sprawdź nadchodzące dane z pilota - radiowo
//   zmierz_prad();                     //sprawdzaj prąd w obwodach silnika
   led1_toggle;
   _delay_ms(1000);
}


No i moja obsługa przerwania :
Kod:
ISR(USART_RXC_vect)
{
   cli();                              //zablokuj globalnie przerwania
   dane_RX = UDR;                        //przepisanie danych z bufora sprzętowego
   if (dane_RX=='A') {PORTC |= (AUX1)}
   if (dane_RX=='B') {PORTC |= (AUX2)}
   if (dane_RX=='C') {PORTC |= (AUX3)}
   USART_Flush();
   led2_toggle;
   sei();                              //odblokuj przerwania
}


Może dodam jeszcze na zakończenie że korzystając z Hyper Terminala nadaję te znaki z niego i też "kicha" , nic się nie dzieje prócz zasygnalizowania wejścia w przerwanie. Oscyloskop podłączony w linię RxD pokazuje że przebiegi ramki którą na nią wysyłam są jak najbardziej OK. No i zgłupiałem :D


PROSZĘ POPRAWIĆ WSTAWIANIE KODÓW NA FORUM --- INACZEJ POST ULEGNIE USUNIĘCIU !! --> SunRiver

topic14999.html




Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2016, o 12:25 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27361
Lokalizacja: Szczecin
Pomógł: 1042

Po pierwsze to widać, że kolega na chwilę obecną nie za bardzo albo nawet i bardzo bardzo nie rozumie jak w ogóle działają przerwania

1. po co blokujesz cli i odblokowujesz sei przerwania w przerwaniu ? sorki ale to nonsens - bo to jest robione automatycznie a ty nie wiedząc nawet, że przerwanie ma jeszcze swój kod w asemblerze zwany PROLOG i EPILOG - kompletnie to zaburzasz. Oczywiście nawet jak to usuniesz a trzeba usunąć to i tak twój program będzie tak samo "nie działał"

2. masz trzy wartunki IF w przerwaniu ... i co ? spodziewasz się, że dojdzie do momentu kiedy one się spełnią wszystkie ? nie wiem wprawdzie co ty wyprawiasz w przerwaniu funkcją USART_Flush() ale czuję , że tu po raz kolejny wyjmujesz sobie dywanik spod nóg i dziwisz się dlaczego się przewracasz.

3. na dodatek ten gigantyczny delay = 1000 ms !!! to już prawie samobójstwo przy odbiorze jakichś ramek danych

dlatego proponuję - przede wszystkim zastosuj bufor cykliczny do obsługi RS232 tak jak się należy i jak od wieków się robi.... Od tego trzeba zacząć i tego trzeba się nauczyć - bez tego .... hmmm nie podziałasz sobie z przyjemnością jeśli chodzi o komunikację RS232 - to będzie zwykle nieprzyjemne działanie bo za każdą ramką i każdą transmisją idąc tym tropem jaki przedstawiłeś - będziesz musiał OD NOWA pisać swój program, procedurę obsługi przerwania itp itd

podczas gdy się korzysta z bufora cyklicznego - to zawsze można polegać na niezawodnej komunikacji szczególnie ASCII

tu polecam gorąco ci książkę:
http://atnel.pl/mikrokontrolery-avr-jezyk-c.html

bo w niej jest to bardzo dobrze opisane

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2016, o 18:02 
Offline
Nowy

Dołączył(a): 13 kwi 2015
Posty: 8
Pomógł: 0

Widzę że pojechałeś po mnie jak po starej szkapie, ale:

1) Blokowanie przerwania w przerwaniu (testowo !) robiłem po to, że mam jeszcze kilka źródeł przerwań (int0, timer0) i podczas różnych prób chciałem i to wyeliminować (ewentualne zgłoszenie innego przerwania o wyższym priorytecie) podczas wykonywania przerwania z modułu USART. Po prostu test czy to jakieś inne mi zaburza czy nie. Że nonsens ? jak sytuacja jest dziwna to warto i tak spróbować. Ale faktycznie usuwam skoro uważasz że może to rodzić problem.

2) Kto Ci powiedział że ja się spodziewam aż się wszystkie spełnią ??? wysyłam jakiś znak ASCII (jak wspomniałem JEDEN przecież znak !!!) i chcę tymi if-ami spowodować JEDNO konkretne działanie na liniach portu - Przecież jak wyrażenie warunkowe if() nie będzie prawdą to kontroler nie zmieni stanu linii które w klamrach określam i rozpocznie realizację kolejnego rozkazu, tak? - w tym przypadku kolejnego wyrażenia warunkowego (czyli nastąpi sprawdzenie czy znak który nadbiegł i mam w zmiennej to drugi z listy spodziewanych itd). Co w tym złego ? generalnie chodzi mi o to że mają być powiedzmy 3 różne reakcje na 3 różne spodziewane znaki ASCII. Stąd przykładowe 3 if-y.

3) USART_Flush() - zapraszam do dokumetacji Atmegi 16 gdzie sami twórcy tego kontrolera polecają "płukanie bufora" po odczycie (strona 150) jeżeli transmisja była błędna. Jest to funkcja właściwie przeklejona z dokumentacji Atmela bo jest tam szybko i sensownie napisana. Więc grzecznie po odczycie "płukam" bufor jak sami sugerują. Co prawda jest to działanie sugerowane na okoliczność błędnych danych ale uważam że nie zaszkodzi i to zrobić PO odczycie, prawda ? Złośliwość z dywanikiem ciut tu chyba nie na miejscu...

4) Oczywiście że posiadam książkę i celowo nie chciałem robić bufora cyklicznego bo po co mi on jak sporadycznie mam w programie zareagować na dosłownie JEDEN znak ASCII? Nie piszcie że to jedyna opcja, bo to jest przerost formy nad treścią dla JEDNEGO znaku ASCII. Oczywiście spróbuję i to testowo ale chciałem tego finalnie uniknąć.

5) Petla z absurdalnym delayem - czy mnie oczy mylą czy tam w treści mojego zapytania jest dopisek że to przykładowa pętla oczekiwania ? Chciałem po prostu pokazać że póki co nic mi się tam specjalnie nie dzieje (nawet widać że w trakcie prób poblokowałem odczyt modułu radiowego i przetwarzanie ADC) a mimo to jest jakiś problem z interpretacją znaku który nadszedł. Ponieważ mam przerwaniowe sprawdzanie bufora to fakt wykonywania nawet tak długiego delaya w niczym (?) przecież nie przeszkadza.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2016, o 20:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Cytuj:
3) USART_Flush() - zapraszam do dokumetacji Atmegi 16 gdzie sami twórcy tego kontrolera polecają "płukanie bufora" po odczycie (strona 150) jeżeli transmisja była błędna. Jest to funkcja właściwie przeklejona z dokumentacji Atmela bo jest tam szybko i sensownie napisana. Więc grzecznie po odczycie "płukam" bufor jak sami sugerują. Co prawda jest to działanie sugerowane na okoliczność błędnych danych ale uważam że nie zaszkodzi i to zrobić PO odczycie, prawda ? Złośliwość z dywanikiem ciut tu chyba nie na miejscu...
Wykonujesz niekontrolowane czyszczenie odbieranych danych. Jest to procedura awaryjna w przypadku wystąpienia błędów oraz konieczności wyczyszczenia bufora. Jak to robisz cyklicznie, to nie dziw się, że masz problemy z odbiorem.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2016, o 20:24 
Offline
Nowy

Dołączył(a): 13 kwi 2015
Posty: 8
Pomógł: 0

Mógłbyś przybliżyć kwestie braku kontroli? Wszak robię to świadomie, funkcji nie wywołuje coś tam przypadkowo, wypełniam bufor po jego odczycie dopiero po sprawdzaniu co wpadło, nie rozumiem w czym problem? Atmel nie wspomina że jest to niedozwolone. Dlaczego uważasz że to może rodzić problem? Pytam z czystej ciekawości bo nie spotkałem się ze stanowiskiem żeby wpisanie np. zer w UDR w czymkolwiek przeszkadzało, oczywiście z zastrzeżeniem że robimy to już po odczycie danych których wyczekujemy...dane jak dane , rejestr przesuwny jak każdy inny. Raczej się nie pogniewa :) Nowe jak nadejdą to i tak nadpiszą tę pustkę...Procedurę wdrożyłem jako jeden z testów czy to rozwiązuje problem. Po jej wywaleniu także nie działa to tak jak wydawało by się że powinno :)

Ta funkcja ma dość proste działanie, zerknij proszę:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


natomiast tak jak powyżej - i bez niej problem istnieje jak istniał.



Ostatnio edytowano 3 kwi 2016, o 20:46 przez protech.bielsko, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2016, o 20:45 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Nie mówię że ona powoduje Twoje problemy, ale jest to proszenie się o problemy. Zwracamy Ci na to uwagę, bo nawet jak teraz kontrolujesz transmisję, to w przyszłych projektach tak nie będzie a tworzysz kod, który będzie powodował problemy.
Dlaczego inicjalizujesz RS232 tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2016, o 20:55 
Offline
Nowy

Dołączył(a): 13 kwi 2015
Posty: 8
Pomógł: 0

Inicjalizuję z podaniem prędkości, jako że mam tak napisaną funkcję (która oczekuje podania wartości liczbowej reprezentującej prędkość transmisji) :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 kwi 2016, o 22:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Ale do funkcji przekazujesz wartość UBRR a nie wymagany baudrate. Informacje jak przeliczyć baudrate na UBRR masz w datasheetach do procesora (są tam nawet tablice podające wartości dla typowych prędkości i częstotliwości taktowania).
Możesz też skorzystać z typowego źródła wiedzy - blogu Mirka (nie mówiąc już o BB) http://mirekk36.blogspot.com/2013/01/rs ... trick.html

--
Pozdrawiam,
Robert


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 kwi 2016, o 11:52 
Offline
Nowy

Dołączył(a): 13 kwi 2015
Posty: 8
Pomógł: 0

Dziękuję Panie Robercie, to ten błąd okazał się kluczowy - ja podawałem wartość liczbową prędkości a do tego wymagana jest nieco inna konstrukcja funkcji inicjalizującej moduł USART (p.Mirek podaje to w swojej książce). Moduł po prostu pracował ze złymi nastawami. Serdecznie dziękuję, to przeoczyłem. Teraz wszystko działa.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 5 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO