ciulany Napisano Sierpień 26, 2011 Udostępnij Napisano Sierpień 26, 2011 Witam wszystkich, Problem jest następujący.... Połączenie zgodnie ze schematem poniżej Kod z przerwania rs: // USART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: On // USART Transmitter: On // USART Mode: Asynchronous // USART Baud Rate: 9600 UCSRA=0x00; UCSRB=0x98; // 98 UCSRC=0x86; UBRRH=0x00; UBRRL=0x33; interrupt [USART_RXC] void uart_rx_isr(void) { #asm("cli"); lcd_putsf("odbior"); delay_ms(1000); if(UDR==0xFF) { lcd_gotoxy(0,1); lcd_putsf("odbior dziala 255 "); delay_ms(1000); UDR=0x55; delay_ms(1000); liczPaczki=0; } #asm("sei"); } Fragmen kodu na początku jest automatycznie wygenerowany przez CodeVison, sprawdziłem i wg mnie jest ok kod do obsługi portu szeregowego jest w c# //------------------ byte[] nad = {0xFD}; serialPort1.Open(); serialPort1.Write(nad, 0, nad.Length); po chwili atmega powinna odesłać bajt więc if (serialPort1.ReadByte() == 255) { byte[] odb = new byte[serialPort1.BytesToRead]; serialPort1.Read(odb, 0, odb.Length); textBox1.Text = Convert.ToString(odb); //MessageBox.Show("Połączono poprawnie"); } else { byte[] odb = new byte[serialPort1.BytesToRead]; serialPort1.Read(odb, 0, odb.Length); textBox1.Text = Convert.ToString(odb); //MessageBox.Show("Połaczono - nie 255"); } serialPort1.Close(); //-------------------------- Efekt działanie tego procesu Przy wysyłaniu PC->uC przerwanie zawsze wykrywa ze dane == 255 tzn wchodzi to if w przerwaniu i odsyła wartość (UDR=0x55) przy czym na PC po wykonaniu serialPort.Read dostaje zawsze 120 lub 0 ( zero gdy np UDR=0x11) Proszę o pomoc, jakieś wskazówki bo siedze 3 dzień i powoli wymiękam 🙂 Z góry dzięki Cytuj Link do komentarza Share on other sites More sharing options...
GAndaLF Sierpień 26, 2011 Udostępnij Sierpień 26, 2011 Nie wiem czy to pomoże, ale rejestru UDR nie powinieneś używać do ifa. Zgodnie z datasheetem tylko raz można z niego odczytać daną a następnie jest ona tracona. Być może program po kompilacji próbuje użyć danej w tym rejestrze kilka razy i stąd błąd. Spróbuj dodać nową zmienną ośmiobitową, przechowywać tam odebraną wartość i dopiero ją dawać do ifa. Cytuj Link do komentarza Share on other sites More sharing options...
ciulany Sierpień 26, 2011 Autor tematu Udostępnij Sierpień 26, 2011 Tak ale w tym przypadku UDR jest potrzebny tylko raz, właśnie w if-ie, póżniej wartość odczytana nie jest już istotna. Wszystko oprócz komunikacji po rs-ie działa tzn lcd, sterowanie silnikow krokowych i inne elementy więc zakładam że błąd jest właśnie gdzieś w algorytmie. Może coś z f-cjami C# jest nie tak... Czy można bezpośrednio porównać w uC wartości np. 255 i 0xFF bo skoro przesyłam cały bajt to max moge mieć 255 i teraz czy zapis w uC if(..==255) bedzie prawidłowy czy może po kompilacji to 255 bedzie widziane jako np int... Cytuj Link do komentarza Share on other sites More sharing options...
bebek89 Sierpień 26, 2011 Udostępnij Sierpień 26, 2011 Witam to jest fragment programu wygenerowany przez avrwiz u mnie działa jak nalezy zegar 16MHz void USART0_Transmit(unsigned char data) { while (!(UCSRA & (1<<UDRE))) sleep(); UDR = data; } void USART0_TransmitString(char *data) { while (*data) USART0_Transmit(*data++); } unsigned char USART0_Receive(void) { while (!(UCSRA & (1<<RXC))) sleep(); return UDR; } void USART0_Init(void) { // USART0 settings: 9600 baud 8-n-1 // WARNING: real baud = 9615: err = 0,156249999999991% UBRRH = 0; UBRRL = 103; UCSRB = (1<<RXEN) | (1<<TXEN); UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0); } [ Dodano: 26-08-2011, 13:17 ] ps. a dla kompilatora to jest obojętne czy jest 255 czy 0xff ponieważ i tak to sobie zamieni gorzej jak nie bd przedrostka "0x" Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
ciulany Sierpień 26, 2011 Autor tematu Udostępnij Sierpień 26, 2011 sprawdze jak to jest na zmiennych char zamiast przesy.ac z c# zmienne bajtowe zobaczymy... I zrobie test na podanym kodzie, ciekawe czy codevision to przekompiluje jesli macie jeszcze jakies sugestie bede wdzieczny... Cytuj Link do komentarza Share on other sites More sharing options...
GAndaLF Sierpień 26, 2011 Udostępnij Sierpień 26, 2011 jeżeli patrzysz na kod w C to może używasz UDR tylko raz ale przecież w trakcie kompilacji jest to zamieniane na kod maszynowy gdzie być może rejestr UDR jest używany więcej razy a z poziomu kodu tego nie widać. Cytuj Link do komentarza Share on other sites More sharing options...
Harnas Sierpień 26, 2011 Udostępnij Sierpień 26, 2011 ps. a dla kompilatora to jest obojętne czy jest 255 czy 0xff ponieważ i tak to sobie zamieni gorzej jak nie bd przedrostka "0x" Będzie to tak samo widoczne dla kompilatora. Spróbuj zamienić przykładowo 255 na 256 i zobacz o ile zwiększy się kod wynikowy. Spróbuj zrobić tak jak napisał to kolega wyżej, przepisać UDR do jakiejś zmiennej, jednak wątpię że to było by przyczyną, bo kompilator pewnie pierw przepisze wartość rejestru UDR to jednego z 32 rejestrów ogólnego przeznaczenia (rdzeń AVR nie może bezpośrednio operować na pamięci ram, flash oraz dedykowanych rejestrach jak np: PORTD, DDRB, itp). Cytuj Link do komentarza Share on other sites More sharing options...
ciulany Sierpień 26, 2011 Autor tematu Udostępnij Sierpień 26, 2011 przypisanie do innej zmiennej nic nie dało dodatkowy spostrzeżenie.... jak z c# wysle serialport1.write(new byte[] {0x01 lub 0x10},0,1) to program w uC nie wchodzi to petli if jezeli wysle ...i tu nie pamietam jak mi wyszlo w testach od {0x02} lub {0x03} i cokolwiek wiekszego aż do 0xF0 czy 0x0F program w uC zawsze wchodzi do if (UDR==255) i wykonuje kod w if-ie może źle rozumiem działanie polecenia serialport.write() ale z tego co przeczytalem na msdn to powinno być ok układ testowałem na dwóch max232 na obu to samo do max-a mam 2 kondensatory 1uF na piny V+ i V- natomiast na VCC i GND mam podpiety bezposrednio zasilacz tzn stabilizator 7805 + kondensator 6800 uF elektrolit...moze to powoduje błędne działanie samego układu.. obniżylem tez predkosc do 960 bodów czyli teoretycznie błąd transmisji przy 8MHz wynosi 0% zrobilem test przy transmisji z bitem parzystości (even) wynik.... przy transmisji PC->uC to samo przy transmisji uC->PC w odpowiedzi dostaje 63 co o tym sądzicie? ps czy w rejestrze UDR zapisywany jest od razu cały bajt czy pojedyncze bity które trzeba czytać jakby w pętli bo sam juz zgłupiałem - analogicznie do tego, czy moge wpisać do UDR cały bajt (UDR=0xAA) czy musze przesuwać pojedyncze bity przy wysyłaniu? Cytuj Link do komentarza Share on other sites More sharing options...
GAndaLF Sierpień 27, 2011 Udostępnij Sierpień 27, 2011 Flaga przerwania przy odbiorze pojawia się kiedy w UDR znajdzie się cała odebrana dana, a przy wysyłaniu podajesz całą daną a interfejs UART wyśle ją samodzielnie Cytuj Link do komentarza Share on other sites More sharing options...
mleko Sierpień 27, 2011 Udostępnij Sierpień 27, 2011 UDR to cały bajt, zarówno przy odczycie jak i zapisie. [ Jakbys bawił się w przesuwanie bitowe to wysyłałbyś dane wielokrotnie, zapis do UDR oznacza wysłanie bajtu przez USART, odczyt odebranie, oczywyście wszystko w ramach dotępnego BR i bufora ] A spróbuj wyświetlać sobie na LCD wszystko co wysyłasz. I spróbuj też skorzystać z jakiegoś gotowego programu do obsługi COM ( ja lubie putty ) W ten sposób sprawdzisz czy transmisja działa poprawnie. Jak już będzie wszystko ok to potem sprawdzaj po kolei poszczególne elementy. Teraz dokładnie przeczytałem Twój post wyżej. Do MAX232 potrzebne są 4 a nie 2 kondensatory. 2 tak jak masz do V+ i V- ale jeszcze dwa są potrzebne na C1+ do C1- i C2+ i C2-, również 1uF. Kawałek z jednego z moich schematów Cytuj Link do komentarza Share on other sites More sharing options...
ciulany Sierpień 27, 2011 Autor tematu Udostępnij Sierpień 27, 2011 co do kondensatorow to dolutuje dwa brakujace i faktycznie najlepszym sposobem na sprawdzenie bedzie jakis gotowy program do obslugi com, wyeliminuje w ten sposob ewentualne bledy w c# co ciekawe max232 przesylal nawet dane bez podania zasilania na vcc i gnd (na v+ i v- bylo podlaczone) jak uda mi sie rozwiazac problem to napisze co bylo przyczyna a tymczasem sprobuje putty, niestety dopiero za kilka dni... Jesli macie jakies inne pomysly zapraszam do dyskusji, na forum zagladam codziennie Cytuj Link do komentarza Share on other sites More sharing options...
ciulany Wrzesień 4, 2011 Autor tematu Udostępnij Wrzesień 4, 2011 zrobiłem testy i poprawiłem układ wynik: po przesłaniu z atmegi do pc 0x07 dostaje 0xF8 00 używam Bray Terminal-a pierwsze bajt to jakby zagegowana 7-emka, a te dwa zera na końcu..?? nie wiem czy to jakieś zakłócenia czy co? jakies pomysły? Cytuj Link do komentarza Share on other sites More sharing options...
niciki Wrzesień 4, 2011 Udostępnij Wrzesień 4, 2011 nie znam tego Bray Terminal-a i dziwne są te 2 bajty przesłanych danych. Ja używam od lat programu "Terminal" napisanego przez Tadeusza Barańczyka. Program ten naprawdę polecam: http://www.stoeber.pl/files/File/TerminalSetup.zip Sprawdź dwa razy ustawienia trasmisji po stronie uK i PC. Nie zapomnij włączyć "echa" w Terminalu, aby widzieć cokolwiek co przychodzi. Powiedz mi jaki masz ustawiony zegar? (bo te Twoje "UBRRL=0x33;" wskazuje 8MHz, sprawdź to!) Co do inicjalizacji, ja u siebie inaczej to robię (czytelniej): #include <avr/io.h> #include <avr/interrupt.h> UBRRL = 51; // baud rate 9600 -> UBBR=51 (cristal 8MHz) // baud rate 9600 -> UBBR=103 (cristal 16MHz) UCSRB = _BV(RXCIE) // (USART) enable interrupt receive complete | _BV(RXEN) // enable transmitter | _BV(TXEN); // enable receiver UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // frame format: noparity, 8bit data, 1bit stop Wtedy, gdy chcę cokolwiek wysłać, to robię to tak: loop_until_bit_is_set(UCSRA, UDRE); // waiting for "ready" UDR = cokolwiek_tam_chcesz; Cytuj Link do komentarza Share on other sites More sharing options...
ciulany Wrzesień 5, 2011 Autor tematu Udostępnij Wrzesień 5, 2011 Tak zegar mam na 8 MHz, w sumie nie wiem jak go się ustawia bo CodeVisoio robi to samo, ja wpisuje wartość w usyawieniach projektu Źródło zegara określam fusebitami mianowicie CKSEL3..0 Ustawiam 0010 co wskazuje na wewnętrzny RC. Włąściwie kończą mi się pomysły już, po ograniczeniu predkosci transmisji do 1200 ( ustawienie UBRRH=0x01; UBRRL=0xA0; ) mam to samo co przy 9600. Przykładowo po przesłaniu 0xDD otrzymuje w terminalu 78 FE F8 Czy same połączenia w gnieździe rs-a maja znaczenie w tym przypadku? chodzi mi o zwory między pinami Cytuj Link do komentarza Share on other sites More sharing options...
niciki Wrzesień 5, 2011 Udostępnij Wrzesień 5, 2011 Napisz jak masz ustawione fusebity. Nie znam programu CodeVision i nie wiem jak ustawienia w nim wpływają na uK. Oczywiście połączenia w gnieździe rs-a maja znaczenie. Jakie zwory?? Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!