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
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
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.
Das Flackern tritt nur auf wenn ich die Taster betätige sonst ist alles gut!
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
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
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
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.
wie hoch ist der Takt in MHz (Quartz), wie sehen deine Fusebit's aus? ups
@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.
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
jo muß Peter Recht geben. min. 1/25s Intervall den Timer einstellen, dann siehst Du kein flackern mehr. werner
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.
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.
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.
@ 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
@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
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.
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?
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
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.
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?
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 !
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
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????
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 | ;============================================================================== |
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.
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ß
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.