Archiv verlassen und diese Seite im Standarddesign anzeigen : Wo ist der Fehler in der Software
the_Ghost666
29.08.2004, 10:28
moin,
ich hoffe mir kann jemand helfen.
bin ein neueinsteiger was die microcontroller angeht und hab nun vor gehabt eine zeitschaltuhr zu bauen, um meinen platinenbelichter zu steuern.
ich hab die tutorials usw bei sprut.de durchgearbeitet und mich nun daran gesetzt. aber es will und will nicht funktionieren und ich hab auch sonst niemanden der mir sagen könnte, wo der fehler ist.
deswegen hoffe ich jemand findet hier zeit einmal über den quellcode zu gucken.
Was passieren soll: eine 4stellige sieben segment anzeige zeigt die zeit an, die vorher über 2 taster eingestellt wurde. wenn man die starttaste drückt, läuft die uhr rückwärts und schaltet dabei ein relais (momentan nur eine led zu testzwecken) bis sie auf null steht.
problem: es passiert nichts. alles bleibt dunkel
wo isn dein Code ????????
(hier sind keine Hellseher)
Gerhard
the_Ghost666
29.08.2004, 11:00
der liegt als asm datei im anhang, kann sein, dass du den nicht sehen oder runterladen kannst. ich poste den mal so rein
list p=16F876A
; Durch 4 Tasten lässt sich der Countdown einstellen, starten und der controller reseten.
; die zeit wird auf einer 4stelligen sieben segment anzeige angezeigt und runtergezählt.
; in der zeit von Start bis 0 wird ein relais eingeschaltet.
;
;************************************************* *************
;* Anzeige : MM:SS
;* Pinbelegung
;* ----------------------------------
;* PORTA: 0 Ziffer1 -----------------------------------------+
;* 1 Ziffer2 -----------------------------+ I
;* 2 Ziffer3 -----------------+ I I
;* 3 Ziffer4 -----+ I I I
;* 4 Eingang I I I I
;* PORTB: 0 Segment B AAAAA AAAAA AAAAA AAAAA
;* 1 Segment F F B F B F B F B
;* 2 Segment A F B F B F B F B
;* 3 Segment G GGGGG GGGGG GGGGG GGGGG
;* 4 Segment H E C E C E C E C
;* 5 Segment C E C E C E C E C
;* 6 Segment E DDDDD HH DDDDD HH DDDDD HH DDDDD HH
;* 7 Segment D
;*
;
; RC0 = Taster (Minuten)
; RC1 = Taster (Sekunden)
; RC2 = Taster (Start)
; RC3 = Ausgang für das Relais
include "P16F876A.inc"
__CONFIG _WDT_OFF & _XT_OSC & _PWRTE_ON
ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES
;Variablen und Konstanten werden vereinbart.
W_TEMP equ 0x20 ;rettung beim interrupt
STATUS_TEMP equ 0x21 ;rettung beim interrupt
PCLATH_TEMP equ 0x22 ;rettung beim interrupt
MinZehner equ 0x23
MinEiner equ 0x24
SekZehner equ 0x25
SekEiner equ 0x26
Digit equ 0x27 ;bei welcher ziffer sind wir?
help equ 0x28
Startsignal equ 0x29 ;steht hier eine 1, ist das das startsignal
Timer equ 0x30 ;zählt bis 50 um den takt von 50hz auf 1hz zu verringern
#define MinTaste PORTC, 0
#define SekTaste PORTC, 1
#define StartTaste PORTC, 2
#define Relais PORTC, 3
org 0x00 ;Startadresse nach Reset ist 0 hier startet der PIC
goto main ;Sprung zum Hauptprogramm
org 0x04 ;Interruptvector ist 0x04,
intvec
bcf INTCON, GIE ;interrupts nicht erlaubt
movwf W_TEMP ;w, status und pclath retten.
swapf STATUS,W
clrf STATUS
movwf STATUS_TEMP
movfw PCLATH
movwf PCLATH_TEMP
movlw D'131'
movwf TMR0
int_service
bcf TRISA,0 ;Schaltet Ziffer1 aus
bcf TRISA,1 ;Schaltet Ziffer2 aus
bcf TRISA,2 ;Schaltet Ziffer3 aus
bcf TRISA,3 ;Schaltat Ziffer4 aus
decf Digit,f
bz int_0
movfw Digit
movwf help
decf help,f
bz int_1
decf help,f
bz int_2
decf help,f
bz int_3
goto int_4
int_0
movlw D'5'
movwf Digit
btfss Startsignal, 0
goto int_end
bsf Relais
decf Timer,f ;ist es der 50ste durchgang diese sekunde?
btfss STATUS,Z
goto int_end
movlw D'50' ;dann füll Timer wieder auf 50 auf
movwf Timer
decf SekEiner,f ;reduziere SekEiner um eine Sekunde
movlw D'255' ;überprüfe ob die zelle unter null springt
subwf SekEiner,w
bnz int_end ;wenn nicht, dann gehts normal weiter
movlw D'9' ;wenn doch, schreib 9 in die SekEiner
movwf SekEiner
decf SekZehner,f ;und verringer Sekzehner
movlw D'255' ;es wird geprüft ob 255 in SekZehner steht
subwf SekZehner,w
bnz int_end ;wenn SekZehner nicht 255, gehts weiter, sonst
movlw D'5' ;wird SekZehner auf 5 gesetzt
movwf SekZehner
decf MinEiner,f ;und MinEiner um 1 reduziert
movlw D'255' ;es wird geprüft ob 255 in MinEiner steht
subwf MinEiner,w
bnz int_end ;wenn nicht geht es weiter, sonst
movlw D'9' ;wird MinEiner auf 9 gesetzt
movwf MinEiner
decf MinZehner,f ;und MinZehner um einen gesengt
goto int_end ;weiter gehts
int_1
movfw SekEiner
call Segmente
movwf PORTB
bsf PORTA, 0
goto int_end
int_2
movfw SekZehner
call Segmente
movwf PORTB
bsf PORTA, 1
goto int_end
int_3
movfw MinEiner
call Segmente
movwf PORTB
bsf PORTA, 2
goto int_end
int_4
movfw MinZehner
call Segmente
movwf PORTB
bsf PORTA,3
goto int_end
; 7-Segment-Tabelle
Segmente
addwf PCL, f
retlw B'00011000' ; 0
retlw B'11011110' ; 1
retlw B'00110010' ; 2
retlw B'01010010' ; 3
retlw B'11010100' ; 4
retlw B'01010001' ; 5
retlw B'00010001' ; 6
retlw B'11011010' ; 7
retlw B'00010000' ; 8
retlw B'01010000' ; 9
int_end
movfw SekEiner ;hier wird überprüft, ob der Zählerstand auf null ist.
iorwf SekZehner, 0
iorwf MinEiner, 0
iorwf MinZehner, 0
btfss STATUS,Z ; wenn ja, dann
goto int_end
bcf Relais ;wird das relais abgeschaltet
bcf Startsignal, 0 ;und das Startsignal gelöscht
movfw PCLATH_TEMP
movwf PCLATH
swapf STATUS_TEMP,W
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
bcf INTCON,T0IF
bsf INTCON, GIE
retfie
;hier muß die Interruptbehandlungsroutine stehen,
;falls Interrupts genutzt werden sollen
;die Grundeinstellungen werden vorgenommen
main
bsf STATUS, RP0
movlw B'110'
movwf ADCON1 ;PortA von Analog auf digital
clrf TRISA ;PortA ist Ausgang
clrf TRISB ;PortB ist Ausgang
movlw B'11110111' ;RC3 ist Ausgang, rest Eingang
movwf TRISC
movlw B'10010100' ;Timer0 bekommt den Vorteiler 32
movwf OPTION_REG
bcf STATUS, RP0
movlw D'131'
movwf TMR0
bsf INTCON, T0IE
bsf INTCON, GIE
; Zeit 0 einstellen
clrf SekEiner
clrf SekZehner
clrf MinEiner
clrf MinZehner
movlw 5
movwf Digit ; Ziffernzähler einstellen
movlw 50
movwf Timer
Einstellen
btfss MinTaste ;Minutentaste gedrückt?
call MinPlus ;dann geh nach MinPlus
btfss SekTaste ;Sekundentaste gedrückt?
call SekPlus ;dann geh nach Sekplus
btfss StartTaste ;StartTaste gedrückt?
call Start ;dann geh nach Start
goto Einstellen ;nichts gedrückt? dann frag nochmal ab.
SekPlus
incf SekEiner,f ;erhöhe SekEiner
movlw D'10' ;Subtrahiere 10 von SekEiner
subwf SekEiner, 0
bz SekEinerVoll ;wenn also SekEiner =10 geh nach SekEinerVoll
return
SekEinerVoll
clrf SekEiner ;setze SekEiner auf 0
incf SekZehner,f ;erhöhe SekZehner
movlw D'6' ;subtrahiere 6 von SekZehner
subwf SekZehner, 0
bz SekMinVerschieben ;wenn SekZehner = 6 geh nach SekMinVerschieben
return
SekMinVerschieben
clrf SekZehner ;setze SekZehner auf 0
incf MinEiner,f ;erhöhe MinEiner um 1
return
MinPlus
incf MinEiner,f ;erhöhe MinEiner
movlw D'10' ;subtrahiere 10 von MinEiner
subwf MinEiner, 0
bz MinEinerVoll ;wenn MinEiner = 10 geh nach MinEinerVoll
return
MinEinerVoll
clrf MinEiner ;setze MinEiner auf 0
incf MinZehner,f ;erhöhe MinZehner um 1
return
Start
bsf Startsignal, 0
return
end ;das Ende des Programms
als schaltplan hab ich mir den hier genommen
http://www.thelastinstance.de/elek/files/p01_schaltplan.gif
ist eigentlich abgeguckt, aber ich will das als lernhilfe benutzen , deswegen schnapp ich mir nicht einfach nen avr und den bei den entwicklern geposteten code
Hallo
sorry, ich hätte mich einloggen sollen...
Also, der Code, das sind schon ein paar Zeilen....
Hast Du den Code schon in der Simulation laufen lassen ?
Wenn ja, und er funktioniert da, liegts oft an der hardware:
1.Test: läuft der Oszillator ?
2.Test: wenn's nicht tut, einen Toggleausgang bauen, den man mit nem Oszi überprüfen kann.
Irgendwie schaff ich es nicht Deinen Schaltplan anzuschauen. Da sind nur wagrechte Striche aber keine senkrechten. Les was von nem AVR.
Und was ist da für ein Quarz oder Oszillator dran ?
Gerhard
the_Ghost666
29.08.2004, 11:35
ich weiß dass mplab einen simulator hat, aber nicht wirklich was ich damit machen soll
es ist ein 4mhz keramikresonator, jaja, fehlertoleranz und so, aber die uhr muss erstmal laufen, nicht genau gehen
schau mal wegen dem schaltplan hier.
das ist die seite , von der ich die idee hab
http://www.thelastinstance.de/elek/project01.phtml
Hallo
ich meine nicht die Fehlertoleranz, ich meine, ob der Oszillator überhaupt arbeitet. Nach meiner Erfahrung ist das - zumindest bei meinen Schaltungen - der häufigste Fehler. Hast Du ein Oszi, mit Du überprüfen kannst, ob der Oszillator schwingt ? An den Schlüssen des resonators, am PIC muß irgend eine Schwingung mit den 4 MHz sichtbar sein. Wenn es nur ne Gleichspannung ist, schwingt er nicht, tut der PIC dann auch nix.
Den Simulator kannst Du in MPLAB unter Debugger - Select Tool - MPLAB SIM auswählen. Dann Compilieren und dann kann das Programm durchgesteppt werden. Mit View - Watch kann ein Watch-Fenster geöffnet werden, mit dem register und Variable während des durchsteppens des Programms beobachtet werden kann. ich simuliere meine Programme immer erst mal auf diese Weise um zumindest die wichtigsten Fehelr zu finden.
Gerhard
the_Ghost666
29.08.2004, 12:13
ne, mit nem oszilloskop kann ich nicht dienen, aber ich werd mal n idiotensicheren code schreiben, um zu testen, ob der pic und die anzeige werkelt
mh wenn ich den simulator anwerfe dann geht er auch immer schön seine schritte, aber springt nicht in dei interruptroutine, dummerweise ist die aber das kernstück der software
Hallo
wenn im Simulator der Interrupt nicht ausgelöst wird, dann ist im Code ein Fehler. Denn eine ISR kann im Simulator ebenfalls angesprungen und durchgesteppt werden.
Gerhard
the_Ghost666
29.08.2004, 12:41
halt, er springt doch in die interrupt routine, dauert aber bloß
Prima
dann gilts noch festzustellen, ob der Oszillator schwingt. Ist ohne Oszi nicht einfach, zumal man die Anschlüsse des Oszilators nicht stark belasten kann. evtl funktionierts aber auch mit nem Digitalmultimeter in AC-Einstellung
Gerhard
the_Ghost666
29.08.2004, 13:24
bei 4mhz???
ich glaub kaum, dass mein multimeter mehr als 100hz schafft
Ich kanns nicht ausprobieren. Ich hab grad keine Schaltung mot nem PIC parat. Aber dann wirds aufwendig: OP oder Modfet als eingang, Schmitt-Trigger, Frequenzteiler, Led.
Wie groß sind die Kapazitäten am Resonator ? Im datenblatt steht was von 15..68pf für 4 MHz ?
Gerhard
the_Ghost666
29.08.2004, 15:02
keramikresonatoren haben 2 interne kondensatoren und 3 beinchen, beim mittleren liegt die masse für die kondensatoren, dh ich hab keine ahnung, aber ist auch unnötig, weils klappen sollte
the_Ghost666
29.08.2004, 20:53
sehrsehr seltsam
drücke ich die starttaste leuchtet kurz eine 0 und die relais-led auf. aber nur solange ich drücke.
bei der minutentaste passiert garnichts und bei der sekundentaste leuchtet die 0 und eine verkrüppelte 2 auf solange ich drücke, aber ziffer 1 und 2, also ganz rechts, bleibt dunkel
da fehlen ja die Kondensatoren 22p sollten reichen
******
GND <----||-----*4MHz*----||-----> GND
******
the_Ghost666
29.08.2004, 22:03
nein, fehlen nicht, die sind in den keramikresonatoren mit 3 beinen bereits eingegossen. nud nen takt bekomm ich auch
Ein Problem könnte sein, daß, wenn eine Taste gedrückt wird, der PIC da öfter durch die Routine läuft, als 1 mal. Du solltest villeicht die Routinen abändern, daß der OIC diese erts verläßt, wenn Du die Taste losgelassen hast.
Gerhard
the_Ghost666
30.08.2004, 13:47
bei tasten fällt mir immer der begriff "entprellen" ein.
was ist damit gemeint und wie bewerkstelligt man es. ich weiß dass es software und hardwarelösungen gibt, aber das wars auch
Beim Entprellen ist gemeint, daß wenn Du die taste drückst, daß dann ein mechanisches Schwingen einsetzt, also Kontakt zu, auf, zu, auf, zu. das ist aber nicht bei allen Tastern gleich. Die kleinen Digi-taster sind besser - sollten eigentlich gar nicht prellen. Je größer die taster-massen, desto länger prellen sie. hardwer-mäßig gibts da ein IC von MAXIM glaub ich, und eins von Motorola (MC14495). Letzteres ist für 6 oder 7 Tasten. Hab ich schon öfter verwendet, ist ok. Softwaremäßig entprellen heißt, daß Du schaust ob Taste gedrückt, dann wartest Du so 20ms, dann schaust Du ob immer noch gedrückt also zb: es sei Taste gedrückt = 0
btfss t1
call taste
..
..
taste:
call delay
btfss t1
goto taste
call delay
btfss t1
goto taste
...
...
return
evtl noch ne Stufe anhängen wenns nicht reicht. Dabei springt er solange auf taste, solange die taste gedrückt ist, dann wird die Aktion ausgeführt, die dafür angedacht ist. (Kann man auch vorziehen) Im Wesentlichen geht es darum, daß die Aktion pro Tastendruck nur 1* ausgeführt wird.
Gerhard
the_Ghost666
30.08.2004, 15:08
achso, ich dachte immer, dass es was mit zu lange drücken zu tun hat.
hab mir nochmal meinen code angesehen.
die sieben segment anzeigen sind ja so geschaltet, dass die anoden durch die Pins am PortA mit saft versorgt werden.
da, wo es leuchten soll, lege ich die passende kathode auf masse. wie mach ich das denn? muss ich den passenden gegenpin als ausgang konfigurieren und auf low stellen? und auf high sollte er dann nicht leuchten, oder? aber gibts dann nicht nen kurzen, weil die beiden auf high liegen?
also die frage ist, wenn ein output auf low liegt, ist er mit masse intern verbunden?
ne ne das passt schon. Der Port A ist Ausgang und da wo du die Kathode schaltest, ist auch Ausgang. Das gibt kein Kurzschluß. Kurzschluß wäre, wenn Du direkt + mit - verbindest. So wie das im Schaltbild dargestellt ist, müßte das schon gehen. Also wenn ich mich auf das Schaltbild beziehe dann schaltest Du rechts die Anoden. Da mußt Du Du ein high ausgeben zum Einschalten. Damit Du dazu eine Kathode schaltest, mußt Du links den Ausgang auf low legen.
Gerhard
the_Ghost666
30.08.2004, 15:56
jetz kapier ich garnichts, ich hab das programm vereinfacht um die schaltung zu testen, an stelle 4 soll alles angeschaltet werden, die tasten sind programmiert.
aber es passiert garnichts wenn ich den strom anschliesse, und wenn ich eine der 3 einstelltasten zu einem bestimmten zeitpunkt drücke und halte, geht die anzeige auf 0..... aber nur solange ich drücke. ich hab den pic vor dem beschreiben gelöscht
org 0x00 ;Startadresse nach Reset ist 0 hier startet der PIC
main
bsf STATUS, RP0
bcf ADCON1, 3
bsf ADCON1, 2
bsf ADCON1, 1 ;PortA von Analog auf digital
movlw B'11110000'
movwf TRISA ;PortA ist Ausgang
movlw B'00000000'
movwf TRISB ;PortB ist Ausgang
bcf STATUS, RP0
clrf PORTA
clrf PORTB
loop
movlw B'00000000'
movwf PORTB
bsf PORTA,3
goto loop
end
the_Ghost666
30.08.2004, 16:38
wenn ich einen pic lösche, was macht der brenner dann?
der setzt da überall nop befehle hin und wenn ich dann den gelöschten pic auslese , nochmal lösche und das ausgelesene mit dem was aufdem pic ist vergleiche, zeigt mir spruts brennprogramm 1024 fehler an
Der Code oben interessiert sich gar nicht für eine taste. Aber miß doch mal Deine Ausgangssignale an PortA und PORTB
Gerhard
the_Ghost666
30.08.2004, 17:31
ja das ist es ja, er interessiert sich nicht für eine taste, aber trotzden hat die taste einfluss auf die reaktion
jetzt sind wir wohl so weit, daß Du mal deinen Schaltplan hier reinstellst. Vielleicht hilft das weiter
Gerhard
the_Ghost666
30.08.2004, 17:57
hab ihn schon ganz oben als link gepostet. das ding ist auf lochraster zwecks erprobung aufgebaut, die transistoren sind bc338-25, die widerstände haben die gleichen werte wie da, taktquelle ist ein 4mhz keramikresonator, prozessor ein pic 16F876a, das relais an RC3 ist eine LED.
anschluss der tasten ist eben Masse-Taster-pin-10k R-5V
die segmente sind alle zusammengeschaltet, also 4xpin1, 4xpin2 und dann an nen 220ohm widerstand und an den µCpin, die anoden sind an nem transistor mit 5V verbunden, 1k R an der Basis und ran an den µC
der einzige unterschied zum schaltplan ist, dass ich den dezimalpunkt mit an den portb gehangen hab und den 47p kondensator parallel zum resetbutton weggelassen hab
is wirklich spassig. Funktioniert der Programmer ? bzw funktioniert das Löschen des PIC ?
Gerhard
the_Ghost666
30.08.2004, 18:15
der programmer hat eigentlich funktioniert, und er löscht eigentlich wie normal... ich werd mal noch ne lochrasterplatine auftreiben und ne einfache blinkerschaltung zum test aufbauen
the_Ghost666
07.09.2004, 16:33
moin, war leider kurzfristig auf urlaub, hab aber nun mal die schaltung neu erstellt und was seltsames bemerkt, ich dachte erst, es sei ein wackelkontakt, die schaltung funktionierte, dann kam ich an den controller und die anzeige flackerte, dann war nichts mehr los, auch ein reset oder strom ausstöpseln brachte nichts. was noch auffiel war, dass der controller für ein kurzes stück code (1 pin von portA auf ausgang (high) schalten und portb komplett ausgang low) mehrere sekunden brauchte, bis er die anzeigen zum leuchten brachte
the_Ghost666
07.09.2004, 16:42
strom war de ganze zeit vorhanden, auch direkt am controller, die ausgänge blieben auf 0,08V und sind nicht high gegangen.
momentan sieht der aufbau so aus, dass ich für die taster 10kohm pullups nutze, eine sieben segment anzeige dran habe, den port b über 220ohm widerstände auf die kathoden der anzeige gelegt habe und einen transistortreiber mit 1kohm an basis an port a gelegt habe, um dort die anode anzuschließen.
achja, ausserdem zeigt er den mittleren strich, also element G nicht an. die anzeige ist ok. das ist der pin24, RB3 am PIC16F876a
BlackBox
07.09.2004, 22:38
Ohne mir jetzt alles durchgesehen zu haben, denke ich mal Du hast ein Problem mit dem Oszilator oder mit der Betriebsspannung.
Wie ist der PIC genau konfiguriert?
Low-Voltage Programming aktiv (wenn ja, dann geht rb.3 nicht)?
Brouw-Out Reset aktiv(wenn ja, dann Reset wenn Spannung zu niedrig)?
Was für ein Oszilatortyp ist eingestellt?
BlackBox
[Edit]
Liegt Reset ordentlich (über Pullup auf) +5V?
the_Ghost666
07.09.2004, 22:54
osc ist n hs oder xt, sollte bei 4mhz ja beides gehen, ich meine es ist momentan hs
die spannungsquelle ist n pcnetzteil(mein rechner hat grad kein os, deswegen nehm ich einfach ein verlängerungskabel und die 5V leitung, mein multi sagt mir 4,98-4,99V) brown out ist an,
.......
moment, ich renn eben raus und schrei etwas
brb ](*,)
the_Ghost666
07.09.2004, 22:57
also, bin wieder da..
dankdankedanke.
ich hab den nochmal ausprobiert. schinbar lag es am lvprogramming und dem brown out. jetzt läuft er wie er soll als hs osc. werd noch etwas rumprobieren, aber der fehler sollte behoben sein, er startet auch nach nem reset sofort wieder.
zum brown out. eigentlich greift das doch, wenn die spannung unter 3V oder so fällt, mein multi zeigt aber die ganze zeit 4,99V an, und n pc netzteil müsste ja acuh ganz schön stabil sein.
the_Ghost666
07.09.2004, 23:17
mh gibts irgendwo ne liste wo steht, was standartmäßig aktiviert ist? brown out und lv programming sind scheinbar standartmäßig aktiviert wenn ich nur _wdt_off _hs_osc und pwrte_on einstelle, dh ich muss meinem programmer sagen, dass er nicht die werte aus dem asm file nehmn soll, sondern ich muss sie manuell einstellen
ich benutze den brenner 5 und spruts pbrenner 3.2
BlackBox
08.09.2004, 07:30
LVP ist als Standart eingestellt.
Mit
.
#include p16f877a.inc ;include file with config bit definitions
__config _HS_OSC & _WDT_OFF & _LVP_OFF ;Set oscillator to HS,
;watchdog time off,
;low-voltage prog. off
kannst Du die Voreinstellungen ändern. Die werden dann ins .hex-File übernommen und sollten vom Brenner verwendet werden.
Wenn der Rechner an ist, sollte die Mindestlast ausreichen oder hast Du alles andere abgeklemmt? Das könnte die Einbrüche erklären. Eine Festplatte kann ruhig dran sein.
Was das Multimeter sagt, heißt nichts weiter, als dass im Mittel 4,99V anliegen. kurze Einbrüche kann das Multimeter nicht feststellen.
Die Brouwn-Out voltage liegt übrigens typ. bei 4V.
BlackBox
the_Ghost666
08.09.2004, 10:45
stimmt, das mit dem brownout hab ich nochmal nachgelesen, naja mainboard 1 platte und 2 laufwerke +lüfter hängen noch dran am rechner
mh wenn ich nen 7805 als energieversorgung benutze um 8VAC über gleichrichter und 2200µF zu stabilisiern sollte das doch reichen, um brown out angeschaltet zu lassen oder? das ding soll dann per steckdose betrieben werden.
achja, die anzeige zeigt die geplanten nullen an, aber da stimmt noch so einiges nicht im code, ich geh erstmal da dran
BlackBox
08.09.2004, 10:49
mh wenn ich nen 7805 als energieversorgung benutze um 8VAC über gleichrichter und 2200µF zu stabilisiern sollte das doch reichen, um brown out angeschaltet zu lassen oder? das ding soll dann per steckdose betrieben werden.
Ja, dass sollte problemlos funktionieren.
BlackBox
Hier gibt es evtl. noch ein paar Anregungen zum Thema:
http://www.mikrocontroller.net/forum/read-4-29195.html
the_Ghost666
08.09.2004, 23:45
TATA!!!
alle probleme beseitigt , der timer läuft wie er soll, ein großes dankeschön an meine helfer hier, besonders an gunzelg ud blackbox
ich werde morgen noch den code kommentieren und dann hier reinstellen, als krönender abschluss
the_Ghost666
09.09.2004, 09:59
ok, hier ist der quellcode meiner finalversion. sollte klappen. die zeit ist gringfügig ungenau, mal sehen obs mit nem oscillator oder quarz besser geht, aber der fehler ist erstmal erträglich
list p=16f876a
;************************************************* *************
;*
;* Pinbelegung
;* ----------------------------------
;* PORTA: 0 Ziffer -----------------------------------------+
;* 1 Ziffer -----------------------------+ I
;* 2 Ziffer -----------------+ I I
;* 3 Ziffer -----+ I I I
;* 4 Eingang I I I I
;* PORTB: 0 Segment B AAAAA AAAAA AAAAA AAAAA
;* 1 Segment F F B F B F B F B
;* 2 Segment A F B F B F B F B
;* 3 Segment G GGGGG GGGGG GGGGG GGGGG
;* 4 Segment H E C E C E C E C
;* 5 Segment C E C E C E C E C
;* 6 Segment E DDDDD HH DDDDD HH DDDDD HH DDDDD HH
;* 7 Segment D
;* PORTC: 0 MinutenTaster
;* 1 SekundenTaster
;* 2 StartTaster
;* 3 Relais
;************************************************* *************
;
; Timer mit Schaltausgang, der aktiviert ist, solange gezählt wird
; Tasten für Minuteneinstellung, Sekundeneinstellung, Start und Reset.
; Timer läuft die eingestellte Zeit von max 99min.59sek rückwärts runter.
; 4Mhz Taktquelle
;
; basierend auf sprut's stoppuhr
;
;
;
;************************************************* *************
; Includedatei für den 16F84 einbinden
#include <P16f876a.INC>
; Konstanten
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC & _BODEN_OFF & _LVP_OFF
DP Equ 4 ; Position des Dezimalpunkts in PORTB
; Variablennamen vergeben
w_copy Equ 0x20 ; Backup für Akkuregister
s_copy Equ 0x21 ; Backup für Statusregister
Ziffer1 Equ 0x22 ; Wert des LSD
Ziffer2 Equ 0x23 ; Wert der zweitkleinsten Stelle
Ziffer3 Equ 0x24 ; Wert der zweitgrößten Stelle
Ziffer4 Equ 0x25 ; Wert des MSD
Digit Equ 0x26 ; Ziffernzähler
ar Equ 0x27
Timer2 Equ 0x28 ; Vorteiler von 50 Hz auf 10 Hz
StartSignal Equ 0x29
Wait1 equ 0x30
Wait2 equ 0x31
Zehntel equ 0x32 ;zehntelsekunden, die nicht angezeigt werden
;************************************************* *************
; los gehts mit dem Programm
org 0
goto Init
;************************************************* *************
; die Interuptserviceroutine
org 4
intvec
bcf INTCON, GIE ; disable Interupt
movwf w_copy ; w retten
swapf STATUS, w ; STATUS retten
movwf s_copy ;
movlw D'131' ; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz)
movwf TMR0
; Intrupt servic routine
Int_serv
bcf PORTA, 0 ; Ziffer1 aus
bcf PORTA, 1 ; Ziffer2 aus
bcf PORTA, 2 ; Ziffer3 aus
bcf PORTA, 3 ; Ziffer4 aus
decf Digit,f ; Ziffernzähler verringern
;Digit=4: anzeigen Ziffer 4
;Digit=3: anzeigen Ziffer 3
;Digit=2: anzeigen Ziffer 2
;Digit=1: anzeigen Ziffer 1
;Digit=0: andere Aktionen, keine Anzeige
btfsc STATUS, Z
goto Int_0 ; Z-Flag=1 ergo Digit=0
movfw Digit
movwf ar
decf ar, f
btfsc STATUS, Z
goto Int_1 ; Digit=1
decf ar, f
btfsc STATUS, Z
goto Int_2 ; Digit=2
decf ar, f
btfsc STATUS, Z
goto Int_3 ; Digit=3
goto Int_4 ; Digit=4
Int_0
movlw 5
movwf Digit
btfss StartSignal, 0
goto Int_end ; ist start freigegeben?
bsf PORTC, 3 ;relais aktivieren
decf Timer2, f ; von 5 bis 0 zählen (50 Hz / 5 = 10 Hz)
btfss STATUS, Z
goto Int_end ; Timer2 <> 0
movlw 5
movwf Timer2 ;zähl die Zehntelsekunden
decf Zehntel, f
movlw D'255'
subwf Zehntel, w ;überprüf ob die ziffer überlief
btfss STATUS, Z
goto Int_end
movlw D'9'
movwf Zehntel
decf Ziffer1, f ; Sekunden erhöhen
movlw D'255'
subwf Ziffer1, w
btfss STATUS, Z
goto Int_end ; Sekunden <> 10
movlw D'9'
movwf Ziffer1
decf Ziffer2, f ; ZehnerSekunden erhöhen
movlw D'255'
subwf Ziffer2, w
btfss STATUS, Z
goto Int_end ; Zehner Sekunden <> 10
movlw D'5'
movwf Ziffer2
decf Ziffer3, f ; EinerMinuten erhöhen
movlw D'255'
subwf Ziffer3, w
btfss STATUS, Z
goto Int_end ; EinerMinuten <> 255
movlw D'9'
movwf Ziffer3
decf Ziffer4, f ; 10er Minuten erhöhen
movlw D'255'
subwf Ziffer4, w
btfss STATUS, Z
goto Int_end ; 10er Minuten <> 10
movlw D'9'
movwf Ziffer4
goto Int_end
Int_1
movfw Ziffer1 ; Wert der 1. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bsf PORTA, 0 ; 1. Ziffer einschalten
goto Int_end
Int_2
movfw Ziffer2 ; Wert der 2. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bsf PORTA, 1 ; 2. Ziffer einschalten
goto Int_end
Int_3
movfw Ziffer3 ; Wert der 3. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bcf PORTB, DP ; Dezimalpunkt ein
bsf PORTA, 2 ; 3. Ziffer einschalten
goto Int_end
Int_4
movfw Ziffer4 ; Wert der 4. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bsf PORTA, 3 ; 4. Ziffer einschalten
goto Int_end
Int_end
movfw Ziffer1 ;Ziffer 1-4 werden logisch inklusic-or verknüpft
iorwf Ziffer2, w
iorwf Ziffer3, w
iorwf Ziffer4, w
btfsc STATUS, Z ;falls dabei 0 rauskomt, ist der zählerstand 00.00
call Nullzeit
swapf s_copy, w ; STATUS zurück
movwf STATUS
swapf w_copy, f ; w zurück mit flags
swapf w_copy, w
bcf INTCON, T0IF ; Interupt-Flag löschen
bsf INTCON, GIE ; enable Interupt
retfie
Nullzeit
bcf StartSignal, 0 ;Stoppe den Zählvorgang
bcf PORTC, 3 ;Schalte das Relais ab
return
; 7-Segment-Tabelle
Segmente
addwf PCL, f
retlw B'00011000' ; 0
retlw B'11011110' ; 1
retlw B'00110010' ; 2
retlw B'01010010' ; 3
retlw B'11010100' ; 4
retlw B'01010001' ; 5
retlw B'00010001' ; 6
retlw B'11011010' ; 7
retlw B'00010000' ; 8
retlw B'01010000' ; 9
;************************************************* *************
; Port A/B auf Ausgabe stellen
Init
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'11110000' ; PortA RA0-RA3 output
movwf TRISA
movlw B'00000000' ; PortB alle output
movwf TRISB
movlw B'11110111' ;PortC eingang ausser RC3
movwf TRISC
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
movlw 5
movwf Digit ; Ziffernzähler einstellen
; 250 Hz-Timer-Interupt einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'10000100' ; internen Takt zählen, Vorteiler zum Timer0, 32:1
movwf OPTION_REG
movlw D'131' ; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz)
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
movwf TMR0
movlw 5
movwf Timer2 ; 50Hz -> 10 Hz Teiler
;ausgangszustand
clrf StartSignal
clrf Ziffer1
clrf Ziffer2
clrf Ziffer3
clrf Ziffer4
clrf Zehntel
bcf PORTC, 3
bsf INTCON, T0IE ; Timer0 interupt erlauben
bsf INTCON, GIE ; Interupt erlauben
loop
btfss PORTC, 1
call SekundenTaste
btfss PORTC, 0
call MinutenTaste
btfss PORTC, 2
call StartTaste
goto loop ; eine Endlosschleife, die die Tasten abfragt
StartTaste
bsf StartSignal,0 ;setzte das Startsignal
return
SekundenTaste
call Wait
btfss PORTC, 1
goto SekundenTaste
call Wait
btfss PORTC, 1
goto SekundenTaste
call Wait ;entprellen
incf Ziffer1, f ;EinerSekunden erhöhen, falls größer 9 erfolgt ein übertrag auf ziffer 2
movlw D'10'
subwf Ziffer1, w
btfss STATUS, Z
return
clrf Ziffer1
incf Ziffer2, f
movlw D'6'
subwf Ziffer2, w
btfss STATUS, Z
return
clrf Ziffer2
return
MinutenTaste
call Wait
btfss PORTC, 0
goto MinutenTaste
call Wait
btfss PORTC, 0
goto MinutenTaste
call Wait ;entprellen
incf Ziffer3, f ;EinerMinuten erhöhen, falls größer 9 erfolgt übertrag auf ziffer4
movlw D'10'
subwf Ziffer3, w
btfss STATUS, Z
return
clrf Ziffer3
incf Ziffer4, f
movlw D'10'
subwf Ziffer4, w
btfss STATUS, Z
return
clrf Ziffer4
return
;warteroutine für 20ms
Wait
movlw D'131'
movwf Wait1
movlw D'250'
movwf Wait2
loop1
incf Wait1, f
btfss STATUS, Z
goto loop1
incf Wait2, f
btfss STATUS, Z
goto loop1
return
;************************************************* *********
end
man, das war der erste große brocken, den ich , wenn auch viel abgeguckt, alleine gemacht hab (natürlich mit hilfestellung)
bin ich stolz O:)
BlackBox
09.09.2004, 16:27
Wenn Du für den Interupt das CCP-Modul verwendest, dann bekommst Du die Zeit auch ganz genau eingestellt. Wenn deine Taktquelle nicht genau ist, dann kannst Du das Ganze sehr leicht eichen.
Bei dem Beispiel von Gast wurde das genauso gelöst.
BlackBox
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.