Forum: Mikrocontroller und Digitale Elektronik AVR ATtiny2313 PORTD Ausgabe in ASM


von Thomas W. (wibwato)


Lesenswert?

Hallo,

in einer Timer Interrupt Service Routine möchte ich etwas an PortD[4..6] 
ausgeben. In AVR Studio 4.10 gehe ich im Einzelschrittbetrieb durch den 
entsprechenden Bereich und sehe mir das PORTD im I/O-Fenster an.

nach der out-Anweisung in der Sequenz
1
ldi     temp1, $F0
2
out     PORTD, temp1
3
ldi     ZL, LOW( Segment0 ) 
4
ldi     ZH, HIGH( Segment0 )
wird bei PORTD auch 0xF0 angezeigt. Nach dem nächsten "Step Into" steht 
PORTD  auf 0xD0 und PIND auf 0x70, nach einem weiteren "Step Into" 
wechselt PIND nach 0x50.
Mit dem Bit D5 passiert also irgend etwas, was nicht meiner Erwartung 
entspricht.
PortD wurde wie folgt "initialisiert":
1
ldi     temp, $F0 ;D4...D7 als Ausgabe
2
out     DDRD, temp

Kann mir bitte jemand gedanklich auf die Sprünge helfen? Was habe ich 
übersehen?
Recht herzlichen Dank im Voraus ;-)

Thomas

von Thomas W. (wibwato)


Lesenswert?

Hier scheint es sich doch nur um ein Simulationsproblem im AVRSudio zu 
handeln (als ich den Thread eröffnet hatte, funktionierte auch die 
dazugehörige Hardware nicht so richtig). Jetzt funzt aber die Hardware 
zufriedenstellend. Auf Port B, Bit 2 gibt es einen ähnlichen Effekt.

Hat da noch jemand eine Idee oder Erklärung dazu?

Danke!

von Abuze (Gast)


Lesenswert?

moin moin,
bloss mal überflogen und kurz angeregt:

Timer-Serviceroutine => Timer 0 verwendet ?
Vllt. läuft T0 im (für deine Anwendung) falschen Modus.
PD.5 ist Compare A für PWM Anwendungen auf T0, könnte also nen Wechsel 
erklären
--> Timer Init am besten mal posten

PortB2 ist lustigerweise Compare B dafür ..... scheint mir also ganz 
daran zu liegen.

wenn die Compares null sind, und der timer nen reset kriegt (fürs 
zeit-auszählen gibts auch nen ctc mode) gibts je nach config nen wechsel 
auf den beiden pins.

In diesem Sinne, Viel Erfolg !

von Thomas W. (wibwato)


Lesenswert?

Hallo Abuze,

recht herzlichen Dank für Deine Antwort. Über die alternativen 
Pinbelegungen habe ich auch nachgedacht, bin mir aber "keiner Schuld 
bewußt" ;-) Und wie gesagt, der Code und die Schaltung tun es ja jetzt.

Habe aber vorsichtshalber den gesammten Code mal kopiert:
1
;************************************************************************************
2
;* From www.mikrocontroller.net/articles/AVR-Tutorial
3
;* modified for Pollin AVR Board 
4
;* 16.10.2007 
5
;************************************************************************************
6
.include "tn2313def.inc"
7
8
.def temp  = r16
9
.def temp1 = r17
10
.def temp2 = r18
11
 
12
13
.def digit_index = r19
14
.def driver_index = r20
15
16
.org 0x0000
17
           rjmp    main                ; Reset Handler
18
.org OVF0addr
19
           rjmp    multiplex
20
 
21
;
22
;********************************************************************
23
; Die Multiplexfunktion
24
;
25
; Aufgabe dieser Funktion ist es, bei jedem Durchlauf eine andere Stelle
26
; der 7-Segmentanzeige zu aktivieren und das dort vorgesehene Muster
27
; auszugeben
28
; Die Funktion wird regelmässig in einem Timer Interrupt aufgerufen
29
;
30
multiplex: push    temp               
31
           in      temp, SREG
32
           push    temp
33
           push    ZL
34
           push    ZH
35
 
36
           ldi     temp, $ef           
37
           out     PORTD, temp
38
                                       
39
           ldi     ZL, LOW( Segment0 ) 
40
           ldi     ZH, HIGH( Segment0 )
41
           add     ZL, digit_index    
42
 
43
           ld      temp, Z             
44
           out     PORTB, temp     
45
46
           out     PORTD, driver_index 
47
  
48
           inc     digit_index
49
           lsl     driver_index  
50
  
51
           cpi     driver_index, $78
52
           brne    multi1
53
           ldi     digit_index, 0
54
           ldi     driver_index, $ef
55
56
multi1:    pop     ZH                  
57
           pop     ZL
58
           pop     temp
59
           out     SREG, temp
60
           pop     temp
61
           reti
62
63
;
64
;**************************************************************************
65
;
66
main:
67
           ldi     temp, RAMEND    ; Stackpointer initialisieren
68
           out     SPL, temp
69
70
           ldi     temp, $FF
71
           out     DDRB, temp
72
           out     PORTB, temp    ;alle bits inaktiv (high)
73
     
74
           ldi     temp, $F0    ;D4...D7 aus Ausgabe
75
           out     DDRD, temp
76
           out     PORTD, temp  
77
                
78
           ldi     driver_index , $ef 
79
           ldi     digit_index , 0   
80
81
           ldi     temp, ( 1 << CS01 ) | ( 1 << CS00 )
82
           out     TCCR0B, temp
83
 
84
           ldi     temp, 1 << TOIE0
85
           out     TIMSK, temp
86
 
87
           sei
88
 
89
               
90
loop:      ldi     temp,$c0
91
           sts     Segment0,temp
92
           ldi     temp,$f9
93
           sts     Segment1,temp
94
           ldi     temp,$a4
95
           sts     Segment2,temp
96
           rcall   wait
97
98
           ldi     temp,$b0
99
           sts     Segment0,temp
100
           ldi     temp,$99
101
           sts     Segment1,temp
102
           ldi     temp,$92
103
           sts     Segment2,temp
104
           rcall   wait
105
106
           ldi     temp,$82
107
           sts     Segment0,temp
108
           ldi     temp,$f8
109
           sts     Segment1,temp
110
           ldi      temp,$80
111
           sts     Segment2,temp
112
           rcall   wait
113
114
           ldi     temp,$90
115
           sts     Segment0,temp
116
           ldi     temp,$88
117
           sts     Segment1,temp
118
           ldi     temp,$83
119
           sts     Segment2,temp
120
           rcall   wait
121
122
           ldi     temp,$c6
123
           sts     Segment0,temp
124
           ldi     temp,$a1
125
           sts     Segment1,temp
126
           ldi     temp,$86
127
           sts     Segment2,temp
128
           rcall   wait
129
      
130
           ldi     temp,$8e
131
           sts     Segment0,temp
132
           ldi     temp,$ff
133
           sts     Segment1,temp
134
           ldi     temp,$7f
135
           sts     Segment2,temp
136
           rcall   wait
137
138
           rjmp    loop
139
    
140
141
wait:      ldi     r21, 10      
142
wait0:     ldi     r22, 0       
143
wait1:     ldi     r23, 0       
144
wait2:     dec     r23
145
           brne    wait2
146
           dec     r22
147
           brne    wait1
148
           dec     r21
149
           brne    wait0
150
           ret
151
152
Codes:                               ; Die Codetabelle für die Ziffern 0 bis F
153
                                     ; sie regelt, welche Segmente für eine bestimmte
154
                                     ; Ziffer eingeschaltet werden müssen
155
                                    
156
  .db     0b11000000,0b11111001    ; c0  '0': a, b, c, d, e, f
157
                                   ; f9  '1': b, c
158
  .db     0b10100100,0b10110000    ; a4  '2': a, b, d, e, g
159
                                   ; b0  '3': a, b, c, d, g
160
  .db     0b10011001,0b10010010    ; 99  '4': b, c, f, g
161
                                   ; 92  '5': a, c, d, f, g
162
  .db     0b10000010,0b11111000    ; 82  '6': a, c, d, e, f, g
163
                                   ; f8  '7': a, b, c
164
  .db     0b10000000,0b10010000    ; 80  '8': a, b, c, d, e, f, g
165
                                   ; 90  '9': a, b, c, d, f, g
166
  .db     0b10001000,0b10000011    ; 88  'A': a, b, c, e, f, g
167
                                   ; 83  'b': c, d, e, f, g
168
  .db     0b11000110,0b10100001    ; c6  'C': a, d, e, f, 
169
                                   ; a1  'd': b, c, d, e, g 
170
  .db     0b10000110,0b10001110    ; 86  'E': a, d, e, f, g
171
                                   ; 8e  'F': a, e, f, g 
172
173
              .DSEG
174
Segment0:    .byte 1         ; Ausgabemuster für Segment 0
175
Segment1:    .byte 1         ; Ausgabemuster für Segment 1
176
Segment2:    .byte 1         ; Ausgabemuster für Segment 2

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.