Forum: Mikrocontroller und Digitale Elektronik PIC16 Segmentdisplay


von Birgit P. (bpie)


Lesenswert?

Hallo.

Ich habe gerade angefangen mich mich PIC Prozessoren zu beschäftigen und 
versuche nun einen PIC16F1947 dazu zu bringen, ein Segmentdisplay und 
eine Hintergrundbeleuchtung für das Display anzusteuern.
Beides einzeln ist auch kein Problem.
Wenn allerdings beides parallel laufen soll, funktioniert es nicht.

Das Problem:
Ich muss einen nicht mit dem Display verbundenen Segment-Pin in dem 
Register LCDSEx aktivieren, damit die Segmente auf dem Display 
angesteuert werden. Dieser Pin soll aber für die PWM genutzt werden.
Ach sehr kurios: Das Phänomen wandert mit. Ich hatte zunächst CCP1 an 
die PWM angeschlossen und musste dann SEG13 aktivieren (obwohl nicht für 
das Display verwendet). Dann hatte ich CCP2 angeschlossen und musste 
SEG32 aktivieren (obwohl nicht für das Display verwendet).
Dieses Verhalten tritt aber auch auf, wenn gar keine PWM initialisiert 
wird.
Anschließend habe ich die Verbindung des PWM/SEG-Pin zur 
Hintergrundbeleuchtung getrennt, dann wurde garnichts mehr am Display 
angezeigt. Egal wie der SEG32 oder SEG13 Pin im LCDSEx-Register gesetzt 
war.
Dafür funktioniert dieses Phänomen nun mit einem anderen Pin, auf dem 
die Funktion des SPI-CLK liegt. SPI ist allerdings nicht initialisiert, 
der PIN ist als Input konfiguriert.

Hat vielleicht schon mal jmd. dieses oder ein ähnliches Problem gehabt?

Als Display verwende ich ein Musterdisplay von ADKOM mit nur einer 
COM-Leitung und 20 Segmenten.

Hier noch kurz die Initialisierung des Displays:
1
 
2
void init_dspl (void)
3
{
4
    //frame clock prescale LCDPS LP<3:0>
5
    LCDPSbits.LP=0x00; //1:1
6
7
    //configure LCDSEn (1=segment function enabled)
8
    LCDSE0=0xFF; //SE0-7                    0-7
9
    LCDSE1=0xCE; //x,9,10,11,x,x,14,15      8-15  
10
    LCDSE2=0xFC; //x,x,18,19,20,21,22,23    16-23
11
    LCDSE3=0x01; //24,x,x,x,x,x,x,x         24-31
12
    //LCDSE4=0x01; //SEG32 
13
14
15
    //configure LCD LCDCON
16
      //Multiplex&bias LMUX<1:0>
17
    LCDCONbits.LMUX=0; //static
18
      //Timing source CS<1:0>
19
    LCDCONbits.CS=0; //Focs/256
20
      //Sleep mode SLPEN
21
    LCDCONbits.SLPEN=1; //disabled in sleep mode
22
23
    //initial pixel values LCDDATA0 bis LCDDATAx: clear
24
    LCDDATA0=0;
25
    LCDDATA1=0x00;
26
    LCDDATA2=0x00;
27
    LCDDATA12=0x00;
28
    LCDDATA13=0x00;
29
30
    //clear interrupt flag PIR2 LCDIF
31
    PIR2bits.LCDIF = 0;
32
33
    //bias voltages LCDRL, LCDREF, ANSELx
34
    //ANSEL werden bereits in der main auf i/o gesetzt
35
    //LCDRL ?
36
    LCDREFbits.LCDIRE=1; //intern
37
    LCDREFbits.LCDIRS=0; //Vdd
38
39
40
    //enable LCD LCDCON LCDEN
41
    LCDCONbits.LCDEN=1; //enabled
42
    
43
}


Anschließend werden nur noch die Register LCDDATA0, LCDDATA1, LCDDATA2 
und LCDDATA12 gesetzt, je nachdem welche Segmente angesteuert werden 
sollen.

Hat jemand eine Idee?

Gruß.

von Andreas H. (ahz)


Lesenswert?

Birgit Pie schrieb:
> Hat jemand eine Idee?

Ja:

!!! LIES DAS DATENBLATT !!!  ;-)

Z.B.:

> Ich hatte zunächst CCP1 an
> die PWM angeschlossen und musste dann SEG13 aktivieren (obwohl nicht für
> das Display verwendet).

Aus dem PIC16(L)F1946/47 Datasheet, Seite 6/7 siehst Du, dass CCP1 und 
SEG13 (per default) auf dem gleichen (physikalischen) Pin liegen.

CCP1 kannst Du aber auch auf einen anderen Pin umlegen. Das wird in 
Kapitel 12 erklärt.

Grüße
Andreas

von Birgit P. (bpie)


Lesenswert?

> Ja:
>
> !!! LIES DAS DATENBLATT !!!  ;-)

Das habe ich schon rauf und runter gelesen, keine Sorge.

> Z.B.:
>
>> Ich hatte zunächst CCP1 an
>> die PWM angeschlossen und musste dann SEG13 aktivieren (obwohl nicht für
>> das Display verwendet).
>
> Aus dem PIC16(L)F1946/47 Datasheet, Seite 6/7 siehst Du, dass CCP1 und
> SEG13 (per default) auf dem gleichen (physikalischen) Pin liegen.

Das weiß ich. SEG13 ist aber garnicht am Display angeschlossen, sollte 
also eigentlich für die PWM-Funktion frei sein. Oder kann ich alle 
SEG-Pins nicht benutzen, nur weil der LCD-Treiber aktiviert wurde? Den 
Hinweis habe ich im Datenblatt nämlich nicht gefunden, kann ich mir auch 
nur schwer vorstellen.

>
> CCP1 kannst Du aber auch auf einen anderen Pin umlegen. Das wird in
> Kapitel 12 erklärt.

Damit meinst du das:?
1
bit 1 P1CSEL: CCP1 PWM C Output Pin Selection bit
2
 0 = P1C function is on RE5/P1C/COM2
3
 1 = P1C function is on RD5/P1C/SEG5
4
bit 0 P1BSEL: CCP1 PWM B Output Pin Selection bit
5
 0 = P1B function is on RE6/P1B/COM3
6
 1 = P1B function is on RD6/P1B/SEG6
Das habe ich noch nicht ausprobiert, nutzt mir aber auch nichts, wenn 
ich einen nicht verwendeten LCD-Pin nicht für andere Dinge verwenden 
kann.


>
> Grüße
> Andreas

von Andreas H. (ahz)


Lesenswert?

Birgit Pie schrieb:
> Das weiß ich. SEG13 ist aber garnicht am Display angeschlossen, sollte
> also eigentlich für die PWM-Funktion frei sein. Oder kann ich alle
> SEG-Pins nicht benutzen, nur weil der LCD-Treiber aktiviert wurde? Den
> Hinweis habe ich im Datenblatt nämlich nicht gefunden, kann ich mir auch
> nur schwer vorstellen.

Seite 350 im DS sagt:
"27.8 Segment Enables
The LCDSEn registers are used to select the pin
function for each segment pin. The selection allows
each pin to operate as either an LCD segment driver or
as one of the pin’s alternate functions."

Es wäre im Zweifelsfall hilfreich, wenn Du mal den Schaltplan & den 
KOMPLETTEN Code posten könntest.

Ich vermute im Moment etwas anderes:
Die PWM scheint ja prinzipiell irgendwie (!) zu pulsen, denn es ist ja 
erst wirklich dunkel, wenn Du den PWM Pin abtrennst.

Wenn Du aber sagst Du musst das LCDSEn des PWM Pins setzen, damit etwas 
erscheint, dann vermute ich einen Fehler in der Initialierung des PWM 
Counters.
Dann würde die PWM nämlich NICHT gehen, also nichts sichtbar.
Mit LCDSEn=1 würdest Du aber das entsprechende Pixel als PWM Signal 
missbrauchen.

Hast Du ein Scope ? Dann mess mal mit dem aktuellen Programm die PWM. 
Danach änderst Du das Programm so, das das LCD KOMPLETT aus ist (LCDEN=0 
sollte reichen, ggf. noch alle LCDSE=0 setzen). Ist Deine "PWM" noch da 
?

Grüße
Andreas

von Birgit P. (bpie)


Angehängte Dateien:

Lesenswert?

Andreas H. schrieb:
> Birgit Pie schrieb:
>> Das weiß ich. SEG13 ist aber garnicht am Display angeschlossen, sollte
>> also eigentlich für die PWM-Funktion frei sein. Oder kann ich alle
>> SEG-Pins nicht benutzen, nur weil der LCD-Treiber aktiviert wurde? Den
>> Hinweis habe ich im Datenblatt nämlich nicht gefunden, kann ich mir auch
>> nur schwer vorstellen.
>
> Seite 350 im DS sagt:
> "27.8 Segment Enables
> The LCDSEn registers are used to select the pin
> function for each segment pin. The selection allows
> each pin to operate as either an LCD segment driver or
> as one of the pin’s alternate functions."

Genau, also müsste doch neben dem Display auch noch andere Sachen 
laufen.

> Es wäre im Zweifelsfall hilfreich, wenn Du mal den Schaltplan & den
> KOMPLETTEN Code posten könntest.
>
> Ich vermute im Moment etwas anderes:
> Die PWM scheint ja prinzipiell irgendwie (!) zu pulsen, denn es ist ja
> erst wirklich dunkel, wenn Du den PWM Pin abtrennst.
>
> Wenn Du aber sagst Du musst das LCDSEn des PWM Pins setzen, damit etwas
> erscheint, dann vermute ich einen Fehler in der Initialierung des PWM
> Counters.
> Dann würde die PWM nämlich NICHT gehen, also nichts sichtbar.
> Mit LCDSEn=1 würdest Du aber das entsprechende Pixel als PWM Signal
> missbrauchen.
>
> Hast Du ein Scope ? Dann mess mal mit dem aktuellen Programm die PWM.
> Danach änderst Du das Programm so, das das LCD KOMPLETT aus ist (LCDEN=0
> sollte reichen, ggf. noch alle LCDSE=0 setzen). Ist Deine "PWM" noch da
> ?



Ich glaube ich muss das Problem vielleicht nochmal erläutern. Eventuell 
habe ich mich unglücklich ausgedrückt, oder es ist falsch rüber 
gekommen.

Es ist so:
Die PWM (CCP2, da ja umgelegt von CCP1)funktioniert, auch nicht nur 
irgendwie, alles wie es sein soll.
Sie funktioniert nur dann nicht mehr, wenn ich die parallele 
SEG32-Funktion im LCDSE4 aktiviere. Das ist dann auch nachvollziebar.

Das eigentliche Problem vermute ich eher auf der Seite des 
Displays.(Kann mich aber auch irren ;-) )
(Die aktiven Segmente sieht man auch ohne angeschaltete PWM, sodass die 
nicht notwenig ist zum Test.)
Beim Display ist es so, dass ich wie gesagt alle Segmente ansteuern 
kann, aber nur, wenn RC1 als SEG-Pin gesetzt ist.

Ist er das nicht, ist dort die PWM zu sehen, aber die Segmente sind weg.
Ich versuche mal es übersichtlich zusammenzufassen:

LCDCON.LCDEN=1 & LCDSE4.SE32=1: am PWM-Pin liegt das Ansteuersignal der 
Segmente an, Displaysegmente sind sichtbar
An den Displaypins liegt eine Rechteckspannung an, die kurzzeitig auf 
low gezogen wird, wenn der Pin angesteuert wird.

LCDCON.LCDEN=1 & LCDSE4.SE32=0: PWM läuft, Displaysegmente sind nicht 
sichtbar
An den Displaypins liegt keine Rechteckspannung an, der Pin ist die 
ganze Zeit auf low.

LCDCON.LCDEN=0 & LCDSE4.SE32=1: PWM läuft, 2 Displaysegmente sind 
sichtbar (Pegel ist statisch high)

LCDCON.LCDEN=0 & LCDSE4.SE32=0: PWM läuft, 2 Displaysegmente sind 
sichtbar (Pegel ist statisch high)

Wenn bei LCDCON.LCDEN=0 auch alle LSCDEx=0 sind, gibt es keine 
Änderungen.


Ich hoffe, das macht mein Problem etwas klarer ;-)


>Gruß
> Andreas

Danke schon mal für deine Mühen.

von Andreas H. (ahz)


Lesenswert?

Birgit Pie schrieb:
> Ich glaube ich muss das Problem vielleicht nochmal erläutern. Eventuell
> habe ich mich unglücklich ausgedrückt, oder es ist falsch rüber
> gekommen.
>
Es kann sicher nicht schaden :-)
Jetzt habe ich auch mehr Ruhe als auf Arbeit.

> Es ist so:
> Die PWM (CCP2, da ja umgelegt von CCP1)funktioniert, auch nicht nur
> irgendwie, alles wie es sein soll.
> Sie funktioniert nur dann nicht mehr, wenn ich die parallele
> SEG32-Funktion im LCDSE4 aktiviere. Das ist dann auch nachvollziebar.
Ja.

>
> Das eigentliche Problem vermute ich eher auf der Seite des
> Displays.(Kann mich aber auch irren ;-) )

Kann ich mir eigentlich nicht vorstellen. Dann dürfte es nicht abhängig 
von irgendwelchen uP Settings sein.
Und Du hast ja Settings wo die Segmente funktionieren (btw.: ALLE 20 
Segmente ? Du hast ja nur die Baseroutinen, nicht aber Main, Device-Init 
oder Testroutinen gepostet).

Ein LCD ist ja eigentlich verhältnismäßig einfach anzusteuern. 
Insbesondere, wenn Du nur einen COM hast.

> (Die aktiven Segmente sieht man auch ohne angeschaltete PWM, sodass die
> nicht notwenig ist zum Test.)
> Beim Display ist es so, dass ich wie gesagt alle Segmente ansteuern
> kann, aber nur, wenn RC1 als SEG-Pin gesetzt ist.
>
> Ist er das nicht, ist dort die PWM zu sehen, aber die Segmente sind weg.

Also an dem Pin können vier Signale werkeln (absteigende Prio):
T1OSI (Timer1 Oscillator)   <-- Ist der SICHER INAKTIV ?
CCP2/P2A                    <-- Hat also Vorrang vor SEG32
SEG32 (ICD)                 <-- Sollte sowieso nicht mehr wirken, wenn 
CCP2 aktiv ist
RC1                         <-- Sollte eigentlich in der Initialisierung 
TRIS1=0 von Dir gesetzt worden sein.


> Ich versuche mal es übersichtlich zusammenzufassen:
>
> LCDCON.LCDEN=1 & LCDSE4.SE32=1: am PWM-Pin liegt das Ansteuersignal der
> Segmente an, Displaysegmente sind sichtbar
> An den Displaypins liegt eine Rechteckspannung an, die kurzzeitig auf
> low gezogen wird, wenn der Pin angesteuert wird.

Bist Du hier 100% sicher ? Lt. Datenblatt würde (s.o.) das PWM Signal 
immer den Pin überschreiben.

>
> LCDCON.LCDEN=1 & LCDSE4.SE32=0: PWM läuft, Displaysegmente sind nicht
> sichtbar
> An den Displaypins liegt keine Rechteckspannung an, der Pin ist die
> ganze Zeit auf low.

Das kann dann aber nicht am Display liegen, denn LCDs werden nicht 
einfach 0-ohmig ;-)

>
> LCDCON.LCDEN=0 & LCDSE4.SE32=1: PWM läuft, 2 Displaysegmente sind
> sichtbar (Pegel ist statisch high)
>
> LCDCON.LCDEN=0 & LCDSE4.SE32=0: PWM läuft, 2 Displaysegmente sind
> sichtbar (Pegel ist statisch high)
>
> Wenn bei LCDCON.LCDEN=0 auch alle LSCDEx=0 sind, gibt es keine
> Änderungen.

Da jetzt die normalen IOs arbeiten, siehst Du da vermutlich die 
statischen Werte der Port Register.
Musst Du mal im Code checken (Du merkst, warum ich den GANZEN Code sehen 
wollte ? ;-)

>
> Ich hoffe, das macht mein Problem etwas klarer ;-)

Also, das Problem ist jetzt glasklar. Fehlt nur noch die Lösung...

Die "üblichen Verdächtigen" hast Du alle geprüft ? Insbesondere, das am 
LCD alles richtig rangeroutet ist ? Konnte ich im Schematic natürlich 
nicht erkennen.
Dazu muss das Pinning vom LCD Datasheet gegen das Schaltplansymbol UND 
gegen den Footprint geprüft werden (bzw. die Kabel überprüft werden).
Auch im Eratasheet sollte man mal wühlen.

Dann sollte man mal die beiden Fälle mit der falschen Signalpriorität 
genauer prüfen. Da liegt vermutlich das Problem.
Anderer Kandidat ist die PWM. Du benutzt nämlich einen EPWM Mode (das 
"C" in CCP2CON=0x3C;) Und der kann bis auf 4 (!) Pins togglen, wenn ich 
das richtig in Erinnerung habe.

> Danke schon mal für deine Mühen.

Welche Mühen ?
Tagsüber waren die 2x 5min eine willkommene Pause. Und jetzt ist das 
Problem ja auch ziemlich spannend (und ausserdem habe ich Rindvieh 
vergessen, ein IC fürs aktuelle WE-Projekt zu zu bestellen. Also habe 
ich heute abend etwas Zeit übrig gehabt)

Grüße
Andreas

P.S: Welches Display ist da eigentlich dran ?
     A.

von Andreas H. (ahz)


Lesenswert?

Andreas H. schrieb:
> Du benutzt nämlich einen EPWM Mode (das
> "C" in CCP2CON=0x3C;) Und der kann bis auf 4 (!) Pins togglen, wenn ich
> das richtig in Erinnerung habe.

Habe nochmal nachgesehen. Es sind max. vier Pins. Die restlichen Drei 
teilen sich ihren Pin mit VLCD1-3. Bei dem Puls/Pausenverhältniss was Du 
eingestellt hattest ($3FF ?), dürfte der Kontrast ziemlich gering sein, 
das Display würde also (fast) nichts mehr anzeigen.

Kannst Du mal nachmessen, ob diese Spannungen in allen von Dir 
beschriebenen Fällen identisch verlaufen ?

Kennst Du übrigens diese Appnote von Mikrochip ?

"AN1354 - Implementing an LCD Using the PIC16F1947 Microcontroller"

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en551178

Grüße
Andreas

von Birgit P. (bpie)


Lesenswert?

Andreas H. schrieb:
>
> Kennst Du übrigens diese Appnote von Mikrochip ?
>
> "AN1354 - Implementing an LCD Using the PIC16F1947 Microcontroller"

>
> Grüße
> Andreas

Hallo.

Die Appnote hat mir geholfen. Ich kenne sie zwar, bin jetzt aber noch 
mal durch gegangen und habe gesehen, dass ich im Vergleich ein Register 
nicht gesetzt habe: das LCDRL.
Ich habe den Wert 0xF0 ersteinmal übernommen und siehe da, es 
funktioniert.

Ich kann das Verhalten zwar noch nicht mit dem Register in Zusammenhang 
bringen, aber Display und PWM lassen sich nun gleichzeigig regeln.


Danke.

von Andreas H. (ahz)


Lesenswert?

Birgit Pie schrieb:
> Ich kann das Verhalten zwar noch nicht mit dem Register in Zusammenhang
> bringen, aber Display und PWM lassen sich nun gleichzeigig regeln.

Also war doch nicht das Display defekt ;-)

Das mit dem Register ist mir auch nicht klar. Wenn es jetzt läuft, dann 
ist das aber auch eher Neugier.

Grüße
Andreas

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.