Forum: Mikrocontroller und Digitale Elektronik DVM mit Quasi-Analoganzeige, ATMEGA8, ASM


von Klaus D. (klaus38)



Lesenswert?

Geschätztes Forum,

als Anfänger habe ich versucht, mich mit folgenden Themen vertraut zu 
machen:

ADC
LCD mit CGRAM
Timer

Ich benutze einen ATMEGA8A-PU und programmiere in Assembler in Studio 4.

Aktuell arbeite ich am Modell eines DVM. Die gemessene Spannung wird in 
Line 1 angezeigt. In Line 2 wird eine Quasi-Analoganzeige mit 0 bis 80 
'Balken' ausgegeben. Das ergibt sich aus 16 Zeichen pro Zeile zu je 5 
Punkten bei 5x7 Dot Matrix.

Bei Verwendung des LCD CP594V-0 funktioniert das auch prima. Weil dieses 
LCD aber so hässlich und klobig ist, würde ich gerne ein LCD DOGM162W-A 
verwenden. Schon bei der Initialisierung desselben musste ich mich ganz 
schön quälen (wer keine anderen Sorgen hat der macht sich welche), habe 
es aber schliesslich hinbekommen. Bei der 4-Bit-Verdrahtung sowie 
Assembler findet man praktisch keine Hilfe im Internet, im Gegensatz zur 
SPI-Verdrahtung und C. Mit SPI möchte ich mich erst später beschäftigen, 
mit C gar nicht.

------------------------------------------------------------------------ 
---
Hilferuf:

Was mir aber beim DOGM162W-A trotz aller Mühen nicht gelingt, das ist 
die Quasi-Analoganzeige in Line 2. Dabei gibt es aber kein Problem mit 
der Line 2 selbst: Ausgaben dahin gelingen einwandfrei. Das Problem 
liegt mit grosser Sicherheit beim CGRAM. Entweder beschreibe ich es 
nicht richtig oder lese es nicht richtig aus oder beides. Wenn mir hier 
jemand helfen würde, wäre ich wirklich dankbar.

DOGM162W-A.asm, Labels 'CGRam'  bis 'Symbole': Beschreiben des CGRAM
DOGM162W-A.asm, Labels 'Loop70' bis 'Loop780': Definition der 
auszugebenden 'Felder', 'Balken' und Blanks
DOGM162W-A.asm, Labels 'Loop80' bis 'Loop85' : Ausgabe der 'Felder', 
'Balken' und Blanks in die Line 2

Der Controller des LCD DOGM162W-A heisst ST7036. Die Adressierung des 
CGRAM ist im Datenblatt auf Seite 34 zu finden:

* Set CGRAM Address

RS   RW   DB7  DB6  DB5  DB4  DB3  DB2  DB1  DB0
 0    0    0    1   AC5  AC4  AC3  AC2  AC1  AC0

Set CGRAM address to AC.
This instruction makes CGRAM data available from MPU.

Weil mir diese Adressierung offensichtlich nicht gelingt, habe ich den 
Text zu den o.g. Labels gegenüber dem Text CP594V-0.asm hier unverändert 
gelassen. Beim LCD CP594V-0 funktioniert es genau so, beim LCD 
DOGM162V-0 aber nicht. Hier muss man demnach noch die Adressierung 
einfliessen lassen. Das habe ich natürlich auf jede Weise, die mir 
eingefallen ist, versucht. Ohne jeden Erfolg.
------------------------------------------------------------------------ 
---

Bisher realisierte Funktionen des DVM:

DC Range: AUTO
DC Range:   0.25 V
DC Range:   2.5  V
DC Range:  25    V
DC Range: 250    V
AC Range: AUTO
AC Range:   0.25 V
AC Range:   2.5  V
AC Range:  25    V
AC Range: 250    V

Diese Funktionen sind mittels einer Taste wählbar. Falls nicht 'AUTO' 
gewählt wurde und die zu messende Spannung den Maximalwert [(2 ^ 10 – 1) 
* 25 = 25575] erreicht oder überschreitet, erscheint 'OVERFLOW' in der 
Line 2 statt der Quasi-Analoganzeige. Bei der Wahl von 'AUTO' wird 
natürlich jeweils der nächst höhere Messbereich eingeschaltet. 
'OVERFLOW' erscheint dann erst bei Erreichen von 255.75 V.

Noch zu realisierende Funktionen (nach vorläufigem Stand):

* Vielfachablesung der zu messenden Spannung ohne Änderung der 
Auflösung.
* Korrekturberechnungen derart, dass die "Genauigkeit" von 10 Bit 
möglichst erreicht wird.
* Überwachung der Versorgungsspannung (Alkali-Zellen oder Akkus).
* Durchgangs-Prüfer.

Insbesondere der lt. Literatur angeblich "ideale" Gleichrichter für die 
AC Messung verschiebt und verbiegt die Kalibrierkurven erheblich. Auch 
der Multiplexer CD4066 ist umso stärker an Ungenauigkeiten beteiligt, je 
niederohmiger die OP Rückkopplung ist, weil die Schalter des CD4066 
einen nicht ganz stabilen Innenwiderstand von ca. 130 Ohm haben. Der ADC 
der MPU selbst ist auch nicht gerade von BURR-BROWN.

Kalibrierung und Ausgleichsberechnungen aufgrund der Ergebnisse sind 
aber erst nach Aufbau eines fest verdrahteten Modells möglich. Die 
Kontakte des bis jetzt verwendeten Steckbrett-Modells verändern ihre 
Übergangswiderstände bei jeder Bewegung erheblich.

Die ASM-Dateien sind sehr sorgfältig kommentiert sowie in primitivster 
Logik ohne alle Tricks erstellt. Einem erfahrenen Programmierer dürften 
die Haare zu Berge stehen, aber so ist halt mein gegenwärtiger 
Wissensstand.

Nach dem Entzippen der Datei <DVM mit Quasi-Analoganzeige.zip> in einem 
Directory ergibt sich folgende Anordnung von Dateien:


\CP594V-0\AvrBuild.bat
   \CP594V-0.aps
   \CP594V-0.asm
   \CP594V-0.aws
   \CP594V-0.hex
   \CP594V-0.map
   \CP594V-0.obj
\DOGM162W-A\AvrBuild.bat
     \DOGM162W-A.aps
     \DOGM162W-A.asm
     \dogm162w-a.aws
     \DOGM162W-A.hex
     \DOGM162W-A.map
     \DOGM162W-A.obj
\DSC22492.pdf
\DSC22493.pdf
\DVM mit Quasi-Analoganzeige.zip
\Versuchsaufbau 1.pdf
\Versuchsaufbau 2.pdf
\Versuchsaufbau 3.pdf
\Versuchsaufbau.spl7

Die Datei 'Versuchsaufbau.spl7' kann mittels des Programms ABACOM sPlan7 
editiert werden. Sie enthält die Schaltpläne entspr. Versuchsaufbau 
1.pdf  bis Versuchsaufbau 3.pdf.

Die ZIP-Datei wurde mittels 7-Zip erstellt.

Der 'sPlan 7.0 Viewer' ist kostenlos erhältlich bei 
www.abacom-online.de/

Ich hoffe sehr auf Eure Hilfe bei menem Problem mit dem CGROM des LCD 
DOGM162W-A.

Für jede Mühe danke ich ganz herzlich.

Klaus

von MWS (Gast)


Lesenswert?

Warst Dir jetzt nicht sicher, was Du machen sollst, Projektvorstellung 
oder Frage? Deine Frage ging dabei weitestgehend unter.

Klaus D. schrieb:
> Entweder beschreibe ich es
> nicht richtig oder lese es nicht richtig aus oder beides.

Da die Routine CGRam in DOGM162W-A.asm nirgends aufgerufen wird, enthält 
das Icon Ram auch nichts.

Und hierzu:

Klaus D. schrieb:
> Einem erfahrenen Programmierer dürften
> die Haare zu Berge stehen

Ja. ;D

von Klaus D. (klaus38)


Lesenswert?

Hallo MWS,

vielen Dank für Deine Antwort. Der eigentliche Grund meines Beitrags ist 
die Frage nach dem Schreiben ins und dem Auslesen aus dem CGRAM des LCDs 
DOGM162W-A. Mit der Vorstellung des Gesamtprojektes bin ich sicherlich 
übers Ziel hinausgeschossen.

Deine Rüge, im File DOGM162-A.asm würde die Routine CGRam nirgends 
aufgerufen, ist korrekt. Der Grund dafür ist aber einfach: Wenn sie 
aufgerufen wird, dann funktioniert sie nicht oder, falls sie doch 
funktionieren sollte, dann funktioniert meine Version des Auslesens 
nicht.

Der Aufruf würde wie folgt erfolgen:

    rcall  LCD_init
    rcall  LCD_clear
    rcall  CGRam        ; <---
    rjmp   Loop010      ; First check of the Measuring Range
;-----------------------------------------------------------------------
; Main Loop
Loop:
    sei                 ; Allow Interrupt

nur funktioniert es beim LCD DOGM162W-A leider nicht.
Beim LCD CP594V-0 funktioniert es einwandfrei.

Unterschiedlich sind die Controller der LCDs:
DOGM162W-A Controller: ST7036
CP594V-0   Controller: KS0070B

Für Hilfe bei meinem Problem wäre ich wirklich sehr dankbar.

Nachfolgend die relevanten Programmzeilen:

;-----------------------------------------------------------------------
; Zeichen ins CGRAM des LCD schreiben

CGRam:
    sbi    PORTD  ,  4        ; RS
    ldi    R16    ,  0b00000000
    out    PORTD  ,  R16

    ldi    ZL     ,  LOW(Symbole*2)
    ldi    ZH     ,  HIGH(Symbole*2)
CGRam1:
    lpm    R16    ,  Z+
    cpi    R16    ,  253
    breq   CGRam2
    rcall  LCD_cmd
    lpm    R16    ,  Z+
    cpi    R16    ,  253
    breq   CGRam2
    rcall  LCD_data
    rjmp   CGRam1
CGRam2:
    cbi    PORTD  ,  4        ; RS
    ret

;-----------------------------------------------------------------------
; Zeichen fürs CGRAM des LCD

Symbole:
    .db  64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0
    .db  72,0,73,0,74,0,75,16,76,16,77,16,78,0,79,0
    .db  80,0,81,0,82,0,83,24,84,24,85,24,86,0,87,0
    .db  88,0,89,0,90,0,91,28,92,28,93,28,94,0,95,0
    .db  96,0,97,0,98,0,99,30,100,30,101,30,102,0,103,0
    .db  104,0,105,0,106,0,107,31,108,31,109,31,110,0,111,0,253,0

;-----------------------------------------------------------------------



;-----------------------------------------------------------------------
; Ausgabe LCD Zeile 2: Löschen der LCD Zeile 2 durch Ausgabe von Blanks
; wenn R22 = 0 und R23 = 0 bzw. Ausgabe der Balken, falls U_Mess > 0

Loop80:
    tst    R23              ;
    brne  Loop81            ; R23 > 0 oder/und R22 > 0 ?
    tst    R22              ; dann ist U_Mess > 0
    brne  Loop81            ; und Balken werden in der LCD Zeile 2
                            ; ausgegeben
    rcall  LCD_line2
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    ldi    R16    ,  ' '
    rcall  LCD_data
    rjmp   Loop
Loop81:
    cbr    R19    ,  0b11000000
    rcall  LCD_line2
Loop82:                    ; Felder, 0 ... 15
    cpi    R19    ,  0
    breq   Loop83
    ldi    R16    ,  5
    rcall  LCD_data
    dec    R19
    tst    R19
    brne   Loop82
Loop83:                    ; Balken, 1 ... 5
    cpi    R20    ,  1
    breq   Loop831
    cpi    R20    ,  2
    breq   Loop832
    cpi    R20    ,  3
    breq   Loop833
    cpi    R20    ,  4
    breq   Loop834
    cpi    R20    ,  5
    breq   Loop835
Loop831:                  ; 1 Balken
    ldi    R16    ,  1
    rcall  LCD_data
    rjmp   Loop84
Loop832:                  ; 2 Balken
    ldi    R16    ,  2
    rcall  LCD_data
    rjmp   Loop84
Loop833:                  ; 3 Balken
    ldi    R16    ,  3
    rcall  LCD_data
    rjmp   Loop84
Loop834:                  ; 4 Balken
    ldi    R16    ,  4
    rcall  LCD_data
    rjmp   Loop84
Loop835:                  ; 5 Balken
    ldi    R16    ,  5
    rcall  LCD_data
    rjmp   Loop84
Loop84:                    ; Blanks, 15 ... 0
    cpi    R21    ,  0
    breq   Loop85
    ldi    R16    ,  0
    rcall  LCD_data
    dec    R21
    tst    R21
    brne   Loop84
Loop85:
    rjmp  Loop

;-----------------------------------------------------------------------

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.