Začínáme s UARTEM - chybička v programu

Ahoj, tak jsem se zas pustil dál do studování AVR, tentokrát UART.
Zkompiloval jsem to, nalil do kontroléru, a jak jíinak, než katastrofa. V terminálu se zobrazuje všecko možný, jen ne to, co tam má být.
Předem díky, že se mi kouknete na zdroják. Popravdě netuším kde může být zrada, dokonce jsem to celé i odsimuloval, a zdálo se že to jede vpořádku.

[code]

			.NOLIST
			.INCLUDE "m8def.inc"
			.LIST

;******************************************************************************
; MUJ PRVNI TEST RS232
;
; Vyšle text “Hello world!”
;
; 115200-8N1
;
; Baudrate = 115200bps
; Xtal = 11.0592MHz
;
;

;******************************************************************************

			.equ	XTAL = 11059200
			.equ	BAUDRATE = 115200

			.equ	UBRR = XTAL/16/BAUDRATE-1





			.CSEG
			
			.ORG 0x000
			rjmp Start


			.ORG 0x030

Start: ldi R16, low(RAMEND) ;Nastaveni stacku
out SPL, R16
ldi R16, high(RAMEND)
out SPH, R16

			;INICIALIZACE UARTU 115200-8N1				

			ldi R16, 0b00100000			;U2X=0
			out UCSRA, R16

			ldi R16, 0b00001000 		;Transmitter enable
			out UCSRB, R16

			ldi R16, 0b10000110			;ASYNchronous mode, parity None, 1 stopbit, 8 databits, 
			out UCSRC, R16

			ldi R16, low(UBRR)
			out UBRRL, R16

			ldi R16, high(UBRR) | (1<<URSEL)
			out UBRRH, R16

			;ODESLANI "Hello world!"



			ldi R16, 'H'				;Vyšli znak "H"
			rcall UART_send

			ldi R16, 'e'				;Vyšli znak "e"
			rcall UART_send

			ldi R16, 'l'				;Vyšli znak "l"
			rcall UART_send

			ldi R16, 'l'				;Vyšli znak "l"
			rcall UART_send

			ldi R16, 'o'				;Vyšli znak "o"
			rcall UART_send

			ldi R16, ' '				;Vyšli znak " "
			rcall UART_send

			ldi R16, 'w'				;Vyšli znak "w"
			rcall UART_send

			ldi R16, 'o'				;Vyšli znak "o"
			rcall UART_send

			ldi R16, 'r'				;Vyšli znak "r"
			rcall UART_send

			ldi R16, 'l'				;Vyšli znak "l"
			rcall UART_send

			ldi R16, 'd'				;Vyšli znak "d"
			rcall UART_send

			ldi R16, '!'				;Vyšli znak "!"
			rcall UART_send

sem: rjmp sem ;Nekonečná smyčka

;Odešle znak po UARTU
UART_send: sbis UCSRA, UDRE ;Počkáme na prázdný UDR
rjmp UART_send
out UDR, R16
ret

[/code]w

po dlouhověkkém čučení a simulování, jsem přišel na to, že zrada je zde:

ldi R16, 0b10000110         ;ASYNchronous mode, parity None, 1 stopbit, 8 databits, 
            out UCSRC, R16 

            ldi R16, low(UBRR) 
            out UBRRL, R16 

            ldi R16, high(UBRR) | (1<<URSEL)  ;TADY!!!
            out UBRRH, R16

odstranění chyby ale nepomohlo
Pokud zapisuju s URSEL=1 nebo 0, je to jedno pokaždé zapíšu do obou registrů najednou (UBRRH i UCSRC)
Tim pádem mi někdo vysvětlete, jak se do těch registrů zapisuje, protože já to vůbec nechápu.
<<btw takhle se to chová v simulátoru

dík moc za trpělivost!

Tak a je to na světě. Chyba byla u mě (opraveno, funguje), bohužel chybu udělali i programátoři atmelu. Chyba je bohužel i v simulátoru. MYslíte, že by byl dobrý nápad jí oznámit?

“odstranění chyby ale nepomohlo” - nepomohlo leda tak v simulátoru. V reálu to po odstranění té blbé chyby funguje naprosto spolehlivě.

Takže upozornění pro ostatní: dávejte si v AVR studiu pozor, při simulování USARTU, jsou chybně interpretovány registry UCSRC a UBRRH

v asm nepisu, takze to lustit nebudu, ale v datasheetu jsou i vzory, nezkousels to podle nich?

USART_Init: ; Set baud rate out UBRRH, r17 out UBRRL, r16 ; Enable receiver and transmitter ldi r16, (1<<RXEN)|(1<<TXEN) out UCSRB,r16 ; Set frame format: 8data, 2stop bit ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0) out UCSRC,r16 ret

USART_Transmit: ; Wait for empty transmit buffer sbis UCSRA,UDRE rjmp USART_Transmit ; Put data (r16) into buffer, sends the data out UDR,r16 ret
Pristup do registru

... ; Set UBRRH to 2 ldi r16,0x02 out UBRRH,r16 ... ; Set the USBS and the UCSZ1 bit to one, and ; the remaining bits to zero. ldi r16,(1<<URSEL)|(1<<USBS)|(1<<UCSZ1) out UCSRC,r16 ...

btw: pro rychlost 115kb s krystalem 11MHz potrebujes do UBRR zapsat “5” (str. 161), tudiz si vystacis s UBRRL a o UBRRH se starat nemusis (po resetu jsou v nem nuly).
Jesli ti to vysila, ale prijimas nesmysly, mozna bys mohl zkusit snizit rychlost :wink: (jeste pro rychlost 4,8kb si vystacis s UBRRL - hodnota “143”)
Mimochodem v C pristup do registru resit nemusis :smiley:
PS: vse je z datasheetu megy8 (nevim, na cem jsi to psal).

JAK Nemusíš? Pokud vim, tak i V cčku se do regisrů (těch status/řídících) taky klasicky zapisuje. Jediný, co asi řešit nebudeš, je že nebudeš potřebovat rozdělovat UBRR na UBRRL a UBRRH, protože to za tebe udělá kompilátor. :slight_smile:

Jinak jak řikám, vyřešeno, Programátoři ATMELu se dopustily chyby. 8)

v simulatoru verze 1 uz jsme na nejaky chyby narazili… Trema tiny 25 ma problemy s citacem 1… Muzes zkusit verzi 2, jesli to tam nebude chodit (mega8 tam neni, nebo aspon u me ne, ale jsou tam jeji klony - napr. mega88).
Ohledne C - prave, nemusim to rozdelovat a ani se starat o ten bit, kterej rozlisuje, kam zapsat, proste napisu jmeno registru a C se postara, aby se to zapsalo tam kam ma.

No šlo o to, že já tenzpůsob jak to “rozdělit” na dva registry vymyslel během pár sekund, pak mi ale bylo divný, proč to nemaká (malé upsání, místo 0 jsem napsal 1), a pak k tomu ještě chyba v simu, aby to nebylo málo.

BTW lze nějak updatovat AVRstudio?

obcas nejakej update vydaj, ale od dubna nic, verze 4.14 build 589 ja stale posledni…

Jeste jsou nejake bety
atmel.no/beta_ware/
Ale nevim jestli je tam neco opravene, pouzivam posledni oficialni verzi. Kazdopadne ty chybky v simulatoru jsou nepříjemné, taky sem par hodin zabil nez sem se docetl ze nefungujici USI pro attiny2313 je znama chyba v simulatoru AVR Studia, dokonce je to i v helpu known issues, ale koho to napadne, clovek vetsinou hleda chybu nejdriv u sebe (vetsinou opravnene)

Ja zas pro jistotu po 4 hodinach hledani chyby zjistil, ze GCC neni schopny spravne prelozit program, ve kterym je globalni promenna typu enum… :unamused: Po vymene enum za cisla to chodi jak vitr, akorat zas musim po celym programu komentovat, co jsem to vlastne proved (u enumu je to pri spravnych nazvech jasny…)

enum my vysvětlovat nemusíš, vim co je to zač. Co myslíš tim “neumí přeložit správně” ??

Pri prekladu do bud nehlasi nic a nejde to, nebo to hodi hlasku typu “declared but not used” a podobny vychytavky… Jste vtipnejsi potom je, ze kdyz tu deklaraci zakomentuje, nahle si uvedomi, ze mu neco chybi a vyhlasi te, ze nemas promennou deklarovanou atd…
Abych nezapomel - tyka se to projektu z vice souboru, pri pouziti v jednom souboru to maka vpoho.

Je ty krystal bezpodmínečně nutný ? u asynchroního přenosu by to to interní mohl udržet ne ?

omg :unamused: asynchronní přenos je ten přewnos, kde se data přenáší bez jakékoliv podpory hodinovým signálem. Jak to chceš proboha udržet rádobypřesným RC oscilátorem, kterej běhá až plus mínus 100kHz? :smiley:
Synchronni by možná fungoval. Navíc frekvence interního není možná rozumě vydělit na standardní baudraty, i když není problém napsat aplikaci (i na komp) která pobere frekvenci BR libovolnou. I když zas nevim jako moc libovolně to půjde naprogramovat. 8)
Takže jo, Xtal je bezpodmínečně nutný. Pokud máš nějaký procík, kteý má separé vývody na xtal, (třeba mega32) je na palici, tam xtal nedávat :slight_smile: Třeba u mega8, kde ti kvůli xtaly zmizeji dva využitelný vývody, tak tam bych to pochopil. u mega32 ne.

Interní RC oscilátor lze nakalibrovat s chybou <1% a to na UART stačí (8b+1 start+1 stop). Krátší délka rámce umožňuji zvýšit toleranci frekvence.

Pro správnou funkce asynch. přenosu musí být časový rozdíl rámců (od spádové hrany startu k náběžné hraně stopu) u obou UARTů menší než polovina doby přenosu jednoho bitu.

No právě… 1%. Kvůli tomu mi komunikace cždycky chodila 5 minut, a pak o přestalo jít, protože se to začlo rozcházet. KDe byla chyba, nevím. Ale oscilátor byl interní, RC, na 1MHz.

To je predsa nezmysel, aby sa vplyvom rozidenia frekvencii padla komunikacia po 5 minutach prace s nou. To je uplny nezmysel.

Komunikacia sa zacina start bitom. Jedine kriterium je udrzat komunikaciu zosynchronizovanu po najblizsi stop bit. Novym start bitom sa vsetko zacina od znova.

Teda teoreticky, ak sa frekvencie dvoch mcu lisia o 2%, potom pri scanovani stop bitu sa ten prijimaci nestriafa o 20%, co je patina bitu. (1start,8data,1stop). Novym start bitom sa obe strany zosynchronizuju a vsetko zacina odznova. Je jedno, kolko ma sprava bajtov, vacsia chyba ako tych 20% v skenovani stop bitu nenastane. Nemoze tu kvoli tomu spadnut komunikacia po 5 minutach. Toto nemoze byt ten dovod.

No ale každopádně bych to rád trápil na rychlosti co možná nejvyšší takže si ten krystal pořídím.

co myslíš tou vyokou rychlostí? kolik kbps?
Dej k tomu AVR xal 16MHz, sice nejde ydělit na standardizované baudraty, ale vpohodě jde nakonfigorovat i případná aplikace na kompu, aby hltala data touhle rychlostí…
AVR e prý dají i přetaktovat, nevim ale o kolik. Víte někdo, na kolik MHz max. běží??

Aha tak se dívám sem myslel že specifikace končí na devatenácti tisících a ono to pokračuje mnohem dál potvůrka. :slight_smile:

No tak to vydá že vezmu krystal 7.3728 MHz a pustím to na modemových 56,7kbaud

konec na 19 kbit/s? :laughing: muzes ti to nastavit klidne na 2 Mbit/s, kdyz to budou umet obe komunikujici strany, bude to dostatecne blizko a pouzijes kabel odpovidajici kvality :wink: