USART, AVR och Mega88

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

USART, AVR och Mega88

Inlägg av Snouser »

Jag försöker lista ut genom exemplen i databladet hur man tar emot information på min uC. Så här säger bladet.

Kod: Markera allt

USART_Init: 
; Set baud rate 
out UBRRnH, r17 
out UBRRnL, r16 
; Enable receiver and transmitter 
ldi r16, (1<<RXENn)|(1<<TXENn) 
out UCSRnB,r16 
; Set frame format: 8data, 2stop bit 
ldi r16, (1<<USBSn)|(3<<UCSZn0) 
out UCSRnC,r16 
ret 

USART_Receive: 
; Wait for data to be received 
sbis UCSRnA, RXCn 
rjmp USART_Receive 
; Get and return received data from buffer 
in r16, UDRn 
ret 
Jag tror att ja förstår det mesta av koden, eller i alla fall principen av den.
Problemet är bara de att dom skriver UDRn (ett N på slutet). Ja gissar att den sista bokstaven ska bytas ut mot något. Frågan är bara vad, och fram för allt varför.

Skulle någon kunna förklara.
Ja försökte läsa mig till det, men efter 10 sidor gav ja upp...
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Inlägg av johano »

Säkert en siffra, 0 eller 1 eller så..

/johan
Användarvisningsbild
Stinrew
Inlägg: 954
Blev medlem: 20 augusti 2006, 03:14:41
Ort: Motala
Kontakt:

Inlägg av Stinrew »

Precis somjohanosäger så ska n bytas ut mot 0. Det beror på att i vissa AVR-kretsar finns det 2 st. UART, och då används 0/1 för att välja vilken av dom det gäller. I mega88 finns ju bara en UART, så alla 'n' ska i dessa sammanhang bytas ut mot '0'.
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Okej, då är min följdfråga; vad ska man med två stycken ingångar till? Jag menar man kan väll ändå bara ta emot en byte itaget så länge man inte kör multitask, eller?


Jag är bara lite nyfiken på hur det fungerar...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> , eller?

Fel. Varje USART fungerar självständigt.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Tja... kommunikation med en PC på den ena UART och kommunikation med andra enheter på den andra UART... eller GSM-modem eller Mätinsamling eller .... ja, vad man nu behöver.

Och det har INGET med multitask att göra.

Jag har tillverkad enheter som dels kommunicerar med PC samtidig som de insamlar data från en radar via UART och som medelst en 3'dje UART skickade ut debug-meddelanden, inget speciellt konstigt i det.
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Inlägg av Micke_s »

lite förtydlignade: Visst, du kan bara ladda och läsa av uart registrerna en i taget. Men hårdvaran kan skicka och ta emot seriella strömmar oberoende av varandra.
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Okej, tack för svaret.

Nästa fråga.

Hur ska jag ladda in boudrate värdet i UBRR0H och UBRR0L?

Jag har inte rikigt fattat de där med låga och högra register,

Är det meningen att jag ska ladda in ett värde i ett te.x Z register och sedan ladda in de högsta registerparet i UBRR0H och viseverse?

EDIT:

Enligt en annan bok jag har så räcker det att man laddar in "prescalervärdet" in i UBRR, i bokens fall (3,69Mhz 9600bps) så är det 23 som ska laddas in. Då borde man väll inte behöva ett register par för att ladda in de värdet...eller?

EDIT2:

Detta borde väll fungera?

Kod: Markera allt

ldi ZH, HIGH(129)
ldi ZL, LOW(129)

out UBRR0H, ZH
out UBRR0L, ZL
Jag får följande fel när jag kör koden:

C:\kod\kod.asm(74): error: Operand 1 out of range: 0xc5
Användarvisningsbild
Stinrew
Inlägg: 954
Blev medlem: 20 augusti 2006, 03:14:41
Ort: Motala
Kontakt:

Inlägg av Stinrew »

Låga och höga register används när man eventuellt hanterar tal större än 0-255, vilka är dom tal som kan beskrivas med unsigned char. Vi säger att du använder 20MHz kristall och vill ställa in en baudrate på 4800 Baud, vilket innebär att UBRR0 ska ges värdet 259. Det decimala värdet 259 kräver 9 bitar för att beskrivas. 259 -> 0b00000001.00000011 = 256 + 2 + 1 = 259. I det fallet ska UBRR0H laddas med 1 medans UBRR0L laddas med 3.

I ditt fall ska UBRR0H laddas med 0 och UBRR0L laddas med 23. Då dessa register vid power-up initeras till 0 behöver du givetvis inte skriva till UBRR0H, men det är snyggare/bättre/säkrare att skriva till samtliga register när du initierar USARTen. Det bör inte spela någon roll i vilken ordning du skriver till dessa register, då detta bör ske innan USART0 aktiveras.

Vet inte hur det fungerar i assembler, men i C så kan man förenkla och skriva:

Kod: Markera allt

UBRR0 = 259;
i stället för:

Kod: Markera allt

UBRR0H = 1;
UBRR0L = 3;

EDIT2-SVAR:

Du kan inte ladda in högre siffra än 15 i UBRR0H, kolla i databladet så får du se att dom 4 höga bitarna är reserverade.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

Ditt problem är inte att UBRR0H endast kan innehålla 0-15
Assemblern håller inte reda på detta och varnar ej
Däremot är adressen till UBRR0H utanför området man kan
nå med OUT instruktionen

Skriv istället
LDI ZH,HIGH(BAUD_NR)
STS UBRR0H,ZH


Swech
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Båda förslagen fungerade super!

Nu till nästa del..

Jag får precis samma fel längre ner i koden.

Operand 1 out of range: 0xc0

Kod: Markera allt

USART_Receive: 
; Wait for data to be received 
sbis UCSR0A, RXC0 
rjmp USART_Receive
Vilket är "sbis" raden.
Varför de tro?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Samma orsak kanske ? :roll:
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Innan så skulle jag väll lagra data.
Nu ska jag väll bara kolla om en bit är satt i SREG.
Jag kan inte se varför något värde skulle vara för stort.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Läste du inte vad Swech skrev ?

> Däremot är adressen till UBRR0H utanför området man kan
> nå med OUT instruktionen

Du kanske ska läsa på om SBIS ?
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg av Snouser »

Jaha, nu fattar jag.
Det går inte att komma åt de specifika registrera, det är därför felmeddelandet kommer upp.

Jag löste problemet så här.

Kod: Markera allt

lds   Temp, UCSR0A 
sbrs Temp , RXC0
Om någon råkar ut för samma problem så finns det en massa information det här:
http://www.avrfreaks.net/index.php?name ... ic&t=58721
Skriv svar