Archiv verlassen und diese Seite im Standarddesign anzeigen : Zählen mit PIC? aaaaaaarg!?
Hi Leute hab hier ein kleines Problem:
Ich möchte (um es endlich zu kapieren) mit einem Taster an RA4 und einer LED auf RB0 an
einem PIC 16F84 einen Zähler bis 10 (mit dem Timer 0) zum laufen bekommen.
Ich dachte eigentlich, dass ich das mit dem Code hier hinbekomme.
Aber ich find wohl den Fehler nicht.
Code:
list p=16f84
#include <P16f84.INC>
;************************************************* ********
; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator*
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC
;************************************************* ********
Ini_con Equ B'00000000' ; TMR0 -> Intetupt disable
Ini_opt Equ B'00000010'
;************************************************* *********
Init bsf STATUS, RP0 ; Bank 1
movlw Ini_opt ; pull-up on
movwf OPTION_REG
movlw B'11111000' ; RA0 .. RA2 outputs, RA3, RA4 input
movwf TRISA ;
movlw B'00000000' ; PortB alle outputs
movwf TRISB
bcf STATUS, RP0 ; Bank 0
clrf PORTA
clrf PORTB
movlw Ini_con ; Interupt disable
movwf INTCON
;************************************************* *********
bsf STATUS, RP0 ; Bank 1
bsf OPTION_REG, T0CS; RA4-Takt zum Timer0
bsf OPTION_REG, PSA ; noch ohne Vorteiler
bcf STATUS, RP0 ; Bank 0
main
bcf INTCON, T0IF
movlw D'245' <hier versuch ich
movwf TMR0 <den Zähler ab245
movlw B'00000000' <zählen zu lassen
movwf PORTB
BTFSC INTCON, T0IF
goto main
led movlw B'1111111'
movwf PORTB
end
Also wenn von euch einer ne Ahnung hat woran es liegen könnte dann
bitte gebt mir Bescheid.
Weitere Infos:
der Pic liegt (richtig gepolt) an +5V
ich habe mit dem Oszi meine saubere Schwingung vom Quarz an Osz1
der Taster ist mit einem Pulldown an RA4 angeschlossen (10k)
Reset liegt über 1k auf +5V
Mfg
Christian
BlackBox
02.07.2004, 11:07
Mmhhh,
dein Taster wird mit Sicherheit prellen. Zählen sollte der Timer aber trotzdem. Nach dem Anschalten der LED "rennt" der PIC aber den Rest des Programmspeichers durch und fängt irgendwann wieder von vorn an und schaltet die LED wieder aus.
BlackBox
Hi
also muss ich den Taster mit (z.B.nem Flipflop) entprellen und nochmal testen?
mfg
Christian
PS:
Dann müsst ich doch eigentlich mitm Oszi zumindest einen Nadelimpuls auf PortB feststellen können wenn ich den Taster mal betätige???
Hallo,
also ich sehe folgendes:
main
bcf INTCON, T0IF <<<<< hier clearst Du das INT-Flag
movlw D'245' <hier versuch ich
movwf TMR0 <den Zähler ab245
movlw B'00000000' <zählen zu lassen
movwf PORTB
BTFSC INTCON, T0IF <<<<< hier wird geskipt
goto main
led movlw B'1111111' <<<<< HI ausgeben
movwf PORTB
end <<<<<<<<< UND DANN ???????
Dein Programm läuft also genau einmal und anschliessend befindet sich der PIC im Nirwana. Bei END ist das Programm zu ende. Es wird nicht wieder von vorne gestartet!
Andreas
BlackBox
05.07.2004, 09:22
@Andreas,
doch, wird es wenn der PC am Ende des Programmspeichers angekommen ist. Sollte man aber nicht machen (hab ich oben doch schon geschrieben).
@BlackBox
Es ist aber nicht sichergestellt, das der PC am Ende ankommt. Das kommt schliesslich darauf an, was nach dem Programm im Speicher steht. Und das können auch Reste eines alten Programmes sein.
Andreas
BlackBox
06.07.2004, 07:40
@Andreas,
normalerweise wird der Flash komplett gelöscht, also mit NOPs ausgefüllt.
Wenn das aber nicht der Fall ist (evtl. bei Eigenbauprogrammern) dann hast Du damit Recht.
@Andreas also eins versteh ich jetzt nicht ich habe nochmal nachgemessen
Es gibt beit betätigung des Tasters (auch wenn er prellt) ja in meinem Programm einen Punkt wo der Ausgang irgendwann hi werden würde
=> Es gibt aber mit dem Oszi keinen einzigen Impuls beim starten des PIC auch nach einem Reset nicht
=> Auch wenn der PIC nur einmal das Programm abarbeitet müsste er ja ein hi an PortB irgendwann bringen
thx
Christian
Ich mal mal die Beschaltung auf
Christian
BlackBox
07.07.2004, 08:51
Dein OPTION-Register stimmt nicht.
Der Timer zählt mit internem Takt und Vorteiler 1:4.
BlackBox
Das versteh ich jetzt nicht ich hab doch
<<bsf OPTION_REG, T0CS; RA4-Takt zum Timer0
damit auf RA4 umgestellt oder stimmt die Übersicht
http://www.sprut.de/electronic/pic/grund/timer/timer.htm nicht?
thx Christian
Laut den Angaben auf der von Die genannten Seite (erste Wahl sollte IMMER das Datenblatt sein!!!) :
OPTREG:T0CS (=Bit 5) muss "1" sein für RA4->Timer
OPTREG:PSA (=Bit 3) muss "1" sein für Vorteiler OFF
Folglich sollte Dein Ini_opt so aussehen:
Ini_opt Equ B'00101xxx' x=egal
mit OPTREG:T0SE (=Bit 4) noch die richtige Flanke. die Du selektieren willst, einstellen.
Andreas
Hallo mal wieder
Also ich hab jetzt den Code geändert :
jetzt hab ich an PORTB dauernd Hi:
Ich hab das OPTREG so beschrieben
Ini_opt Equ B'00101000' wie Andreas es gesagt hat:
list p=16f84
#include <P16f84.INC>
;************************************************* ********
; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator*
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC
;************************************************* ********
Ini_con Equ B'00000000' ; TMR0 -> Intetupt disable
Ini_opt Equ B'00101000'
;************************************************* *********
Init bsf STATUS, RP0 ; Bank 1
movlw Ini_opt ; pull-up on
movwf OPTION_REG
movlw B'11111000' ; RA0 .. RA2 outputs, RA3, RA4 input
movwf TRISA ;
movlw B'00000000' ; PortB alle outputs
movwf TRISB
bcf STATUS, RP0 ; Bank 0
clrf PORTA
clrf PORTB
movlw Ini_con ; Interupt disable
movwf INTCON
;************************************************* *********
main
bcf INTCON, T0IF
movlw D'245'
movwf TMR0
movlw B'00000000'
movwf PORTB
BTFSC INTCON, T0IF
goto main
led movlw B'1111111'
movwf PORTB
end
Tja gebracht hat es nur das der PortB jetzt dauernd Hi ist ?!?
hat irgendjemand ein Beispiel wo mit einem PIC ereignisse Gezählt wurden und dann an einen oder mehrere Pins ausgegeben wurden???
Mfg
Christian
Versuchs mal so (ungetestet):
main:
bcf INTCON, T0IF ; Clear INT-Flag
movlw D'245' ; Timer preload
movwf TMR0
movlw B'00000000' ; port b auf "00000000"
movwf PORTB
loop:
BTFSC INTCON, T0IF ; Counter-Overflow?
goto port_on ; ja -> mach an
goto loop ; nein -> warten af weitere Tastendrucke
port_on:
movlw B'1111111' ; port b auf "11111111"
movwf PORTB
endlos ; und auf ewig warten
goto endloos ; (hier kommt was auch immer hin)
end
Das ganze funktioniert genau einmal - nach dem Einschalten ist PORTB auf "0", nach 10 (entprellten) Tastendrucken wird PORTB auf "1" gesetzt und auf ewig gewartet. Das entprellen kann man auch in Software machen.
Ich hoffe das funktioniert und macht es Dir aunschaulich.
Andreas
Vielen Dank an alle
besonderst an Andreas dein Code funktioniert ich finde nur bis auf die Schleife am Ende
keinen Unterschied?!?
Ich hab den Code hier noch mal gepostet, falls jemand nochmal so ein Problem hat.
Code:
list p=16f84
#include <P16f84.INC>
;************************************************* ********
; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator*
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC
;************************************************* ********
Ini_con Equ B'00000000' ; TMR0 -> Interupt disable
Ini_opt Equ B'00101000'
;************************************************* *********
Init:
bsf STATUS, RP0 ; Bank 1
movlw Ini_opt ; pull-up on
movwf OPTION_REG
movlw B'11111000' ; RA0 .. RA2 outputs, RA3, RA4 input
movwf TRISA ;
movlw B'00000000' ; PortB alle outputs
movwf TRISB
bcf STATUS, RP0 ; Bank 0
clrf PORTA
clrf PORTB
movlw Ini_con ; Interupt disable
movwf INTCON
;************************************************* *********
main:
bcf INTCON, T0IF ; Clear INT-Flag
movlw D'245' ; Timer preload
movwf TMR0
movlw B'00000000' ; port b auf "00000000"
movwf PORTB
loop:
BTFSC INTCON, T0IF ; Counter-Overflow?
goto port_on ; ja -> mach an
goto loop ; nein -> warten af weitere Tastendrucke
port_on:
movlw B'1111111' ; port b auf "11111111"
movwf PORTB
endlos:
; und auf ewig warten
nop
nop
goto endlos ; (hier kommt was auch immer hin)
end
Also nochmal danke bis denne
Mfg
Christian
ich hab mal mit nem pic nen inkrementgeber auslesen müssen. d.h. ne art drehschalter. wenn man den dreht, gibt der in sehr kleinen abständen high-low-high-low-high-low......
und ich sollte halt zählen, wie oft.
ich sage im vorraus, dass das ganze nie funktioniert hat (habs irgendwann aufgegeben, lag aber mit sicherheit an was pic-intenem, der konnte die variable nicht speichern oder so..)
also aufgemerkt:
ich hatte 2 schleifen, eine für den high-zustand des inktementgebers und eine für den low-zustand. war er z.b. high, blieb er so lange in der high-schleife, bis er low wurde. dann wurde die variable um 1 incrementiert und es ging in die low-schleife. da passierte dann wieder das gleiche.
es ist ja so:
mann kann auch einfach zählen, z.b. jedes mal wenn ein high-signal anliegt einen hoch. das prob ist dann, dass der inkrementgeber auf high stehenbleiben kann und dann zählt sich der pic tot. also hab ich's gemacht wie oben beschrieben. vielleicht kannst du das auf deinen taster übertragen.
frag mich nicht nach dem code, der ist in der firma, in der ich das gemacht hab... (semesterferien) :P
edit:
mal den code verdeutlicht:
(in nem dirt-basic:)
--------------------
if port=high then goto highschleife else goto lowschleife 'start vom ganzen
highschleife:
if port=low then goto lowzähler
goto highschleife
lowschleife:
if port=high then goto highzähler
goto lowschleife
highzähler
inc variable 'zählt variable um eins hoch
goto highschleife
lowzähler
inc variable
goto lowzähler
-------------------
klar?
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.