Hallo,
ich hab mit einem kleinen Projekt auf einem AT90S8515 angefangen. Das
Programm soll mehrere Drehgeber auswerten und die aktuelle Position über
den UART an den PC weiterreichen. Dazu arbeite ich mit 3
Interrupt-gesteuerten Routinen.
Die erste auf Timer0 Überlauf wertet die Drehgeber aus.
Die zweite auf Timer 1 Compare Match A soll die Daten regelmäßig in
einen Puffer schreiben
Die dritte soll bei UART Data Register Empty ausgelöst werden um das
nächste Byte aus dem Puffer zu senden.
Das ganze funktioniert auch wenn ich es im AVR-Studio im Simulator
laufen lasse.
Wenn ich es aber auf den Controller lade, dann wird nur die
Interruptroutine für Timer 1 aufgerufen.
Ich habe das Programm auf das Grundgerüst reduziert und im Controller
getestet. Immer noch das gleiche Problem.
Ich bedanke mich jetzt schon mal bei allen die mir weiterhelfen möchten.
:-)
MfG.
Carsten
1 | .include "8515def.inc"
|
2 |
|
3 | .def temp1 = r16
|
4 | .def temp2 = r17
|
5 |
|
6 | .equ F_CPU = 1843200
|
7 | .equ BAUD = 9600
|
8 | .equ TIMER1FREQ = 10
|
9 |
|
10 | .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1)
|
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 | ; Timer1MatchInterrupt Für 10 Hz mit clock/8 und match bei 23040
|
19 | .equ TIMER1MATCH = F_CPU / 8 / TIMER1FREQ
|
20 |
|
21 | ; Reset Handler
|
22 | .org 0x000
|
23 | rjmp main
|
24 | ; Timer0Interrupt
|
25 | .org OVF0addr
|
26 | rjmp timer0_handler
|
27 | .org OC1Aaddr
|
28 | rjmp timer1match_handler
|
29 | .org UDREaddr
|
30 | rjmp udre_handler
|
31 |
|
32 | .org $00d
|
33 | ;***********************************************************************
|
34 | ; Hauptprogramm
|
35 | main:
|
36 | ldi temp1, LOW(RAMEND)
|
37 | out SPL, temp1
|
38 | ldi temp1, HIGH(RAMEND)
|
39 | out SPH, temp1
|
40 |
|
41 | ;Timer 0 mit CK/8
|
42 | ;ldi temp1, 0b00000010 ;
|
43 | ldi temp1, 1 << CS01
|
44 | out TCCR0, temp1
|
45 |
|
46 | ; Timer 1 Konfigurieren
|
47 | ; CK/8 setzen
|
48 | ldi temp1, 1 << CS01
|
49 | ; Clear on Compare Match
|
50 | sbr temp1, 1 << CTC1
|
51 | out TCCR1B, temp1
|
52 | ; Compare Match A seten
|
53 | ldi temp1, Low(TIMER1MATCH)
|
54 | out OCR1AL, temp1
|
55 | ldi temp1, High(TIMER1MATCH)
|
56 | out OCR1AH, temp1
|
57 |
|
58 | ; TIMSK setzen damit Timer aktiv sind
|
59 | ; Timer 0 overflow aktivieren
|
60 | ldi temp1, 1 << TOIE0
|
61 | ; Timer 1 compare match a aktivieren
|
62 | sbr temp1, 1 << OCIE1A
|
63 | out TIMSK, temp1
|
64 |
|
65 | ;UART Konfigurieren
|
66 | ; Baudrate einstellen
|
67 | ldi temp1, UBRR_VAL
|
68 | out UBRR, temp1
|
69 | ; TX aktivieren
|
70 | sbi UCR, TXEN
|
71 |
|
72 | ; Zum test ob Interrupt ausgelöst wird
|
73 | sbi UCR, UDRIE
|
74 | ldi temp1, 'X'
|
75 | out UDR, temp1
|
76 |
|
77 | ; Interrupts allgemein aktivieren
|
78 | sei
|
79 |
|
80 | ; In einer Schleife prüfen, ob neue Werte übertragen werden müssen
|
81 | main_loop:
|
82 | rjmp main_loop
|
83 |
|
84 |
|
85 |
|
86 | ;***********************************************************************
|
87 | ; Handler für Timer0
|
88 | timer0_handler:
|
89 | ;verwendete Register sichern
|
90 | sbi PORTB, 0
|
91 | reti
|
92 |
|
93 | ;***********************************************************************
|
94 | ; Handler für Timer1Match
|
95 | timer1Match_handler:
|
96 | ;Wert von Drehgeber als Hexzahl in Puffer schreiben
|
97 | sbi PORTB, 1
|
98 | sbi UCR, UDRIE
|
99 | reti
|
100 |
|
101 | ;***********************************************************************
|
102 | ; Handler für UART Data Register Empty
|
103 | udre_handler:
|
104 | sbi PORTB, 2
|
105 | cbi UCR, UDRIE
|
106 | reti
|