www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD-Display Stack-Fehler


Autor: Martin K. (spyro07)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich verusche ein LCD anzusteuern.
Das LCD ist leider noch nicht da, aber ich habe  beim Simulieren bemerkt 
das irgendwie der Stack überläuft.
Nachdem ich gleich nach der Stack-Initialisierung (nur zum Test) nachdem 
ich die Adresse in den z-Pointer geladen habe mit rcall lcd_send_Data 
das UP aufrufe.
Dort geht es auch noch durch, durch das weitere UP wait5ms geht es auch 
noch.
Dann wenn das ret von lcd_send_data ausgeführt wird, lande ich wieder 
bei init.

Woran liegt das?

Habe ich irgendwo veressen wieder ein Register zurück zu holen, oder 
derartiges?
Mir fällt nämlich da nichts auf, was ich vergessen haben könnte.

Wäre gut wenn mir da jemand helfen könnte.
;********************************:
;* Display-Ansteuerung ATMEGA16  *;
;*    PA0    DB4          *;   
;*   PA1  DB5          *;
;*   PA2  DB6          *;
;*   PA3  DB7          *;
;*   PA4  RS          *;
;*   PA5  E          *;
;********************************;  
.include   "m16def.inc"

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

.equ  LCD_PORT  =  PORTA
.equ  XTAL    =  16000000 

  rjmp init                 ; Reset Handler                           


init:
    ldi     temp, LOW(RAMEND)                ; Stackpointer initialisieren
     out     SPL, temp
     ldi     temp, HIGH(RAMEND)
    out     SPH, temp

  ldi    temp, $FF
  out    PORTA, temp

   ldi   ZL, LOW(menu*2)         ; Adresse des Strings in den
    ldi   ZH, HIGH(menu*2)        ; Z-Pointer laden
  rcall  lcd_text

lcd_init:
     ldi    temp,8          ; 30ms Power-On-Wait
powerupwait:
    rcall    delay5ms
    dec    temp
    brne   powerupwait
    
    ldi     temp, 0b00000010     ; pad byte
    out     LCD_PORT, temp
    rcall   lcd_enable
    rcall   delay50us
    rcall   lcd_enable
    rcall   delay50us
    rcall   lcd_enable
    rcall   delay50us


    ldi   temp, 0b01100000     ; function set
    rcall   lcd_command
    rcall   delay50us
   
    ldi   temp, 0b00001111     ; display on
    rcall   lcd_command
    rcall   delay50us

  rcall   lcd_clear

    ldi   temp, 0b00000111     ; entry mode set
    rcall   lcd_command
  rcall   delay50us

     ldi   ZL, LOW(menu*2)         ; Adresse des Strings in den
    ldi   ZH, HIGH(menu*2)        ; Z-Pointer laden
  rcall  lcd_text

loop:
 

  rjmp  loop 

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UP´s für LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Befehl an LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lcd_command:
  push  temp
  mov    temp, lcd_data                            ; wie lcd_data, nur ohne RS zu setzen
  mov     temp1, temp
    swap    temp1
    andi    temp1, 0b00001111
    out     LCD_PORT, temp1
    rcall   lcd_enable
    
  andi    temp, 0b00001111
    out     LCD_PORT, temp
    rcall   lcd_enable
    rcall   delay50us
    pop     temp
    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Datenbyte an LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;
lcd_send_data:
     push    temp
     push    temp1
   
     mov    temp, lcd_data  
     mov     temp1, temp            
                                   
     swap   temp1                  
     andi   temp1, 0b00001111       
     sbr   temp1, 4            
     out   LCD_PORT, temp1         
     rcall   lcd_enable                                                     ; 2. Nibble, kein swap da es schon
                                   
     andi   temp, 0b00001111        
     sbr   temp, 4             
     out   LCD_PORT, temp         
     rcall   lcd_enable             
     rcall   delay50us              
  ret         

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Befehl "Display löschen";;;;;;;;;;;;;;;;;;;;
lcd_clear:
  ldi   temp, 0b00000001   
    rcall   lcd_command
    rcall   delay5ms
    ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Befehl "Cursor Home";;;;;;;;;;;;;;;;;;;;;;;;
lcd_home:
    ldi   temp, 0b00000010   
    rcall   lcd_command
    rcall   delay5ms
    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LCD-Enable;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lcd_enable:
  nop
  nop
    sbi   LCD_PORT, 5                 
    nop                              
    nop
    nop
    cbi   LCD_PORT, 5  
  ret                          

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Text ausgeben;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lcd_text:
  
lcd_text1:
    lpm     lcd_data, Z+
    cpi     lcd_data, 0
    breq    lcd_text2
    rcall    lcd_send_data
    rjmp    lcd_text1
 
lcd_text2:
    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Dezimalzahl ausgeben;;;;;;;;;;;;;;;;;;;;;;;;;;
lcd_number:
  mov    temp, lcd_data
    push    temp
    push    temp1

    mov     temp1, temp
  
    ldi     temp, '0'-1     
lcd_number_1:
    inc     temp            
    subi    temp1, 100       
    brcc    lcd_number_1     
                          
    subi    temp1, -100      
  mov    lcd_data, temp
    rcall   lcd_send_data         
 
;** Zehner  **
    ldi     temp, '0'-1     
lcd_number_2:
    inc     temp            
    subi    temp1, 10        
    brcc    lcd_number_2     
    subi    temp1, -10
  
  mov    lcd_data, temp
    rcall   lcd_send_data           ; die Zehnerstelle ausgeben
 
;** Einer **        
    ldi     temp, '0'       
    add     temp, temp1  
  mov    lcd_data, temp   
    rcall   lcd_send_data         
    pop     temp1   
  pop    temp
    ret   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50us Pause;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay50us:          
  push  temp  
  push  temp1
delay50us_1:                         
  ldi    temp, 0
delay50us_2:
    dec    temp
    brne   delay50us_2
  inc    temp1  
  cpi    temp1, 4
  brne  delay50us_1
  
  pop    temp1
  pop   temp
    ret                                   

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5ms Pause;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay5ms:  
  push  temp
  push  temp1                         
    ldi    temp, $86
delay5ms_1:  
  ldi    temp1, $C6
delay5ms_2:  
  dec    temp1
    brne   delay5ms_2
    dec    temp
    brne   delay5ms_1
  pop    temp1
  pop   temp
    ret 
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;        
             ;              
 

menu:
           .db "~~~~Herzlich~~~~~~~Willkommen~~~", 0

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>lcd_send_data:
>     push    temp
>     push    temp1
.........
>     rcall   lcd_enable
>     rcall   delay50us
>  ret

MfG Spess

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles was du per PUSH auf den Stack beförderst mußt du auch vor dem 
RET wieder vom Stack per POP anholen.
Und wenn du dir mal deine Routine anschust siehst du: Da fehlt doch 
was...

Autor: Martin K. (spyro07)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, vielen Dank, dass habe ich nämlich nicht gesehn.
Problem gelöst.

mfg

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.