www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wo steckt der Fehler? ASM Source


Autor: Reinhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich verzweifel gerade etwas an einem kleinen ATmega8 evtl. hat hier
jemand einen Rat oder Tipp was ich falsch mache oder übersehe.
Schaltung wie hier im Tutorial mit folgendem Programm:

-----------------------------------------------------------
.include "m8def.inc"

.def temp = R16
.equ CLOCK = 3686411
.equ BAUD = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1

.org 0x00
        rjmp main

.org URXCaddr                 ;Interruptvektor für UART-Empfang
        rjmp int_rxc

;Hauptprogramm
main:
        ldi temp, LOW(RAMEND)
        out SPL, temp
        ldi temp, HIGH(RAMEND)
        out SPH, temp

        ; Baudrate einstellen
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp

        ; Frame-Format: 8 Bit
        ldi temp, (1<<URSEL)|(3<<UCSZ0)
        out UCSRC, temp

        sbi UCSRB, RXCIE            ;Interrupt bei Empfang
        sbi UCSRB, RXEN             ;RX (Empfang) aktivieren
        sbi UCSRB, TXEN             ;TX (Senden) aktivieren

  ldi temp, 0x01       ;0x01 ins Arbeitsregister r16 laden
        out DDRC, temp       ;Inhalt von r16 ins IO-Register DDRC
ausgeben

  ldi temp, 0x01
        out PORTC, temp      ;PORTC auf 0x01 setzen -> Port PC0

        sei                  ;Interrupts global aktivieren

loop:
  cbi PINC, 0    ;An
  rcall wait    ;warten
  sbi PINC, 0    ;aus
  rcall wait    ;warten

        rjmp loop               ;Endlosschleife

;Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:
        push temp
        ldi temp, 'H'
        rcall serout
        ldi temp, 'a'
        rcall serout
        ldi temp, 'l'
        rcall serout
        ldi temp, 'l'
        rcall serout
        ldi temp, 'o'
        rcall serout
        ldi temp, 10
        rcall serout
  ldi temp, 13
        rcall serout
        pop temp                          ; temp wiederherstellen
        reti                              ; Interrupt beenden



serout:
        sbis UCSRA,UDRE           ;Warten bis UDR für das nächste
                                  ;Byte bereit ist
        rjmp serout
        out UDR, temp
        ret

wait:
; =============================
;    delay loop generator
;     18432000 cycles:
; -----------------------------
; delaying 18431985 cycles:
          ldi  R17, $A9
WGLOOP0:  ldi  R18, $92
WGLOOP1:  ldi  R19, $F8
WGLOOP2:  dec  R19
          brne WGLOOP2
          dec  R18
          brne WGLOOP1
          dec  R17
          brne WGLOOP0
; -----------------------------
; delaying 15 cycles:
          ldi  R17, $05
WGLOOP3:  dec  R17
          brne WGLOOP3
; =============================

  ret

------ENDE-------

Das Problem ist ich bekomme weder eine serielle Verbindung zum
Controller noch blinkt Port PC0. Der Controller lässt sich mit YAAP
einwandfrei beschreiben und auslesen.


Guten Rutsch
Reinhard

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Blinken wird's so sicher nicht. PINC und PORTC verwechselt.

Die Interrupt-Routine ist bemerkenswert - statt den Status zu retten,
ein konsequenter Verzicht auf alle Befehle die was dran ändern ;-).
Sieht man nicht oft.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgendermaßen würde ich die Interruptroutine noch abändern und wie
oben schon gesagt noch statt PINC PortC schreiben.

;Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:
        push temp
  in temp,SREG  ; Statusregister sichern
  push temp  ; dito
        ldi temp, 'H'
        rcall serout
        ldi temp, 'a'
        rcall serout
        ldi temp, 'l'
        rcall serout
        ldi temp, 'l'
        rcall serout
        ldi temp, 'o'
        rcall serout
        ldi temp, 10
        rcall serout
        ldi temp, 13
        rcall serout
        pop temp1    ; Statusregister vom Stack holen
  out SREG, temp1    ; dito
        pop temp               ; temp wiederherstellen
        reti

Gruß

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man sollte sich solche Art der schlechten Interruptprogrammierung
garnicht erst angewöhnen. Das verstößt nämlich gegen die ersten 3
Lehrsätze der Interruptprogramierung:

1. Halte Interrupts so kurz wie möglich
2. Halte Interrupts so kurz wie möglich
3. Halte Interrupts so kurz wie möglich

Und serielle Ausgabezeiten nutzlos zu verwarten, gulpt hier schon
stolze 19200 Zyklen kostbarer CPU-Zeit:

3686411 / 9600  10  5


Peter

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.