mikrocontroller.net

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


Autor: Thomas W. (wibwato)
Datum:

Bewertung
0 lesenswert
nicht 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
ldi     temp1, $F0
out     PORTD, temp1
ldi     ZL, LOW( Segment0 ) 
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":
ldi     temp, $F0 ;D4...D7 als Ausgabe
out     DDRD, temp

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

Thomas

Autor: Thomas W. (wibwato)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Abuze (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 !

Autor: Thomas W. (wibwato)
Datum:

Bewertung
0 lesenswert
nicht 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:
;************************************************************************************
;* From www.mikrocontroller.net/articles/AVR-Tutorial
;* modified for Pollin AVR Board 
;* 16.10.2007 
;************************************************************************************
.include "tn2313def.inc"

.def temp  = r16
.def temp1 = r17
.def temp2 = r18
 

.def digit_index = r19
.def driver_index = r20

.org 0x0000
           rjmp    main                ; Reset Handler
.org OVF0addr
           rjmp    multiplex
 
;
;********************************************************************
; Die Multiplexfunktion
;
; Aufgabe dieser Funktion ist es, bei jedem Durchlauf eine andere Stelle
; der 7-Segmentanzeige zu aktivieren und das dort vorgesehene Muster
; auszugeben
; Die Funktion wird regelmässig in einem Timer Interrupt aufgerufen
;
multiplex: push    temp               
           in      temp, SREG
           push    temp
           push    ZL
           push    ZH
 
           ldi     temp, $ef           
           out     PORTD, temp
                                       
           ldi     ZL, LOW( Segment0 ) 
           ldi     ZH, HIGH( Segment0 )
           add     ZL, digit_index    
 
           ld      temp, Z             
           out     PORTB, temp     

           out     PORTD, driver_index 
  
           inc     digit_index
           lsl     driver_index  
  
           cpi     driver_index, $78
           brne    multi1
           ldi     digit_index, 0
           ldi     driver_index, $ef

multi1:    pop     ZH                  
           pop     ZL
           pop     temp
           out     SREG, temp
           pop     temp
           reti

;
;**************************************************************************
;
main:
           ldi     temp, RAMEND    ; Stackpointer initialisieren
           out     SPL, temp

           ldi     temp, $FF
           out     DDRB, temp
           out     PORTB, temp    ;alle bits inaktiv (high)
     
           ldi     temp, $F0    ;D4...D7 aus Ausgabe
           out     DDRD, temp
           out     PORTD, temp  
                
           ldi     driver_index , $ef 
           ldi     digit_index , 0   

           ldi     temp, ( 1 << CS01 ) | ( 1 << CS00 )
           out     TCCR0B, temp
 
           ldi     temp, 1 << TOIE0
           out     TIMSK, temp
 
           sei
 
               
loop:      ldi     temp,$c0
           sts     Segment0,temp
           ldi     temp,$f9
           sts     Segment1,temp
           ldi     temp,$a4
           sts     Segment2,temp
           rcall   wait

           ldi     temp,$b0
           sts     Segment0,temp
           ldi     temp,$99
           sts     Segment1,temp
           ldi     temp,$92
           sts     Segment2,temp
           rcall   wait

           ldi     temp,$82
           sts     Segment0,temp
           ldi     temp,$f8
           sts     Segment1,temp
           ldi      temp,$80
           sts     Segment2,temp
           rcall   wait

           ldi     temp,$90
           sts     Segment0,temp
           ldi     temp,$88
           sts     Segment1,temp
           ldi     temp,$83
           sts     Segment2,temp
           rcall   wait

           ldi     temp,$c6
           sts     Segment0,temp
           ldi     temp,$a1
           sts     Segment1,temp
           ldi     temp,$86
           sts     Segment2,temp
           rcall   wait
      
           ldi     temp,$8e
           sts     Segment0,temp
           ldi     temp,$ff
           sts     Segment1,temp
           ldi     temp,$7f
           sts     Segment2,temp
           rcall   wait

           rjmp    loop
    

wait:      ldi     r21, 10      
wait0:     ldi     r22, 0       
wait1:     ldi     r23, 0       
wait2:     dec     r23
           brne    wait2
           dec     r22
           brne    wait1
           dec     r21
           brne    wait0
           ret

Codes:                               ; Die Codetabelle für die Ziffern 0 bis F
                                     ; sie regelt, welche Segmente für eine bestimmte
                                     ; Ziffer eingeschaltet werden müssen
                                    
  .db     0b11000000,0b11111001    ; c0  '0': a, b, c, d, e, f
                                   ; f9  '1': b, c
  .db     0b10100100,0b10110000    ; a4  '2': a, b, d, e, g
                                   ; b0  '3': a, b, c, d, g
  .db     0b10011001,0b10010010    ; 99  '4': b, c, f, g
                                   ; 92  '5': a, c, d, f, g
  .db     0b10000010,0b11111000    ; 82  '6': a, c, d, e, f, g
                                   ; f8  '7': a, b, c
  .db     0b10000000,0b10010000    ; 80  '8': a, b, c, d, e, f, g
                                   ; 90  '9': a, b, c, d, f, g
  .db     0b10001000,0b10000011    ; 88  'A': a, b, c, e, f, g
                                   ; 83  'b': c, d, e, f, g
  .db     0b11000110,0b10100001    ; c6  'C': a, d, e, f, 
                                   ; a1  'd': b, c, d, e, g 
  .db     0b10000110,0b10001110    ; 86  'E': a, d, e, f, g
                                   ; 8e  'F': a, e, f, g 

              .DSEG
Segment0:    .byte 1         ; Ausgabemuster für Segment 0
Segment1:    .byte 1         ; Ausgabemuster für Segment 1
Segment2:    .byte 1         ; Ausgabemuster für Segment 2

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.