Forum: Mikrocontroller und Digitale Elektronik 7 Segment Anzeige per Pic Steuern


von John (Gast)


Lesenswert?

Hallo Leute habe da ein kleines Problem ich möchte gerne eine 7 Segment 
anzeige per Pic steuern und mit dem Schalter Hoch oder Runter Schalten 
bloss wenn ich den Schalter betätige habe ich immer so ein Flackern kann 
mir jemand vieleicht sagen wie ich das weg bekomme hier ein kleiner 
Ausschnitt.


Start:movf  Sp1,w
      movwf  PORTB
      movlw  b'11011111'
      movwf  PORTD
      btfss  PORTA,0
      goto  ssh
      goto  Start

;----------------------------------------------------------------------- 
-----
ssh:  call    wait
      incf  einer,w
      movwf  einer
      call  Anzeige
      movwf  Sp1
      goto  Start

von John (Gast)


Lesenswert?

Hier der richtige Ausschnitt



Start:            movf  Sp1,w
      movwf  PORTB
      movlw  b'11011111'
      movwf  PORTD
      call  wait1
      movf  Sp2,w
      movwf  PORTB
      movlw  b'10111111'
      movwf  PORTD
      call  wait1
      movf  Sp3,w
      movwf  PORTB
      movlw  b'01111111'
      movwf  PORTD
      call  wait1
      btfss  PORTA,0
      goto  ssh
      goto  Start

;----------------------------------------------------------------------- 
---
ssh:            call  wait
      incf  einer,w
      movwf  einer
      call  Anzeige
      movwf  Sp1
      goto  Start

von Michel (Gast)


Lesenswert?

Was macht denn die Routine wait1?

von John (Gast)


Lesenswert?

das ist ne zeitschleife

von Wilhelm F. (Gast)


Lesenswert?

Ohne jetzt auf das Programm mal einzugehen:

Zum Test einer Multiplexung reicht natürlich ein Hauptprogramm mit einer 
Warteschleife. Wenn da noch irgend welche Interrupts statt finden, gibt 
es vielleicht ein Flackern oder Jittern.

Die Multiplexumschaltungen müßten korrekterweise in einem Timer-Interupt 
liegen, der eine hohe Priorität hat. Und die Frequenz muß auch so hoch 
gewählt sein, daß das Auge kein Flackern mehr beobachten kann. Minimum 
20ms für den Zeitdurchlauf eines gesamten Displays.

von John (Gast)


Lesenswert?

Das Flackern tritt nur auf wenn ich die Taster betätige sonst ist alles 
gut!

von M. J. (manfred-64)


Lesenswert?

nu mal Tacheles!
Post den gesamten Code oder las es :(

von Peter D. (peda)


Lesenswert?

John schrieb:
> Das Flackern tritt nur auf wenn ich die Taster betätige sonst ist alles
> gut!

Und genau deshalb macht man Multiplexen im Timerinterrupt.
Erst dann ist alles gut.


Peter

von John (Gast)


Lesenswert?

so jetzt hier der code wird aber erstmal eine Taste abgefragt


p=16f887
      #include <P16f887.inc>

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

einer      EQU    20h
zehner     EQU    21h
hunderter  EQU    22h
tausender  EQU    23h
Sp1        EQU    24h
Sp2        EQU    25h
Sp3        EQU   26h
Sp4        EQU    27h



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

      bsf  STATUS,RP0
      bsf  STATUS,RP1
      clrf  ANSELH
      clrf  ANSEL
      bsf  STATUS,RP0
      bcf  STATUS,RP1
      movlw  b'11111111'
      movwf  TRISA
      clrf  TRISB
      clrf  TRISC
      clrf  TRISD
      clrf  TRISE
      bcf  STATUS,RP0

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

      clrf  PORTA
      clrf  PORTB
      clrf  PORTC
      clrf  PORTD
      clrf  PORTE
      clrf  einer
      clrf  zehner
      clrf  hunderter
      clrf  tausender


;----------------------------------------------------------------------- 
------
      clrf  Sp1
Start:
      movf  Sp1,w
      movwf  PORTB
      movlw  b'10011111'
      movwf  PORTD
      call  wait1
      movf  Sp2,w
      movwf  PORTB
      movlw  b'10111111'
      movwf  PORTD
      call  wait1
      movf  Sp3,w
      movwf  PORTB
      movlw  b'01111111'
      movwf  PORTD
      btfss  PORTA,0
      goto  ssh
      goto  Start

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

ssh:            call  wait
      incf  einer,w
      movwf  einer
      call  Anzeige
      movwf  Sp1
      goto  Start


Anzeige:  addwf PCL,f

      retlw b'10111111'  ;Zahl 0
      retlw b'10000110'  ;Zahl 1
      retlw b'11011011'  ;Zahl 2
      retlw b'11001111'  ;Zahl 3
      retlw b'11100110'  ;Zahl 4
      retlw b'11101101'  ;Zahl 5
      retlw b'11111101'  ;Zahl 6
      retlw b'10000111'  ;Zahl 7
      retlw b'11111111'  ;Zahl 8
      retlw b'11101111'  ;Zahl 9

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

wait:     movlw d'175'
      movwf 31h
schl2:     movlw d'175'
      movwf 30h
schl1:     nop
      nop
      nop
      nop
      nop
      nop
      nop
      decfsz 30h,f
      goto schl1
      decfsz 31h,f
      goto schl2
      return




wait1:     movlw d'50'
      movwf 33h
schl3:     movlw d'25'
      movwf 34h
schl4:     nop
      nop
      nop
      nop
      nop
      nop
      nop
      decfsz 34h,f
      goto schl4
      decfsz 33h,f
      goto schl3
      return

      end

von M. J. (manfred-64)


Lesenswert?

so ganz ohne Kommentare macht das keinen Spaß, ich fisle hier nich raus 
was an PortB,C,D.... passieren soll.
Was, wie, wo ???


PS: Freitag Abende alle auf Achse ich zu hause und bereits am ende der 
2. Flasche Wein :P

von M. J. (manfred-64)


Lesenswert?

Peter Dannegger schrieb:
> Und genau deshalb macht man Multiplexen im Timerinterrupt.
> Erst dann ist alles gut.

ist so im allgemeinem dahergelaber Bullshith.
in dieser Aufgabenstellung ist ein Interrupt völlig unnötig und so 
deshalb auch nicht vorhanden.

von ups (Gast)


Lesenswert?

wie hoch ist der Takt in MHz (Quartz), wie sehen deine Fusebit's aus?

ups

von M. J. (manfred-64)


Lesenswert?

@john
Ein Time-Management tut einem multiplexing aber immer gut wenn's nich 
flackern soll!
Ob Interrupt oder nich is Dir überlassen aber es dem Zufall überlassen 
(Taste gedrückt o. nich) is MÜLL.

von Peter D. (peda)


Lesenswert?

Manfred John schrieb:
> Peter Dannegger schrieb:
>> Und genau deshalb macht man Multiplexen im Timerinterrupt.
>> Erst dann ist alles gut.
>
> ist so im allgemeinem dahergelaber Bullshith.

Vielen Dank für Deinen völlig unnützen Beitrag.
Warum willst Du einem Anfänger die einfache und zuverlässige Lösung 
ausreden?
Der kann doch nicht beurteilen, daß Du "Bullshith" redest.

Man kann sich theoretisch damit abquälen, die Mainloop auf gleiche 
Ausführungszeit bei jeder Verzweigung zu trimmen, damit nichts flackert.
Aber einfach und sinnvoll ist das nicht.

Nimmt man den Interrupt fürs Multiplexen, braucht die Mainloop keinerlei 
Rücksicht zu nehmen. Sie schreibt die Darstellungsmuster in den 
Display-RAM, ganz wie sie lustig ist. Und der Timerinterupt gibt ihn 
dann exakt zu gleichen Zeitintervallen aus.

Programmieren wird dadurch einfach und sicher, indem man die einzelnen 
Aufgaben voneinander trennt (Divide et impera).
Spaghetticode ist ja nicht zu Unrecht verpönt.


Peter

von Maik W. (werner01)


Lesenswert?

jo muß Peter Recht geben. min. 1/25s Intervall den Timer einstellen, 
dann siehst Du kein flackern mehr.



werner

von Thorsten S. (Gast)


Lesenswert?

ich verstehe nur bahnhof? welcher Timer?

du fragst die Taste ab aber sperrst sie dann nicht. Der Controller läuft 
für die Zeit des Drückens 1000 Mal da durch, und deswegen "rattert" 
deine Anzeige. Die Taste hängt doch an Port A,0 oder?

Zu Deinem Code gehört auch, wo was angeschlossen ist ....

Willst du denn nur eine 7Seg Anzeige ansteuern oder mehrere? so wie ich 
das sehen hast du zudem deine "sp" register nirgens auf 0 gesetzt, nun 
kann es passieren das er dir ins nirvana möllert wenn dort müll drin 
steht...

T.

von Tobi D. (fanti)


Lesenswert?

Thorsten S. schrieb:
> du fragst die Taste ab aber sperrst sie dann nicht. Der Controller läuft
> für die Zeit des Drückens 1000 Mal da durch, und deswegen "rattert"
> deine Anzeige.

naja, also durch die "wait" schleifen, die 2 mal verschachtelt sind, 
dauert eine mainloop schleife doch lang genug um die taster nicht extra 
sperren zu müssen.

ich würde eher sagen, die wait schleife, die bei "ssh" aufgerufen wird, 
also 175 x 175 takte, führt dazu, dass das multiplexen nicht mehr 
schnell genug funktioniert.
mein tip: mach mal die zeit kürzer oder lösch diese wait-schleife raus, 
wozu hast du sie eingebaut? zum entprellen des tasters?
am besten wäre wohl ein taster-interrupt geeignet.

von M. J. (manfred-64)


Lesenswert?

Peter Dannegger schrieb:
> John schrieb:
>> Das Flackern tritt nur auf wenn ich die Taster betätige sonst ist alles
>> gut!
>
> Und genau deshalb macht man Multiplexen im Timerinterrupt.
> Erst dann ist alles gut.
>
>
> Peter

Ja Du hast völlig recht, Dein Beitrag hilft sicher jedem Neuling.

Peter Dannegger schrieb:
> Man kann sich theoretisch damit abquälen, die Mainloop auf gleiche
> Ausführungszeit bei jeder Verzweigung zu trimmen, damit nichts flackert.
> Aber einfach und sinnvoll ist das nicht.

LOL Du hast wirklich keine Ahnung wie man ein anständiges Timemanagement 
ohne gleich für jeden Zeitintervall einen einengen Interrupt zu 
verballern, macht!

Aber Deine Magischekugel scheint wirklich gut zu funktionieren!
Was Du alles aus zwei Sätzen von mir herauslesen kannst, Hut ab.

Nur Schade das das alles hier John nicht weiter hilft.

von M. J. (manfred-64)


Lesenswert?

@ john:

Das Multiplexen solltest Du wirklich besser über den Timer steuern, ob 
mit oder ohne Interrupt is egal.
Die Tastenabfrage würde ich in ein eigenes Unterprogramm verbannen.
so das auch dies über den Timer geregelt werden kann und keine sinnlose 
zeit in der Warteschleife verheizt wird.

Einfach den Timer auf kleinst benötigten Zeitintervall trimmen.
Durch den Interrupt oder einfaches Pollen des Timer InteruptFlags
ein Unterprogramm aufrufen in dem Du durch eigene Zählvariable(n)
die noch benötigten Zeitintervalle erzeugst. Durch setzen von Flag's 
kannst Du das dann in der Hauptschleife auswerten.

So wird das Ganze auch flexibler für Änderungen u.o. Erweiterungen.

Ach ja nicht vergessen deine Sprung-Variable für die LookUp-Tabelle auf 
Gültigkeit zu prüfen.


mfg

von M. J. (manfred-64)


Lesenswert?

@Peter

Ich möchte mich hiermit ganz ehrlich bei Dir für meine Wortwahl 
"Bullshitt"
entschuldigen. So was ist nicht nötig und war so auch nicht gewollt aber 
manchmal fällt es mir nicht auf wie unfreundlich manche "Kurzfassungen" 
beim lesenden ankommen könnten. Vor allem wenn ich angesoffen bin :/

Also Sorry noch mal's, war nich' so gemeint.


mfg

von M. J. (manfred-64)


Lesenswert?

Manfred John schrieb:
> Einfach den Timer auf kleinst benötigten Zeitintervall trimmen.
> Durch den Interrupt oder einfaches Pollen des Timer InteruptFlags
> ein Unterprogramm aufrufen in dem Du durch eigene Zählvariable(n)
> die noch benötigten Zeitintervalle erzeugst. Durch setzen von Flag's
> kannst Du das dann in der Hauptschleife auswerten.

ubs, missverständlich ausgedrückt

Wenn Interrupt benutzt, natürlich kein weiteres Subprogramm aufrufen. 
Das bisschen Zählen, testen etc. natürlich gleich in der 
Interruptroutine erledigen.

von John (Gast)


Lesenswert?

Danke für eure Antworten wie schon hier mal gesagt ich bin ein neuling 
in PicProgrammierung und kenne mich mit dem Interrupt noch nicht aus.
Gibt es vieleicht eine Seite im Internet oder ein Buch wo das Gut 
erklärt wird?

von Tobi D. (fanti)


Lesenswert?

ich bin ja immernoch der meinung, dass man es auch ohne interrupt machen 
kann. klar wäre es eleganter aber für den zweck als einsteiger klappt es 
mit sicherheit auch so, wenn man etwas auf die timings achtet.

schau mal bei sprut vorbei, da gibts interessantes zu vielen themen:
http://www.sprut.de/electronic/pic/int/int.htm

von Der 7-Segmentige (Gast)


Lesenswert?

wie immer bei PIC Assembler: www.sprut.de

von M. J. (manfred-64)


Lesenswert?

Hier was auf deutsch und Billig :)
http://www.buecherbillig.de/grosse-picmikro-handbuch-p-40350.html

in Verbindung mit Sprut's Seite, sollte das für den Hobby Bereich erst 
mal reichen.

von John (Gast)


Lesenswert?

Kann mir vieleicht jemand erklären wie das mit dem Timer-Interupt 
funktioniert und auf was ich dabei achten soll oder vieleicht sogar ein 
kleines beispiel?

von Lehrmann M. (ubimbo)


Lesenswert?

John schrieb:
> Kann mir vieleicht jemand erklären wie das mit dem Timer-Interupt
> funktioniert und auf was ich dabei achten soll oder vieleicht sogar ein
> kleines beispiel?

Das findest du doch alles bei Sprut.de
Ein bisschen bemühen musst du dich schon selbst auch - und verstehen 
kann das jeder - wirklich jeder !

von Peter D. (peda)


Lesenswert?

Lehrmann Michael schrieb:
> Das findest du doch alles bei Sprut.de

Z.B.:
http://www.sprut.de/electronic/pic/programm/led.htm


Allerdings ist da noch ein Schönheitsfehler.
Kein Mensch kann Ziffern alle 250Hz ablesen. Daher ist es unnötig, im 
Interrupt immer wieder neu die Ziffern in 7-Segment-Kode umzuwandeln.
Diese Umwandlung sollte man daher besser ins Main verschieben.
Dann erfolgt die Umwandlung immer nur dann, wenn wirklich ein neuer 
Zählwert vorliegt.
Man gewinnt dadurch also CPU-Leistung, die man vielleicht an andere 
Stelle gebrauchen kann. Bzw. man kann die gleiche Anwendung mit 
langsameren Takt betreiben (Strom sparen).


Peter

von Juppi J. (juppiii)


Lesenswert?

Hallo
Fang gleich mit INT an, dann wird es später leichter ,mit Pic oder AVR

von John (Gast)


Lesenswert?

Also nochmal eine Frage zu der Steuerung ich brauche oder am besten 
währe ein Timer interrupt und die Tasten frage ich dann immer ab wenn 
der Timer abgelaufen ist oder brauche ich noch einen interrupt bei den 
Tastern????

von M. J. (manfred-64)


Lesenswert?

Hi,

hab heute keinen Kopf für Große Erklärungen :/

Hier ein Timer-Interrupt-Routine von mir, is zwar keine 7Segmentdingens
aber alles drin was Du brauchst. Ich frage einen Port ab (auf 
Flankenänderung deswegen etwas aufwendiger als ne einfache 
Tastenabfrage)
und eien 1 Sekundentakt. Inkl. dem drum herum was ein Pic16Fxxx für die 
Interrupt Abwicklung braucht.
Ich hoffe es hilft Dir weiter

mfg
1
;==============================================================================
2
; INTERRUPT SERVICE ROUTINE
3
;==============================================================================
4
5
ISR       ORG     0x0004            ; interrupt vector location
6
;         Context saving for ISR
7
          MOVWF   W_TEMP            ; save off current W register contents
8
          MOVF    STATUS,W          ; move status register into W register
9
          MOVWF   STATUS_TEMP       ; save off contents of STATUS register
10
          MOVF    PCLATH,W          ; move pclath register into W register
11
          MOVWF   PCLATH_TEMP       ; save off contents of PCLATH register
12
; USER INTERRUPT SERVICE ROUTINE GOES HERE
13
14
;------------------------------------------------------------------------------
15
; Sekunden Takt / DCF77 Timer
16
;------------------------------------------------------------------------------
17
Sekunde  BCF    INTCON,T0IF    ; auf ruf alle 1/125 Sec.
18
    bcf    Sec_Flag
19
    btfsc  DCF_Port
20
    goto  DCFPortHI
21
    goto  DCFPortLO
22
DCFPortHI          
23
    btfsc  DCF_Port_Flag  
24
    goto  DCFPortEND    ; DCF_PORT war Hi
25
    bsf    DCF_Rise_Flag  ; DCF_PORT ist Hi geworden DCFBit auswerten
26
    bsf    DCF_Port_Flag  
27
    goto  DCFPortEND
28
DCFPortLO
29
    btfss  DCF_Port_Flag
30
    goto  DCFPortEND    ; DCF_PORT war bereits Lo
31
    bsf    DCF_Sink_Flag  ; DCF_PORT ist Lo geworden
32
    bcf    DCF_Port_Flag
33
DCFPortEND
34
    incf  DCF_Timer     ; Sec_Tackt erzeugen
35
    DECFSZ  Clock125
36
    goto  INT_END
37
    MOVLW  D'125'  
38
    MOVWF   Clock125
39
    bsf    Sec_Flag    
40
  
41
;         Restore context before returning from interrupt
42
INT_END
43
          MOVF    PCLATH_TEMP,W     ; retrieve copy of PCLATH register
44
          MOVWF   PCLATH            ; restore pre-isr PCLATH register contents
45
          MOVF    STATUS_TEMP,W     ; retrieve copy of STATUS register
46
          MOVWF   STATUS            ; restore pre-isr STATUS register contents
47
          SWAPF   W_TEMP,F
48
          SWAPF   W_TEMP,W          ; restore pre-isr W register contents
49
          RETFIE                    ; return from interrupt
50
;==============================================================================

von John (Gast)


Lesenswert?

Also kein Interrupt bei den Tastern nur der Timerinterrupt?
Tschuldigung muss fragen das der Schaltplan und Layout fertig ist und 
die eingänge der Taster sich auf PORTA befinden wo kein interrupt 
möglich ist.

von Pascal K. (zerb)


Lesenswert?

Dann benutz einfach den Timer0 an RA4.
Falls du doch mit einer ISR arbeiten möchtest kannst du das Layout der 
Platine nicht einfach abändern ? Sprich: Leiterbahnen aufkratzen und 
Fädeldraht verwenden ?

Gruß

von M. J. (manfred-64)


Lesenswert?

John schrieb:
> Also kein Interrupt bei den Tastern nur der Timerinterrupt?
> Tschuldigung muss fragen das der Schaltplan und Layout fertig ist und
> die eingänge der Taster sich auf PORTA befinden wo kein interrupt
> möglich ist

Jo, Du kannst natürlich den Taster abfragen wann und wo Du willst :)
Sollte ja nicht auf die µSec genau wichtig sein wann der Schalter 
gedrückt wurde.
in meinem Beispiel ist das hauptsächlich mit im Interrupt weil das ganze 
eigentlich eine Zeitmessung ist.

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.