von
Anfänger (Gast)
18.03.2008 13:15
Hi,
Ich habe mir den Code vom Tutorial übernommen und hab ihn nur für den
Atmega168 angepasst. Beim ersten Versuch, ohne den RX-ISR (also
Polling) und habe auch Daten empfangen und dann mit RX-ISR, leider ohne
erfolg. Ich weiss nicht mehr weiter, kann mir Jemand Helfen.
Chip:Atmega 168 (über STK500)
CLK:16MHz
Baud:9600
PS. Der angepasste Code 1
2 .include "m168def.inc"
3
4 .def temp_1 = R16
5
6 .equ F_CPU = 16000000 ; Systemtakt in Hz
7 .equ BAUD = 9600 ; Baudrate
8
9 ; Berechnungen
10 .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden
11 .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
12 .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille
13
14 .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
15 .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
16 .endif
17
18 .org 0x00
19 rjmp main
20
21 .org 0x0024 ; Interruptvektor für UART-Empfang
22 rjmp int_rxc
23
24 ; Hauptprogramm
25
26 main:
27
28 ; Stackpointer initialisieren
29
30 ldi temp_1, LOW(ramend)
31 out SPL, temp_1
32 ldi temp_1, HIGH(ramend)
33 out SPH, temp_1
34
35 ; Port D = Ausgang
36
37 ldi temp_1, 0xFF
38 out DDRD, temp_1
39
40 ; Baudrate einstellen
41
42 ldi temp_1, HIGH(UBRR_VAL)
43 ldi XH, HIGH(UBRR0H)
44 ldi XH, LOW(UBRR0H)
45 st X,temp_1 ; UBRR0H (0xC5)
46 ldi temp_1, LOW(UBRR_VAL)
47 st -X,temp_1 ; UBRR0L (0xC4)
48
49 ; Frame-Format: 8 Bit
50
51 ldi temp_1,(1<<UMSEL00)|(3<<UCSZ00)
52 ldi XH, HIGH(UCSR0C)
53 ldi XH, LOW(UCSR0C)
54 st X,temp_1
55
56 ldi temp_1, (1<<RXCIE0)|(1<<RXEN0)
57 ldi XH, HIGH(UCSR0B)
58 ldi XH, LOW(UCSR0B)
59 st X,temp_1
60
61 sei ; Interrupts global aktivieren
62
63 loop:
64
65 rjmp loop ; Endlosschleife
66
67 ; Interruptroutine: wird ausgeführt sobald ein Byte
68 ; über das UART empfangen wurde
69
70 int_rxc:
71 push temp_1
72
73 ldi XH, HIGH(UDR0)
74 ldi XH, LOW(UDR0)
75 ld temp_1, X
76
77 com temp_1 ;beim STK500 gehen die LED bei Low an
78 out PORTD, temp_1
79
80 pop temp_1
81 reti
von
ecslowhand (Gast)
18.03.2008 13:47
Einige Fehler:
>> rjmp int_rxc
nehme den JMP-Befehl: jmp int_rxc
UBRR_VAL ist ein 16-bit Wert, Du benutzt nur 8-Bit!!!
Zudem lädst Du nur das XH-Register und nicht das XL-Register!!!
>> ; Baudrate einstellen
>> ldi temp_1, HIGH(UBRR_VAL)
>> ldi XH, HIGH(UBRR0H)
>> ldi XH, LOW(UBRR0H)
>> st X,temp_1 ; UBRR0H (0xC5)
>> ldi temp_1, LOW(UBRR_VAL)
>> st -X,temp_1 ; UBRR0L (0xC4)
Warum benutzt Du das X-Register? Geht doch viel einfacher:
[asm]
ldi r16, LOW(UBRR_VAL) ; Baudrate berechnen..
ldi r17, HIGH(UBRR_VAL)
sts UBRR0L, r16 ; ...und setzen
sts UBRR0H, r17
[/asm]
von
ecslowhand (Gast)
18.03.2008 14:00
Eine komplette Beispielroutine für den MEGA168:
1 ; ---------------------
2 ; UART0 initialisieren (MEGA168)
3 ; ---------------------
4 USART_init:
5 ldi r16, LOW((clock/(16*baudrate))-1) ; Baudrate berechnen..
6 ldi r17, HIGH((clock/(16*baudrate))-1)
7 sts UBRR0L, r16 ; ...und setzen
8 sts UBRR0H, r17
9
10 lds r16, UCSR0B
11 sbr r16, (1<<RXCIE0)|(1<<RXEN0) ; RX-Interrupt disable, RX disable
12 sbr r16, (1<<TXEN0) ; TX enable
13 cbr r16, (1<<UCSZ02) ; 8 datenbits
14 sts UCSR0B, r16
15 lds r16, UCSR0C
16 cbr r16, (1<<UCPOL0) ; asyncron
17 cbr r16, (1<<UMSEL01)|(1<<UMSEL00)
18 cbr r16, (1<<UPM01)|(1<<UPM00) ; no parity
19 cbr r16, (1<<USBS0) ; 1 stopp-bit
20 cbr r16, (1<<UCSZ02) ; 8 datenbits
21 sbr r16, (1<<UCSZ01)|(1<<UCSZ00)
22 sts UCSR0C, r16
23 ret
LG EC
von
ecslowhand (Gast)
18.03.2008 14:02
Mist, immer wenn`s schnell gehen soll......
<>> sbr r16, (1<<RXCIE0)|(1<<RXEN0) ; RX-Interrupt disable, RX
disable
Muss natürlich heissen: 1 sbr r16, (1<<RXCIE0)|(1<<RXEN0) ; RX-Interrupt enable, RX enable
von
Anfänger (Gast)
18.03.2008 16:18
Hi,
es klapt :) und "sts" ist wirlich einfacher,
danke dir.
habe den Code mit rauf gepackt, wenn auch Andere mall ein änliches
Problem haben sollten.
1 .include "m168def.inc"
2
3 .def temp_1 = R16
4
5 .equ F_CPU = 16000000 ; Systemtakt in Hz
6 .equ BAUD = 9600 ; Baudrate
7
8 ; Berechnungen
9 .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden
10 .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
11 .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille
12
13 .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
14 .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
15 .endif
16
17 .org 0x00
18 rjmp main
19
20 .org 0x0024 ; Interruptvektor für UART-Empfang
21 jmp int_rxc
22
23 ; Hauptprogramm
24
25 main:
26
27 ; Stackpointer initialisieren
28
29 ldi temp_1, LOW(ramend)
30 out SPL, temp_1
31 ldi temp_1, HIGH(ramend)
32 out SPH, temp_1
33
34 ; Port C = Ausgang
35
36 ldi temp_1, 0xFF
37 out DDRC, temp_1
38 out PORTC, temp_1
39
40 rcall USART_init
41 sei ; Interrupts global aktivieren
42
43 loop:
44
45 rjmp loop ; Endlosschleife
46
47 ; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde
48 USART_init:
49 ldi r16, LOW(UBRR_VAL ) ; Baudrate berechnen..
50 ldi r17, HIGH(UBRR_VAL)
51 sts UBRR0L, r16 ; ...und setzen
52 sts UBRR0H, r17
53
54 lds r16, UCSR0B
55 sbr r16, (1<<RXCIE0)|(1<<RXEN0) ; RX-Interrupt enable, RX enable
56 sbr r16, (1<<TXEN0) ; TX enable
57 cbr r16, (1<<UCSZ02) ; 8 datenbits
58 sts UCSR0B, r16
59
60 lds r16, UCSR0C
61 cbr r16, (1<<UCPOL0) ; asyncron
62 cbr r16, (1<<UMSEL01)|(1<<UMSEL00)
63 cbr r16, (1<<UPM01)|(1<<UPM00) ; no parity
64 cbr r16, (1<<USBS0) ; 1 stopp-bit
65 sbr r16, (1<<UCSZ01)|(1<<UCSZ00)
66 sts UCSR0C, r16
67 ret
68
69 int_rxc:
70 push temp_1
71
72 lds temp_1, UDR0
73
74 com temp_1 ;beim STK500 gehen die LED bei Low an
75 out PORTC, temp_1
76
77 pop temp_1
78 reti
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.