Forum: Mikrocontroller und Digitale Elektronik UART mit Interrupt


von Sahra N. (sahra_nana)


Lesenswert?

hat das Beispiel bei irgend jemanden funktioniert:
1
int_rxc:
2
    push    temp                        ; temp auf dem Stack sichern
3
    in      temp, sreg                  ; SREG sichern
4
    push    temp
5
    
6
    lds     temp, UDR0                  ; UART Daten lesen
7
    cpi     temp, '1'                   ; empfangenes Byte mit '1' vergleichen
8
    brne    int_rxc_1                   ; wenn nicht gleich, dann zu int_rxc_1
9
    cbi     PORTB, 0                    ; LED einschalten, low aktiv
10
    rjmp    int_rxc_2                   ; Zu int_rxc_2 springen
11
int_rxc_1:
12
    cpi     temp, '0'                   ; empfangenes Byte mit '0' vergleichen
13
    brne    int_rxc_2                   ; wenn nicht gleich, dann zu int_rxc_2
14
    sbi     PORTB, 0                    ; LED ausschalten, low aktiv
15
int_rxc_2:
16
 
17
    pop     temp
18
    out     sreg, temp                  ; SREG wiederherstellen
19
    pop     temp                        ; temp wiederherstellen
20
    reti
also bei funz nicht

von Karl H. (kbuchegg)


Lesenswert?

Da dein Beispiel nicht vollständig ist, werden sich Helfer schwer tun 
die Frage zu beantworten.

von Johnny B. (johnnyb)


Lesenswert?

Also auf meinem NEC V850 funktioniert Dein code nicht.

von Karl H. (kbuchegg)


Lesenswert?

Tip:
Lass dir zu Kontrollzwecken IMMER das Zeichen, das du empfangen hast, 
gleich wieder über den Sendekanal ausgeben. Dann kannst du in deinem 
Terminalprogramm kontrollieren, welches Zeichen dein Programm über die 
Schnittstelle empfangen hat.

"Lokales Echo" ist kein Ersatz für Kontrollmöglichkeiten.

von Brumbaer (Gast)


Lesenswert?

AUf den ersten Blick sieht die Routine ok aus.

Aber wird sie überhaupt aufgerufen ?

Zeigt der IR Vector auf sie,
Ist der Receiver Interrupt eingeschaltet ?
Sind überhaupt Interrupts erlaubt ?
Ist das DDR gesetzt ?


Toggle doch mal den Pin in einer Endlosschleife, dann siehst du schon 
mal ob das geht.

Dann Toggle den Pin bei jedem Aufruf der Routine, dann weisst du 
schonmal ob dein Programm dort hinkommt. Ich vermute, dass nicht.

MfG
SH

von Sahra N. (sahra_nana)


Lesenswert?

.include "m88def.inc"

.def temp = R16

.equ F_CPU = 3686400                            ; Systemtakt in Hz
.equ BAUD  = 9600                               ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille 
Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit 
zu hoch!"
.endif

.org 0x00
        rjmp main

.org URXCaddr
        rjmp int_rxc

; Hauptprogramm

main:

    ; Stackpointer initialisieren

    ldi     temp, HIGH(RAMEND)
    out     SPH, temp
    ldi     temp, LOW(RAMEND)
    out     SPL, temp

    ; Port D = Ausgang

    ldi     temp, 0xFF
    out     DDRD, temp

    ; Baudrate einstellen

    ldi     temp, HIGH(UBRR_VAL)
    sts     UBRR0H, temp
    ldi     temp, LOW(UBRR_VAL)
    sts     UBRR0L, temp

    ; Frame-Format: 8 Bit

    ldi     temp, (1<<USBS0)|(3<<UCSZ00)
    sts     UCSR0C, temp

  sbr  temp,(0<<RXCIE0)
  sbr  temp,(0<<RXEN0)
  sbr  temp,(0<<TXEN0)
  sts     UCSR0B ,temp




    sei                                     ; Interrupts global 
aktivieren

 loop:
  rjmp loop                               ; Endlosschleife

; Interruptroutine: wird ausgeführt sobald ein Byte über das UART 
empfangen wurde



    int_rxc:
    push    temp                        ; temp auf dem Stack sichern
    in      temp, sreg                  ; SREG sichern
    push    temp

    lds     temp, UDR0                  ; UART Daten lesen
    cpi     temp, '1'                   ; empfangenes Byte mit
                                            1 vergleichen
    brne    int_rxc_1                   ; wenn nicht gleich, dann zu 
int_rxc_1
    cbi     PORTB, 0                    ; LED einschalten, low aktiv
    rjmp    int_rxc_2                   ; Zu int_rxc_2 springen
int_rxc_1:
    cpi     temp, '0'                   ; empfangenes Byte mit '0' 
vergleichen
    brne    int_rxc_2                   ; wenn nicht gleich, dann zu 
int_rxc_2
    sbi     PORTB, 0                    ; LED ausschalten, low aktiv
int_rxc_2:

    pop     temp
    out     sreg, temp                  ; SREG wiederherstellen
    pop     temp                        ; temp wiederherstellen
    reti

hier das ganze Beispiel

von spess53 (Gast)


Lesenswert?

Hi

Ersetze mal

> sbr  temp,(0<<RXCIE0)
> sbr  temp,(0<<RXEN0)
> sbr  temp,(0<<TXEN0)
> sts     UCSR0B ,temp

durch

  ldi temp,(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0)
  sts     UCSR0B ,temp

1. dein temp ist sonst unbestimmt
2. 'sbr  temp,(0<<XYZ)' bewirkt nichts

MfG Spess

von Sahra N. (sahra_nana)


Lesenswert?

>> sbr  temp,(0<<RXCIE0)
>> sbr  temp,(0<<RXEN0)
>> sbr  temp,(0<<TXEN0)
>> sts     UCSR0B ,temp

>   ldi temp,(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0)
>   sts     UCSR0B ,temp
> 1. dein temp ist sonst unbestimmt
> 2. 'sbr  temp,(0<<XYZ)' bewirkt nichts


hier war nur einen Schreibfehler, ich habe auch alle auf 1 gesetzt..

von spess53 (Gast)


Lesenswert?

Hi

>    ldi     temp, (1<<USBS0)|(3<<UCSZ00)
>    sts     UCSR0C, temp

>  sbr  temp,(0<<RXCIE0)
>  sbr  temp,(0<<RXEN0)
>  sbr  temp,(0<<TXEN0)
>  sts     UCSR0B ,temp

Du hast aber vorher schon etwas nach temp geladen. Und danach setzt du 
noch ein paar Bits. Was meinst du, was dabei herauskommt?

MfG Spess

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.