Založen: Sep 03, 2019 Příspěvky: 69 Bydliště: Karlovy Vary
Zaslal: ne květen 03 2020, 9:28 Předmět: UART s přerušením atmega8
Ahoj,
už nevím kudy kam, mám tu úplně triviální program pro příjem po UARTu a někde mám něco blbě.
Když mám verzi bez přerušení a volání rutiny pro výpis z UDR do registru provozuji v hlavní smyčce, vše funguje. Vlastně to čte UDR pořád za běhu programu hlavní smyčky.
ALE jak to udělám systémem přerušení, tj že při příjmu Rx vyvolám přerušení, které mě odkáže na výčet UDR do registru a zpět do hlavní smyčky, tak mi to přečte data jen jednou a při dalším příjmu dat to absolutně nic nedělá. Jako by se mi UDR nevyprázdnilo a tak nepřijme další hodnoty.
Už nevím co a jak, tak prosím o radu. Ti, co mne chtějí odkázat na datasheet, tak z toho jsem to prostě nepochopil, nejsem znalec AJ a google překladač to jako vždy kazí.
kód:
.NOLIST
.INCLUDE "m8def.inc"
.LIST
.def reg=R16
.def reg2=r17
.EQU DATAIND=DDRD
.EQU LEDD=DDRC
.EQU DATAIN=PORTD ;RX DATA
.EQU LED=PORTC ;PC0-PC4 LED
.cseg
.org $0
rjmp ini
.org $00b
rjmp USART_Receive
Ini: ldi reg, 0b00000000
out DATAIND, REG
ldi reg, 0b11111111
out LEDD, reg
out LED, reg
ldi reg, 0b00000000
out DATAIN, REG
ldi reg,LOW(RAMEND)
out SPL,reg
ldi reg,HIGH(RAMEND)
out SPH,reg
; Set baud rate
ldi reg, 51
ldi reg2, 0
out UBRRH, reg2
out UBRRL, reg
; Enable receiver and transmitter
ldi reg, (1<<RXEN)|(1<<RXCIE)
out UCSRB, reg
; Set frame format: 8data, 1stop bit
ldi reg, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
out UCSRC, reg
ldi reg, 0b00000000
out led, reg
rcall time2s
ldi reg, 0b11111111
out led, reg
sei
Založen: Jun 30, 2005 Příspěvky: 1571 Bydliště: Pardubický kraj
Zaslal: ne květen 03 2020, 10:36 Předmět:
Jak tak na to koukám, zatím si nepochopil princip přerušení. Na tvém místě bych si dopřát trošek luxusu, který nabízí jazyk C. Amega je na to uzpůsobená, najdeš na to více tutoriálů, zdarma kvalitní překladač atd...
Obsluha přerušení se nikdy neukončuje rjmp ale příkazem reti.
sbic/sbis (skip if bit in I/O register is cleared/set) skips the next instruction depending on the I/O bit's state. In the example above I added a relative jump (rjmp) to show you how you could use this instruction. In this case, the mcu will jump to bit_is_set if bit 7 of PortD is not cleared (->set) and proceed with the instruction following the relative jump if that bit is cleared.
Naposledy upravil Zmije dne ne květen 03 2020, 12:55, celkově upraveno 1 krát.
ldi reg,LOW(RAMEND)
out SPL,reg
ldi reg,HIGH(RAMEND)
out SPH,reg
; Set baud rate
ldi reg, 51
ldi reg2, 0
out UBRRH, reg2
out UBRRL, reg
; Enable receiver and transmitter
ldi reg, (1<<RXEN)|(1<<RXCIE)
out UCSRB, reg
; Set frame format: 8data, 1stop bit
ldi reg, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
out UCSRC, reg
ldi reg, 0b00000000
out led, reg
rcall time2s
ldi reg, 0b11111111
out led, reg
sei
;------------------- Hlavní smyčka ------------------------
je tam samozřejmě nesmyslné. V přerušení se žádné čekací cykly zásadně nedělají, princip přerušení je, že se automaticky vyvolá v okamžiku, kdy událost nastala, tak nemá smysl na ní čekat.
Stejně tak
kód:
.org $00b
rcall USART_Receive
rjmp start
je nesmysl, má tam být jen
kód:
.org $00b
rjmp USART_Receive
Procesor se instrukcí reti automaticky vrací na místo, kde k přerušení došlo, s tím rcall se pokaždé vrací na start, což je blbost. Že to teď jako fuguje, je jen proto, že to nic jiného než skákání na start stejně nedělá a že přetéká zásobník se asi taky nepozná.
ldi reg,LOW(RAMEND)
out SPL,reg
ldi reg,HIGH(RAMEND)
out SPH,reg
; Set baud rate
ldi reg, 51
ldi reg2, 0
out UBRRH, reg2
out UBRRL, reg
; Enable receiver and transmitter
ldi reg, (1<<RXEN)|(1<<RXCIE)
out UCSRB, reg
; Set frame format: 8data, 1stop bit
ldi reg, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
out UCSRC, reg
ldi reg, 0b00000000
out led, reg
rcall time2s
ldi reg, 0b11111111
out led, reg
sei
;------------------- Hlavní smyčka ------------------------
Založen: Sep 03, 2019 Příspěvky: 69 Bydliště: Karlovy Vary
Zaslal: po květen 04 2020, 19:03 Předmět:
Takhle to generuje delay loop generátor i s tím reti na konci. Co by se tedy mělo zlepšit? Stačí jen bodovitě vyjmenovat, nějak to snad dohledám. Tohle bylo jen pro pochopení uartu, takže nečekám, že to bude hned použitelné 😁
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.