Skocz do zawartości

RS232 -USART - ATmega16


ciulany

Pomocna odpowiedź

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

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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...

Link do komentarza
Share on other sites

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"

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

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...

Link do komentarza
Share on other sites

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ć.

Link do komentarza
Share on other sites

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).

Link do komentarza
Share on other sites

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?

Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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?

Link do komentarza
Share on other sites

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;
Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.