www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART + Taschenrechner Teil2


Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich mach der Übsicht halber mal nen neuen Thread auf. Also das UArt 
klappt nur komme ich nicht weiter als bis zur ersten LED. Der Code ist 
der:



.include "m32def.inc"                    ; bzw. 2333def.inc
 
.def temp    = R16
.def Data    = R17
.def Count   = R18


.equ CLOCK   = 16000000
.equ BAUD    = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1
 
.org 0x00
        rjmp main
 
.org URXCaddr                             ; Interruptvektor für UART-Empfang
        rjmp Recive1


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

        ldi temp, 0xFF                    ; Port D = Ausgang
        out DDRD, temp

        ldi temp, 0b01100000
        out PortD, temp
 
        ; Baudrate einstellen
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
 
        ; Frame-Format: 8 Bit
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
        out UCSRC, temp
 
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
        
        sei                               ; Interrupts global aktivieren
        
loop:  
  
    rjmp loop                         ; Endlosschleife

Recive1:

       sbis UCSRA, RXC    
     rjmp  Recive1
       in Data, UDR                      ; Empfangenes Byte in Data speichern
     cpi  Data, 0x15
     brne Ende
     
     rjmp header_init

       Ende:
     reti                               ; zurück zum Hauptprogramm


Recive:

       sbis UCSRA, RXC    
     rjmp  Recive
       in Data, UDR                      ; Empfangenes Byte in Data speichern
     ret  



Transmit:

       sbis UCSRA, UDRE                   ; Warten bis UDR ist
       rjmp Transmit
       out UDR, Data                      ; Data senden
     ret

       

header_init:

     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
     cbi  PORTD, 5
     
     ldi  Data, 0x13
     rcall Transmit
     ldi  Count, 0x31                    ; Counter der bytes zählt aktivieren

header_recive:
       
     
       rcall Recive
     dec Count
     cpi Count, 0
     brne header_recive
     cbi  PORTD, 6
     ldi Data, 0x06
     rcall Transmit
    
    



Neustart:

    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
    rjmp loop




hier der Link zum Protokol:

http://users.pandora.be/gp/casio/index.html

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke mal das Problem liegt hier:

header_recive:


       rcall Recive
     dec Count
     cpi Count, 0
     brne header_recive
     cbi  PORTD, 6
     ldi Data, 0x06
     rcall Transmit

entweder du machst das "cpi Count, 0" weg oder ersetzt es durch
"cpi count, 0x00"

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Condi wrote:
> entweder du machst das "cpi Count, 0" weg oder ersetzt es durch
> "cpi count, 0x00"
Ersetze XYZ durch XYZ oder "den Teufel mit Beelzebub austreiben"? Die 
beiden Ausdrücke sind gleichwertig (und in Assembler sogar tatsächlich, 
da nicht Case-sensitiv und dementsprechend count = Count)...

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann man "Taschenrechner Teil 1.0" auch mal sehen??
Ich habe zufällig auch einen CFX-9850...

AxelR.

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du springst in der Receive Intrerruptroutine raus aus dieser, falls dein 
eingehendes Datenbyte 0x15 ist. Da Du nie wieder in die INtRoutine 
zurückspringst, wird kein RETI aufgerufen und das I-Flag wird nicht 
gelöscht. Daher können keine weiteren Interrupts abgearbeitet werden.

Pack den Transmitkram in die Hauptroutine und frage dort ein bit im 
Register 20 oder so ab. Ist dieses gesetzt, weil 0x15 empfangen wurde, 
machst Du den Job in der Hauptschleife.

Siehe ...HanneS... "Jobflag
http://www.mikrocontroller.net/search?query=jobfla...

AxelR.

8N1 mit 9K6- bist Du sicher???

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florentin,

weshalb fängst Du wieder von vorne und mit den selben Problemen an ?

Diesmal rettest Du gar nichts auf den Stack und plötzlich nimmst

Du nur noch 1 Stoppbit....


Gruss Otto

Autor: Axel R. (axelr) Flattr this
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hab das Blatt mal aufn Scanner gelegt...

Scheint aber schon mal diskutiert worden zu sein, oder? (klar, im Teil 1 
eben;-)) )

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut meinem Mega32 Datenblatt ist:
ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)

8n2

Der Code ist  zwar nicht so schön, aber er sollte funktionieren. Wenn 
0x15 empfangen wurde, wir der Interrupt disabled und dann wird immer 
geprüft ob wieder was empfangen wurde.

Bei Neustart sollte halt anstelle des rjmp loop ein reti stehen. Das 
Problem liegt in der Schleife, die ich schon erwähnte, die scheint nicht 
0 zu werden.
Du solltest mehr Anzeigen in die Schleifen machen, damit du mehr infos 
bekommst.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so ich habe lange nicht hier reingeschaut. hier der aktuelle Code:


.include "m32def.inc"                    ; bzw. 2333def.inc
 
.def temp    = R16
.def Data    = R17
.def Count   = R18


.equ CLOCK   = 16000000
.equ BAUD    = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1
 
.org 0x00
        rjmp main
 
.org URXCaddr                             ; Interruptvektor für UART-Empfang
        rjmp Recive1


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

        ldi temp, 0xFF                    ; Port D = Ausgang
        out DDRD, temp

        ldi temp, 0b01100000
        out PortD, temp
 
        ; Baudrate einstellen
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
 
        ; Frame-Format: 8 Bit
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
        out UCSRC, temp
 
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
        
        sei                               ; Interrupts global aktivieren
        
loop:  
  
    rjmp loop                         ; Endlosschleife

Recive1:

       in Data, UDR                      ; Empfangenes Byte in Data speichern
     cpi  Data, 0x15
     brne Ende
     
     rjmp header_init

       Ende:
     reti                               ; zurück zum Hauptprogramm


Recive:

       sbis UCSRA, RXC
     rjmp Recive
       in Data, UDR                      ; Empfangenes Byte in Data speichern
     ret  



Transmit:

       sbis UCSRA, UDRE                   ; Warten bis UDR ist
       rjmp Transmit
       out UDR, Data                      ; Data senden
     ret

       

header_init:

     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
    


ldi temp, 10
wait0:
                push temp
                ldi temp, 200
wait0_1:                               
                nop
                nop
                nop
                nop
                nop
                dec temp
                cpi temp, 0
                brne wait0_1
                pop temp
                dec temp
                cpi temp, 0
                brne wait0



     
     ldi  Data, 0x13
     rcall Transmit
     
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren

       cbi  PORTD, 5
header_recive:
       
     
       rcall Recive
     
     dec Count
     cpi Count, 0
     brne header_recive
     


       ldi temp, 10
wait1:
                push temp
                ldi temp, 200
wait1_1:                               
                nop
                nop
                nop
                nop
                nop
                dec temp
                cpi temp, 0
                brne wait1_1
                pop temp
                dec temp
                cpi temp, 0
                brne wait1



     ldi Data, 0x06
     rcall Transmit
     




     ldi Count, 16
data_recive:
     rcall Recive
     dec count
     cpi Count, 0
     brne data_recive





ldi temp, 10
wait2:
                push temp
                ldi temp, 200
wait2_1:                               
                nop
                nop
                nop
                nop
                nop
                dec temp
                cpi temp, 0
                brne wait2_1
                pop temp
                dec temp
                cpi temp, 0
                brne wait2



     ldi Data, 0x06
     rcall Transmit

     
cbi  PORTD, 6


ldi  Count, 50

end_header:
       
       rcall Recive
     
     dec Count
     cpi Count, 0
     brne end_header
    



ldi temp, 10
wait3:
                push temp
                ldi temp, 200
wait3_1:                               
                nop
                nop
                nop
                nop
                nop
                dec temp
                cpi temp, 0
                brne wait3_1
                pop temp
                dec temp
                cpi temp, 3
                brne wait3






     ldi Data, 0x06
     rcall Transmit


  
      

Neustart:

rjmp Neustart

    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
    rjmp loop


       





er hängt bei data_recive...die LED geht nicht an. ansonsten kein Fehler 
auf dem Rechner er hängt sich nur auf

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sagt hyperterm?

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so ich habe die Warteschleifen jetzt 20mal durchlaufen lassen und es 
geht!!!

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und mit reti am ende kann ich das ganze sogar mehrfach hinterienander 
machen...

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Warteschleifen sind unnütz. Da du den HW UART nimmst, waret der bis 
die Hardware bereit ist. Hast du auch die richtigen Fuse bits gesetzt?

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ohne Warteschleifen gehts nicht!


und welche Fusebits meinst du?

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du meinst, dass Du ohne die Warteschleifen nichts
an den LEDS siehst oder ?

Otto

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
erstens das und zweiten kommt aud dem Rechner kein Done. Also ich sehe 
nur die erste ohne Warteschleife.

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na die von dem Mega32. Schonmal im Datenblatt nachgelesen?
Vom Werk aus läuft der mit 1Mhz internem Clock.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die habe ich auf 16 MHz Quarz gestellt...du musst schon sagen welche 
fusebits. ich kann ja nciht erahnen, dass du die für den tackt meinst

Autor: Michael Frangenberg (startrekmichi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wegen den Warteschleifen: Der Taschenrechner ist so lahm, dass der µC 
sich etwas gedulden muss, bevor er die Handshakes usw senden darf. An 
sonsten ist der Taschenrechner noch nicht zum Empfangen bereit und das 
Gesendete geht verloren.
Theoretisch könnte man den µC wahrscheinlich mit 4MHz oder so laufen 
lassen, würde locker reichen. Vielleicht geht sogar noch weniger.

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nop
                dec temp
                cpi temp, 0
                brne wait0_1

wenn Du temp verringerst, wird das ZeroFlag Erst gesetzt, wenn temp NULL 
ist.

Daher ja auch BRNE. Du brauchst keinen zusätzlichen Vergleich mittels 
CPI temp,0 machen. Das macht der Controller von Hause aus.

dec temp
brne wait0_1

reicht daher.

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt eigentlich, die Bootloader FuseBits hätten es auch sein können. 
Tschuldige.

@Michael

Warum hast du in deinem Programm keine Warteschleifen drin?
Ich war immer der Meinung 9600 Baud ist 9600 Baud egal ob der MC mit 
1Mhz läuft oder 16Mhz, zumindest bei HW-UART.

Autor: Michael Frangenberg (startrekmichi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vom µC aus gesehen stimmt das auch. Nur beim Taschenrechner anscheinend 
nicht. (Ev hat der nen Software-uart oder so was.)
Im Protokoll isses so, dass der GTR (=Taschenrechner) etwas sendet und 
dann der µC das bestätigen soll. Wenn das Bestätigungsbyte aber zu 
schnell nach Empfang der Daten gesendet wird, hat der GTR anscheinend 
ein Problem und erkennt das Byte nicht.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Michael Frangenberg


danke nochmal für deine Hilfe gestern. Mein ICQ ging irgendwie nichtmehr 
an.


Ich werde heute mal versuchen die Daten zu speichern und wenn das Klappt 
das Programm für allgemeine Übertragungen bereit machen also das mit der 
Datenlänge aus header etc. Am besten wäre je eigentlich zum speichern 
nen externer EEprom oder Sram. Das müsst ich mir noch besorgen.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so hier mal mit speicher Funktion:



.include "m32def.inc"                    ; bzw. 2333def.inc
 
.def temp    = R16
.def Data    = R17
.def Count   = R18



.equ CLOCK   = 16000000
.equ BAUD    = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1
 
.org 0x00
        rjmp main
 
.org URXCaddr                             ; Interruptvektor für UART-Empfang
        rjmp Recive1


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

        ldi temp, 0xFF                    ; Port D = Ausgang
        out DDRD, temp

        ldi temp, 0b01100000
        out PortD, temp
 
        ; Baudrate einstellen
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
 
        ; Frame-Format: 8 Bit
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
        out UCSRC, temp
 
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
        
        sei                               ; Interrupts global aktivieren
        
loop:  

    ldi temp, 0b01100000
        out PortD, temp
  
    rjmp loop                         ; Endlosschleife

Recive1:

       in Data, UDR                      ; Empfangenes Byte in Data speichern
     cpi  Data, 0x15
     brne Ende
     
     rjmp header_init

       Ende:
     reti                               ; zurück zum Hauptprogramm


Recive:

       sbis UCSRA, RXC
     rjmp Recive
       in Data, UDR                      ; Empfangenes Byte in Data speichern
     ret  



Transmit:
    

                    ldi temp, 20
       wait1:
                    push temp
                    ldi temp, 200
       wait1_1:                               
                    nop
                    nop
                    nop
                    nop
                    nop
                    dec temp
                    cpi temp, 0
                    brne wait1_1
                    pop temp
                    dec temp
                    cpi temp, 0
                    brne wait1


       sbis UCSRA, UDRE                   ; Warten bis UDR ist
       rjmp Transmit
       out UDR, Data                      ; Data senden
     ret

       

header_init:

       cbi  PORTD, 5
    
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
    
     
     ldi  Data, 0x13
     rcall Transmit
    
    
     ldi     r30,LOW(Header)
       ldi     r31,HIGH(Header)
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren

       
header_recive:
       
     
       rcall Recive
     st Z+, Data
     
     dec Count
     cpi Count, 0
     brne header_recive
     



     ldi Data, 0x06
     rcall Transmit
     

     ldi Count, 16
     ldi r30,LOW(Content)
       ldi r31,HIGH(Content)
data_recive:
     rcall Recive
     st Z+, Data
     dec count
     cpi Count, 0
     brne data_recive



     ldi Data, 0x06
     rcall Transmit

    


       ldi Count, 50
     ldi r30,LOW(End_Header)
       ldi r31,HIGH(End_Header)

end_header_recive:
       
       rcall Recive
     st Z+, Data
     dec Count
     cpi Count, 0
     brne end_header_recive
    




     ldi Data, 0x06
     rcall Transmit



Check:

ldi r30,LOW(Content)
ldi r31,HIGH(Content)

ld r19, Z
 
cpi r19, 2

brne Neustart

cbi  PORTD, 6




  
      

Neustart:


    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
    reti





.DSEG                                      ; das Folgende kommt ins SRAM
Header:     .BYTE  50
Content:    .BYTE  16
End_Header: .Byte  50




       


nur leider will das ni so wie ich will...der vergleich ist nicht 
erfolgreich...

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florentin,

das kann es auch nicht - aus mehreren Gründen aber der Reihe nach:

Du solltest zuerst mal "aufräumen"

1. vor brne muß kein cpi, wenn Du auf "0" vergleichst
2. den Z-Pointer mußt Du auch initialisieren (z.B. auf Ramstart)
3. es heißt "receive"

Otto

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie geht das mit dem TPointer? Ok Aufräümen werde ich wohl mal machen...

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florentin,

auf RAMSTART zu initialisieren geht z.B. so:

Z_INIT:  ldi temp, LOW(RAMSTART)  ; Wert LO initialisieren
  mov ZL, temp         ; Z-Register low
      ldi temp, HIGH(RAMSTART) ;
      mov ZH, temp         ; Z-Register high
  ret

Verstehe es bitte nicht falsch - Du solltest Deinen Code
zuerst mal aufräumen, sonst findet sich evtl. keiner, der
Lust hat, sich da durch zu wühlen.....

Gruss Otto

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welches Modell hast du genau?

@Michael
Du hast 8Mhz verwendet, d.h. du hättest mindestens auch die Hälfte der 
"Waitstates" einlegen müssen. Zumindest (9850, 32kb, schwarz) bei meinem 
funktioniert auch 8n1 und Mega162 mit 14,7Mhz. Naja und mit dem PC 
klappt es ja auch....
Was ich so gefunden habe, scheint der schon mindestens ein UART zu 
haben, nur keine Interrupts bzw. halt deaktiviert.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier mal aufgeräumt:

.include "m32def.inc"                    ; bzw. 2333def.inc
 
.def temp    = R16
.def Data    = R17
.def Count   = R18



.equ CLOCK   = 16000000
.equ BAUD    = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1
 
.org 0x00
        rjmp main
 
.org URXCaddr                             ; Interruptvektor für UART-Empfang
        rjmp Receive1


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

        ldi temp, 0xFF                    ; Port D = Ausgang
        out DDRD, temp

        ldi temp, 0b01100000
        out PortD, temp
 
        ; Baudrate einstellen
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
 
        ; Frame-Format: 8 Bit
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
        out UCSRC, temp
 
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
        
        sei                               ; Interrupts global aktivieren
        
loop:  

    ldi temp, 0b01100000
        out PortD, temp
  
    rjmp loop                         ; Endlosschleife

Receive1:

       in Data, UDR                      ; Empfangenes Byte in Data speichern
     cpi  Data, 0x15
     brne Ende
     
     rjmp header_init

       Ende:
     reti                               ; zurück zum Hauptprogramm


Receive:

       sbis UCSRA, RXC
     rjmp Receive
       in Data, UDR                      ; Empfangenes Byte in Data speichern
     ret  



Transmit:
    

                    ldi temp, 20
       wait1:
                    push temp
                    ldi temp, 200
       wait1_1:                               
                    nop
                    nop
                    nop
                    nop
                    nop
                    dec temp
                    brne wait1_1
                    pop temp
                    dec temp
                    brne wait1


       sbis UCSRA, UDRE                   ; Warten bis UDR ist
       rjmp Transmit
       out UDR, Data                      ; Data senden
     ret

       

header_init:

       cbi  PORTD, 5
    
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
    
     
     ldi  Data, 0x13
     rcall Transmit
    
    
     ldi     r30,LOW(Header)
       ldi     r31,HIGH(Header)
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren

       
header_receive:
       
     
       rcall Receive
     st Z+, Data
     
     dec Count
     brne header_receive
     
     ldi Data, 0x06
     rcall Transmit
     

     ldi Count, 16
     ldi r30,LOW(Content)
       ldi r31,HIGH(Content)
data_receive:
     rcall Receive
     st Z+, Data
     dec count
     brne data_receive

     ldi Data, 0x06
     rcall Transmit

       ldi Count, 50
     ldi r30,LOW(End_Header)
       ldi r31,HIGH(End_Header)

end_header_receive:
       
       rcall Receive
     st Z+, Data
     dec Count
     brne end_header_receive

     ldi Data, 0x06
     rcall Transmit



Check:

ldi r30,LOW(Content)
ldi r31,HIGH(Content)

ld r19, Z

brne Neustart

cbi  PORTD, 6


Neustart:


    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
    reti



.DSEG                                      ; das Folgende kommt ins SRAM
Header:     .BYTE  50
Content:    .BYTE  16
End_Header: .Byte  50





mit dem Z-Pointer initialisieren habe ich auch noch nicht ganz 
begriffen. Das habe ich noch nirgendwo gelesen. Aber es scheint logisch.

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florentin,

der Warteschleife solltest Du ein 2. Register
spendieren und nicht mit "push" und "pop"
arbeiten.

Die im SRAM gespeicherten Konstanten werden
von den Routinen überschrieben - da kann ich
keinen Sinn erkennen.

Beispiel:

den Z-Pointer (R30 und R31) hast Du mittels:

ldi r30,LOW(Content)
ldi r31,HIGH(Content)

auf die Adresse von "content" gelegt.

                       ldi Count, 16
                       ldi r30,LOW(Content)
                       ldi r31,HIGH(Content)
data_receive:          rcall Receive
                       st Z+, Data
                       dec count
                       brne data_receive

mit "st Z+" speicherst Du Daten ab dieser
Adresse und überschreibst damit

"END_Header"

Gruss Otto

Autor: Michael Frangenberg (startrekmichi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Condi
Ich hab meine Platinen mit 7,3728MHz laufen lassen und auch die 
entsprechend langen Warteschleifen eingebaut.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wieso überschreib ich damit das nächste. Ich verstehe das jetzt so ich 
sezt den Z Pointer auf Content lede Byte für Byte data_receive ein und 
lade anschliesend den Pinter auf die Nächste adresse...

Autor: canbastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

     ldi r30,LOW(Content)
     ldi r31,HIGH(Content)

data_receive:      rcall Receive
                   st Z+, Data
                   dec count
                   brne data_receive

> sezt den Z Pointer auf Content

ja, aber sndchliessend durchläufst Du
16 x Data_receive und speicherst die Daten
mit Z+ d.h. die Daten werden gespeichert
unter

content
content+1
content+2
..
..

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ist doch richtig so oder? ich habe für Content 16 Bytes reserviert 
und möchte diese nun nacheinander beschreiben.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder doch nicht? Und wenn es falsch ist wie könnte ich den Code ändern? 
Damit es funktioniert, wie es soll. Ich habe da leider noch nicht soviel 
Erfahrung.

Autor: canbastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch - Du hattest recht. Rette in der
Interrupt-Routine auch das "SREG"
(siehe Tutorium) auf den Stack

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wieso in der inrerrupt Routine? Die wird doch vor dem speichern und 
laden aufgerufen...

ps: das war doch das Status register...wo stand das nochmal im tut?

Autor: canbastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil ansonsten nach der Rückkehr zur normalen Bearbeitung ein Ergebnis 
fehlen könnte: 
http://www.mikrocontroller.net/articles/AVR-Tutori...

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habs jetzt so gemacht. aber es geht leider immer noch nicht.



.include "m32def.inc"                    ; bzw. 2333def.inc
 
.def temp    = R16
.def Data    = R17
.def Count   = R18



.equ CLOCK   = 16000000
.equ BAUD    = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1
 
.org 0x00
        rjmp main
 
.org URXCaddr                             ; Interruptvektor für UART-Empfang
        rjmp Receive1


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

        ldi temp, 0xFF                    ; Port D = Ausgang
        out DDRD, temp

        ldi temp, 0b01100000
        out PortD, temp

        ; Baudrate einstellen
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
 
        ; Frame-Format: 8 Bit
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
        out UCSRC, temp
 
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
        
        sei                               ; Interrupts global aktivieren
        
loop:  

    ldi temp, 0b01100000
        out PortD, temp
  
    rjmp loop                         ; Endlosschleife

Receive1:

       in   r20, SREG   
       in Data, UDR          ; Empfangenes Byte in Data speichern
       cpi  Data, 0x15
     brne Ende
     rjmp header_init

       Ende:
     out SREG, r20 
     reti                               ; zurück zum Hauptprogramm


Receive:

       sbis UCSRA, RXC
     rjmp Receive
       in Data, UDR                      ; Empfangenes Byte in Data speichern
     ret  



Transmit:
    

                    ldi temp, 20
       wait1:
                    push temp
                    ldi temp, 200
       wait1_1:                               
                    nop
                    nop
                    nop
                    nop
                    nop
                    dec temp
                    brne wait1_1
                    pop temp
                    dec temp
                    brne wait1


       sbis UCSRA, UDRE                   ; Warten bis UDR ist
       rjmp Transmit
       out UDR, Data                      ; Data senden
     ret

       

header_init:

       cbi  PORTD, 5
    
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
    
     
     ldi  Data, 0x13
     rcall Transmit
    
    
     ldi     r30,LOW(Header)
       ldi     r31,HIGH(Header)
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren

       
header_receive:
       
     
       rcall Receive
     st Z+, Data
     
     dec Count
     brne header_receive
     
     ldi Data, 0x06
     rcall Transmit
     

     ldi Count, 16
     ldi r30,LOW(Content)
       ldi r31,HIGH(Content)
data_receive:
     rcall Receive
     st Z+, Data
     dec count
     brne data_receive

     ldi Data, 0x06
     rcall Transmit

       ldi Count, 50
     ldi r30,LOW(End_Header)
       ldi r31,HIGH(End_Header)

end_header_receive:
       
       rcall Receive
     st Z+, Data
     dec Count
     brne end_header_receive

     ldi Data, 0x06
     rcall Transmit



Check:

ldi r30,LOW(Content)
ldi r31,HIGH(Content)

ld r19, Z

brne Neustart

cbi  PORTD, 6


Neustart:


    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
    reti



.DSEG                                      ; das Folgende kommt ins SRAM
Header:     .BYTE  50
Content:    .BYTE  16
End_Header: .Byte  50




       


Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Quelltexte bitte als Anhang!

Autor: Flo S. (tuxianer)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
so es geht!!!! es lag allerdings nicht an fehlerhafter programmierung, 
sondern das das Rechner protokoll falsch ausgewertet wurde. und die 
variable an der Falschen stelle eingelesen wurde. hier nochmal das 
neuste:

Autor: Flo S. (tuxianer)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
so kaum ist das eine Problem gelöst hat man auch schon das nächste am 
Hals. ich wollte jetzt machen, das man mehrere Dioden via Rechner an und 
aus schalten kann...aber jetzt gehts nimmer. Das äusert sich in sofern, 
dass das prog einmal durchläuft auch ordentlich kommuniziert mit dem 
Reechner...aber keine Diode geht an. Und wenn ich dann ein zweites mal 
was sende was vorher ging kommt jetzt nen Error.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
keine ne Idee?

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was macht deine Check Routine?

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach ja und

       Ende:
     reti                               ; zurück zum Hauptprogramm

ist auch nicht so toll. da hast du wohl vergessen den Interrupt wieder 
einzuschalten oder?

Autor: Condi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vergiss das letzte

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die überprüft die vom Rechner gesendete Variable auf den einen Wert der 
dann die entsprechende LED aktiviert. Hä die ist doch schon aktiviert. 
Die wird dann nur später deaktiviert und am ende wieder aktiviert.


Also wenn ein Interrupt ausgelöst wird, aber die Bedingung nicht erfüllt 
ist springter inne Schleife. Interrupt ist aber noch aktiv...und wenns 
erfolgreich war springt er zu header_init und da wird sie deaktiviert 
und am ende aktiviert wenn die Übertragung komplett ist.

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florentin,

>die überprüft die vom Rechner gesendete Variable auf den einen Wert der
dann die entsprechende LED aktiviert.

Kannst Du das Programm vom GTR mal bitte in den Anhang stellen?

Dann kann man das evtl. hier mal nachvollziehen.


Danke
AxelR.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein Programm direkt ist es nicht zu Testzwecken sende ich nur mit dem 
Befehl:

2->A

also ich schreibe 2 in Variable A



und danach der Befehl:

Send (A)

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok ein Problem hätte ich gelöst...und zwar hatte ich immer nur versucht 
2 zu senden und genau die LED war falsch angeschlossen auf dem 
Steckbrett. Aber es bleibt immer noch das Problem, das es nicht mehr 
richtig weiter empfängt nach einer Übertragung und das ich auf dem 
Rechner immer nen Error erhalte. Ich vermute es springt nicht richtig 
zurück, weil ich weitere Unterroutinen Aufrufe.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und zwar im simulator springt er nach dem Anschalten der dieode via ret 
in diee loop. Da liegt das problem. Aber wison springt er nicht dorthin 
zurück, von wo die funktion aufgerufen wurde???

Autor: Flo S. (tuxianer)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
so...also es liegt daran das ret nicht wieder dahin zurückspringt, weil 
ich die Funkt, ja nicht mit call aufgerufen aheb das konnte garnicht 
gehen...so hier der Aktuelle Code:

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.