-         

Ergebnis 1 bis 4 von 4

Thema: Interrupt Transmit Complete UART

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200

    Interrupt Transmit Complete UART

    Anzeige

    Hallo Leute,

    habe mir ein kleines Programm gestrickt, dass Zeichen aus dem RAM an das Hyperterminal schicken soll. Leider bringe ich meinen Atmel nicht dazu einen Interrupt (UTXCaddr) auszulösen.

    Eigentlich habe ich alles gemacht was zu tun ist:
    sbi UCSRB,TXCIE ; Interrupt für "senden fertig" aktivieren
    sei ; globale Interruptfreigabe
    sbi UCSRA,TXC ; Initialisierung des Interrupts

    Was habe ich vergessen?

    Code:
     .NOLIST                    	; List-Output unterdrücken
     .INCLUDE <m8def.inc>       	; das gibt es für jeden Controllertyp
    
    
     .def temp = R16				; für Interrupt
     .def ZEICHEN = R17
     .equ VARIABLE = 0 				; Beschreibung der Variable
    
    
     ;------------------------------------------------------
     ;    Peripherie initialisieren
     ;------------------------------------------------------
    .equ F_CPU = 7273800                            ; 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
    
    
     .LIST                      	; List-Output wieder aufdrehen
     .CSEG                      	; was nun folgt, gehört in den FLASH-Speicher
    
    
     ;------------------------------------------------------
     ;     Start Adresse 0000 /Interruptvektoren
     ;------------------------------------------------------
     .org 0x000
    	rjmp Init			; Interruptvektoren überspringen
     
     .org UTXCaddr			; UART Transmit Complete Interrupt
        rjmp serout 
    
    
     ;------------------------------------------------------
     ;     INITIALIZE
     ;------------------------------------------------------
    INIT:
    ;Stack Pointer setzen
      ldi temp,high(RAMEND)
      out SPH,temp
      ldi temp,low(RAMEND)
      out SPL,temp
    
    ; Baudrate einstellen
      ldi temp, HIGH(UBRR_VAL)
      out UBRRH, temp
      ldi temp, LOW(UBRR_VAL)
      out UBRRL, temp
    
    ; Frame-Format: 1 Stop-Bits, 8 Bit 
      ldi temp, (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
      out UCSRC, temp
      sbi UCSRB,TXEN               	; Sender aktivieren
      sbi UCSRB,TXCIE				; Interrupt für "senden fertig" aktivieren
    
      sei							; globale Interruptfreigabe
      sbi UCSRA,TXC    				; Initialisierung des Interrupts
     ;------------------------------------------------------
     ;   HAUPTSCHLEIFE
     ;------------------------------------------------------
    Hauptschleife:					
    
    
    rjmp Hauptschleife
    
    
     ;------------------------------------------------------
     ;   Subroutinen / ISRs
     ;------------------------------------------------------
    
    ;Auslesen der Zeichen und bereitstellen in ZEICHEN
    ;Erhöhen des Z-Pointers; bei leerem Zeichen --> Zurücksetzen des Z-Pointers
    
    serout:
       lpm								; Erstes Byte des Strings nach R0 lesen
    
       mov ZEICHEN,R0
       adiw ZL, 1                       ; Adresse des Z-Pointers um 1 erhöhen
       tst R0							; Inhalt von R0 auf Bull testen
    
       brbc 1,sprung_b
      	ldi ZL, LOW(Daten*2)			; Adresse des ersten Strings in den
      	ldi ZH, HIGH(Daten*2)			; Z-Pointer laden
       sprung_b:
    
        out     UDR, ZEICHEN			; Zeichen auf UART ausgeben
    reti
    
     ;------------------------------------------------------
     ;   Datenbereich
     ;------------------------------------------------------
    Daten:
               .db 0x12, 0x12
    		   .db 0x20, 0x20	
    		   .db 0x63, 0x63	
    		   .db 0x58, 0x00	
    
     ;------------------------------------------------------
     ;   ENDE
     ;------------------------------------------------------
     Ende:  
            rjmp Ende

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    pacer_one,

    Dein Programm hat keine offensichtlichen Fehler. Unsicher bin ich nur an einer Stelle: Ich weiss nicht sicher, ob Du die ".org"-Direktive in demselben Segment zweimal verwenden darfst. Versuchsweise könntest Du den Platz zwischen "rjmp Init" und der Adresse 0x000D mit "reti"-Anweisungen füllen. Z.B. so:

    Code:
    .CSEG
    .ORG $0000
    
    ;*------------------------------------
    ;
    ; Reset- and Interrupttabelle
    ;
    	rjmp INIT ;  	 1 - Reset/Init-Routine
    	reti;  IINT0 	 2 - External Interrupt Request 0
    	reti;  IINT1 	 3 - External Interrupt Request 1
    	reti;  T2_CMP	 4 - Timer/Counter2 Compare match
    	reti;  T2_OVF	 5 - Timer/Counter2 Overflow
    	reti;  T1_CPT 	 6 - Timer/Counter1 Capture event
    	reti;  T1_CMPA 	 7 - Timer/Counter1 Compare A match
    	reti;  T1_CMPB 	 8 - Timer/Counter1 Compare B match
    	reti;  T1_OVF 	 9 - Timer/Counter1 Overflow
    	reti;  T0_OVF	10 - Timer/Counter0 Overflow
    	reti;  SPI_STC	11 - Serial Transfer Complete
    	reti;  RX_FULL 	12 - UART Rx char available
    	reti;  TX_EMPT 	13 - UART Tx data register empty
    	rjmp serout;  TX_DONE 	14 - UART Tx complete
    	reti;  ADC_DONE	15 - ADC conversion complete
    	reti;  EE_RDY	16 - EEPROM Ready
    	reti;  ANA_CMP 	17 - Analog comparator
    	reti;  TWI_INT 	18 - Two-wire Interface
    	reti;  IINT2	19 - External Interrupt Request 2
    	reti;  T0_CMP	20 - Timer/Count0 Compare match
    	reti;  SPM_RDY	21 - Store Program Memory ready
    	rjmp INIT		; falls das Programm jemals hier ankommt, ...
    			; .. dann ist was schief gegangen.
    Dann bist Du sicher, dass es nicht an der zweiten "org"-Direktiven lag.

    Sonst fällt mir an Deinem Programm wirklich nichts auf.

    Hat's geholfen?

    mare_crisium

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.12.2004
    Ort
    LEV
    Beiträge
    505
    Hallo,
    du sendest ja nix,
    also bekommst du auch keinen Interrupt "senden fertig" (TXCn).
    Sende doch testweise vor der Hauptschleife mal ein Zeichen.

    Evtl. willst du auch den
    USART Data Register Empty Interrupt (UDREn) verwenden.

    Gruß Jan

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200
    stimmt, ich muss natürlich zuerst ein Zeichen senden, ich war da wohl auf dem falschen Dampfer und habe versucht einen Interrupt über das Setzen von:
    sbi UCSRA,TXC, was natürlich totaler Quatsch ist, weil ja damit nur das Interruptflag gelöscht wird.

    Das mit den .org-Direktiven habe ich aus einem Tutorial als Template übernommen. Zumindest hat das bis jetzt keine Probleme verursacht

    Danke für die Hilfe, geht jetzt also...

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •