www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Powertip PG12864A - Problem mit Chipselect


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Powertip PG12864A Display mit 128x64 Pixeln an mein Pollin 
Evaluationsboard angeschlossen. Das Display wird über einen ATmega 8 
angesteuert.
Mein Problem ist nun, dass ich auf der linken Displayhälfte(CS1 = high) 
normal schreiben kann, wenn ich jedoch auf der rechten Displayhälfte 
schreiben will(CS2 = high), wird ebenfalls auf der linken Seite 
geschrieben, allerdings nicht genau die selben Pixelmuster sondern 
irgendwas komisches. Als Test hab ich z.b. ein Byte 10101010 übertragen, 
welches auf der rechten Hälfte so angezeigt wird, auf der linken jedoch 
00111111.
Wenn ich aber beide Chips anspreche, also CS1 und CS2 high, 
funktionieren beide Hälften wie gewollt.

Im Programm habe ich schon CS1 und CS2 vertauscht, daran kann es 
normalerweise nicht liegen, und auch irgendwelche Zusatzfunktionen an 
den Ports C und D, welche ich abschalten müsste, habe ich nicht 
gefunden.

Hier mein Code, am Anfang stehen auch direkt die Pinzuordnungen zum 
Display.
.include "m8def.inc"

.def temp = r16
.def param = r17
.def counter = r18
.def counter2 = r19
.def addreg = r20

.equ LCD_DP = PORTD    ;LCD Data Port
.equ LCD_DPD = DDRD    ;LCD Data Port Direction

.equ LCD_CP = PORTC    ;LCD Control Port
.equ LCD_CPD = DDRC    ;LCD Control Port Direction

.equ LCD_RS = PORTC0  ;LCD Register Select Pin
.equ LCD_RW = PORTC2  ;LCD Read/Write Pin
.equ LCD_EN = PORTC1  ;LCD Enable Pin
.equ LCD_CS1 = PORTC3  ;LCD Chip Select 1 Pin
.equ LCD_CS2 = PORTC4  ;LCD Chip Select 2 Pin
.equ LCD_RE = PORTC5  ;LCD Reset Pin



.org 0x000
  rjmp reset



reset:

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

    ldi temp, 0xFF
    out LCD_DPD, temp    ;LCD Data Port als Ausgang setzen

    ldi temp, 0x00
    out LCD_DP, temp

    ldi temp, 0xFF
    out LCD_CPD, temp    ;LCD Control Port als Ausgang setzen

    ldi addreg, 1

    ldi temp, (1<<LCD_RE)
    out LCD_DP, temp

    ldi param, 0xFF      ;0x10 = 460 µs*4 / 0xFF = 34ms*4
    rcall wait_ms

    rcall LCD_clear
    rcall LCD_init

    ldi counter, 0
    


loop:
    ldi temp, 0b01010101
    out LCD_DP, temp
    rcall LCD_data_both
    add counter, addreg
    cpi counter, 65
    brsh nop_loop

    rjmp loop

nop_loop:
    rjmp nop_loop


wait_ms:
    push temp
    mov temp, param
    push param
    cpi temp, 0
    breq wait_ms_end

    subi temp, 1
    mov param, temp
    rcall wait_ms

    wait_ms_loop:
    subi temp, 1
    cpi temp, 0
    brne wait_ms_loop

    wait_ms_end:
    pop param
    pop temp
    ret

LCD_init:
    push temp

    ldi temp, 0b00111111
    out LCD_DP, temp
    rcall LCD_command

    ldi param, 0
    rcall LCD_set_x

    ldi param, 2
    rcall LCD_set_page

    ldi param, 0
    rcall LCD_set_start

    pop temp
    ret

LCD_set_x:
    push temp
    mov temp, param

    ori temp, 0b01000000
    out LCD_DP, temp
    rcall LCD_command

    pop temp
    ret

LCD_set_page:
    push temp
    mov temp, param

    ori temp, 0b10111000
    out LCD_DP, temp
    rcall LCD_command

    pop temp
    ret

LCD_set_start:
    push temp
    mov temp, param

    ori temp, 0b11000000
    out LCD_DP, temp
    rcall LCD_command

    pop temp
    ret

LCD_clear:
    push temp
    push counter
    push counter2

    ldi counter, 0
    ldi counter2, 0
    ldi param, 0
    rcall LCD_set_x
    rcall LCD_set_page
    rcall LCD_set_start

    LCD_clear_loop:
      add counter, addreg
      ldi temp, 0b11111111
      out LCD_DP, temp
      rcall LCD_data_both
      cpi counter, 64
      brlo LCD_clear_loop
    
    add counter2, addreg
    mov param, counter2
    rcall LCD_set_page
    ldi counter, 0
    cpi counter2, 8
    brlo LCD_clear_loop

    pop counter2
    pop counter
    pop temp
    ret

LCD_command:
    push temp
    push param

    ldi temp, (1<<LCD_RE) | (1<<LCD_EN) | (1<<LCD_CS1) | (1<<LCD_CS2)
    out LCD_CP, temp
    ldi param, 0x05
    rcall wait_ms
    ldi temp, (1<<LCD_RE)
    out LCD_CP, temp

    pop param
    pop temp
    ret

LCD_data_one:
    push param    

    ldi param, (1<<LCD_CS1)
    rcall LCD_data

    pop param
    ret

LCD_data_two:
    push param    

    ldi param, (1<<LCD_CS2)
    rcall LCD_data

    pop param
    ret

LCD_data_both:
    push param    

    ldi param, (1<<LCD_CS1) | (1<<LCD_CS2)
    rcall LCD_data

    pop param
    ret

LCD_data:
    push temp

    mov temp, param
    ori temp, (1<<LCD_RE) | (1<<LCD_EN) | (1<<LCD_RS)
    out LCD_CP, temp
    push param
    ldi param, 0x05
    rcall wait_ms
    ldi temp, (1<<LCD_RE)
    out LCD_CP, temp

    pop param
    pop temp
    ret

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner eine Lösung? Oder irritiert der Code? Der Code ist glaube ich 
garnicht so wichtig, daran dürfte es eigentlich nicht liegen.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ich habe das Problem nun ein wenig eingegrenzt:

Folgenden Code habe ich in der Schleife:
lpm temp, Z+
    
    ;ldi param, 3
    ;rcall LCD_set_page
    mov param, counter
    rcall LCD_set_x
    out LCD_DP, temp
    rcall LCD_data_two


    
    add counter, addreg
    cpi counter, 54
    brsh nop_loop

Dies funktioniert nicht, auf der rechten Seite werden die gewünschten 
Daten geschrieben (Buchstaben, tut aber nichts zur Sache) und links(also 
linke Hälfte) werden komische Zeichen ausgegeben. Dabei ist mir 
aufgefallen, dass jeweils der Befehl, der vorher durch den Aufruf "rcall 
LCD_set_x" übertragen wurde, angezeigt wird, also als ob man das falsche 
Register gewählt hat. Dummerweise werden die Register in der 
Befehlsroutine nichtmal angerührt, und ich bin mir ziemlich sicher dass 
das Register korrekt ist.
Allerdings werden bei einem Befehl immer beide Chips angesprochen, 
während die Schreiboperation danach nur den zweiten anspricht. Testweise 
habe ich beim Befehl auch mal nur den zweiten Chip angesprochen, dann 
wird es korrekt angezeigt. Allerdings sollte es auch so gehen, dass 
beide Chips den Befehl mitkriegen.

Hauptproblem ist im Moment also, dass auf irgendeine komische Art und 
Weise die Befehlsdaten im falschen Register landen...

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Vielleicht solltest du mal das Timing überarbeiten. RS,RW und CS sollten 
gesetzt werden, bevor E auf H  und nachdem E wieder auf L gesetzt wird.

MfG Spess

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja habs jetzt eh gelöst, indem ich einfach ein globales Chipselect 
Register gemacht habe, dass dann immer in den aufrufen für Befehl bzw. 
Daten benutzt wird. Das muss man dann halt vor dem jeweiligen Aufruf 
setzen, aber dadurch spart man sich quasi die ganzen Prozeduren für Chip 
1 und Chip 2 und hat eine allgemeine.

Das Timing werde ich trotzdem überarbeiten, ist sicherer...

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.