PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zählen mit PIC? aaaaaaarg!?



doener
01.07.2004, 16:26
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, 10: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

02.07.2004, 14:01
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???

Softi
04.07.2004, 13:19
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, 08: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).

05.07.2004, 19:36
@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, 06: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.

doener
06.07.2004, 17:58
@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

doener
06.07.2004, 18:01
Ich mal mal die Beschaltung auf
Christian

BlackBox
07.07.2004, 07:51
Dein OPTION-Register stimmt nicht.

Der Timer zählt mit internem Takt und Vorteiler 1:4.

BlackBox

09.07.2004, 01:03
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

09.07.2004, 12:19
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

doener
09.07.2004, 14:16
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

09.07.2004, 19:56
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

doener
12.07.2004, 20:58
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

Goblin
16.07.2004, 11:03
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?