Zoals jullie mischien weten be ik bezig die binaire klok te maken met een pic16f84.
Nu heb ik alles opgebouwd op een breadbord en.. het werkt
okee loopt niet op tijd (word aan gewerkt)

nu heb ik van poort B pin 6 en 7 als input geprogt
dit is om de tijd te setten maar als ik een van die poorten
5v geef slaat de pic dicht d.w.z. alles gaat uit en blijft uit
of als ik de poort in mijn routine weer op 0 zet dan is en blijft het net een discotheek
Ik doe dus iets fout maar wat

Het proggen is het probleem niet maar ik denk dat ik met de electronica de fout in ga.
dus wat is de basismethode om een poort hoog te maken
of laag te trekken?(doorhalen wat niet van toepassing is)

Op 18 december 2002 00:00:57 schreef k.p.meinesz:
nu heb ik van poort B pin 6 en 7 als input geprogt
dit is om de tijd te setten maar als ik een van die poorten
5v geef slaat de pic dicht d.w.z. alles gaat uit en blijft uit
of als ik de poort in mijn routine weer op 0 zet dan is en blijft het net een discotheek

Hmm...Dit snap ik niet. Is die B7/B6 nou een input of een output?
Ik kan niet naar je breadboard kijken, maar je code wil ik wel bekijken (alleen als het in mpasm geschreven is) Als het te groot is om te posten, kun je 'm naar me mailen.
Voor zover ik weet is dit geen gemultiplexte poort, dus zou niet voor problemen moeten zorgen.

Als je routines voor het bijhouden van de klok gewoon naar behoren werken lijkt mij dat de voeding en het crystal juist zijn aangesloten, dus ik denk dat het toch aan je code ligt.

Met 'slaat de pic dicht' bedoel je vastlopen / resetten ?

Dit komt waarschijnlijk door een kortsluiting aangezien dit bij het indrukken gebeurd.
- Gebruik je een te lage pull-down/up weerstand?
- Heb je de pennen zeker weten als ingang gedefinieerd?
- Ergens anders een kortsluiting gemaakt?

dus wat is de basismethode om een poort hoog te maken
of laag te trekken?

Dit is geen geen verklaring voor je probleem,maar beide manieren zijn goed, zolang je de pen maar de andere kant op trekt wanneer de schakelaar niet wordt bediend (pull-down/up). Dit kan met een 10K weerstand.
Overigens heeft Poort B al een interne Pull-up, dit wil dus zeggen dat wanneer je deze pen niet aansluit de Pic een 1 ziet, om dan een nul te lezen moet je hem dus via de schakelaar aan de gnd hangen.
Deze interne pull-up staat niet standaard aan, dus daar moet je even de datasheet voor door spitten.

Op 18 december 2002 00:39:58 schreef DIY:

[...]

Hmm...Dit snap ik niet. Is die B7/B6 nou een input of een output?
Ik kan niet naar je breadboard kijken, maar je code wil ik wel bekijken (alleen als het in mpasm geschreven is) Als het te groot is om te posten, kun je 'm naar me mailen.
Voor zover ik weet is dit geen gemultiplexte poort, dus zou niet voor problemen moeten zorgen.

Als je routines voor het bijhouden van de klok gewoon naar behoren werken lijkt mij dat de voeding en het crystal juist zijn aangesloten, dus ik denk dat het toch aan je code ligt.

b6/7 is input maar als ik de poort hoog maak lijkt de pic er voorgoed(tot reset) mee te stoppen
echter als ik dit doe loopt het wel maar is het niet te stoppen


         btfsz portb,6
         call  incmin
         btfsz portb,6
         call  inchour
         return
inchour  incf  min,1
         call debounce
         bcf  portb,6
         return
incmin(idem inchour)

Jep, pullups/downs moeten er wel inzitten.

Verder doe je in je code iets wat ik niet begrijp.

Je leest poortB.6 in en kijkt of deze hoog of laag is.
Als tie hoog is dan hoog je minuten op; als tie laag is kijk je of portB.6 hoog of laag is...Uhh..
Je kijkt dus twee keer achter elkaar of poortA.6 hoog of laag is...TypeFoutje?

Ik neem aan (je eerste post), dat je eerst poortB.7 en dan poortB.6 'checkt'.
Goed als dat zo is, dan nog..

Je stopt je debounce routines in de routine waar je actie onderneemt vanwege een keypress..-->Die actie moet je ondernemen zodra de debounce gedaan is en je dus ZEKER weet dat er een keypress is.
Nu ga je een subroutine in, terwijl de toets 'nog aan het denderen' is.
Je moet EERST 'debouncen'. De processor kan anders een 'keyrelease' zien als een 'keypress'!

Wat ik ook niet begrijp is wat je wilt bereiken door poortB.6 laag te maken. PoortB.6 is een input!
De inhoud van het poortB-latch register wordt gedomineerd door signalen van buiten af.
-->De code moet gewoon weer terugvallen in de main-routine nadat het 'minuten'- of 'uren'-register is opgehoogd. Let alleen wel dat de processor de toets heel veel keer per seconde scant, dus 1 keypress kan wel een hoop incrementjes veroorzaken. Een extra pauseroutine inlassen is wel slim om dit te voorkomen.

Op 18 december 2002 23:10:24 schreef DIY:
Jep, pullups/downs moeten er wel inzitten.

Verder doe je in je code iets wat ik niet begrijp.

Je leest poortB.6 in en kijkt of deze hoog of laag is.
Als tie hoog is dan hoog je minuten op; als tie laag is kijk je of portB.6 hoog of laag is...Uhh..
Je kijkt dus twee keer achter elkaar of poortA.6 hoog of laag is...TypeFoutje?

yep

Je stopt je debounce routines in de routine waar je actie onderneemt vanwege een keypress..-->Die actie moet je ondernemen zodra de debounce gedaan is en je dus ZEKER weet dat er een keypress is.
Nu ga je een subroutine in, terwijl de toets 'nog aan het denderen' is.
Je moet EERST 'debouncen'. De processor kan anders een 'keyrelease' zien als een 'keypress'!

dat zou het weleens kunnen zijn.

Wat ik ook niet begrijp is wat je wilt bereiken door poortB.6 laag te maken. PoortB.6 is een input!
De inhoud van het poortB-latch register wordt gedomineerd door signalen van buiten af.
-->De code moet gewoon weer terugvallen in de main-routine nadat het 'minuten'- of 'uren'-register is opgehoogd. Let alleen wel dat de processor de toets heel veel keer per seconde scant, dus 1 keypress kan wel een hoop incrementjes veroorzaken. Een extra pauseroutine inlassen is wel slim om dit te voorkomen.

dit had ik eens geprobeert om te kijken wat er dan gebeurt
omdat ik het gevoel had dat de processor bleef hangen in de keypad routine
nu als ik hem dus laag stuurde via het programma dan zag ik duidelijk dat hij elke keer idd er 1 minuut bij optelde
maar hij stopte nooi meer.
ik zal de code ff posten.


STATUS		equ	03h
INTCON		equ	8bh
TRM0		equ	01h
TRISA		equ	86h
TRISB		equ	85h
PORTA		equ	05h
PORTB		equ	06h
tempw		equ	40h
temps		equ	41h
sec		equ	42h
secs		equ	43h
min		equ	44h
mins		equ	45h
hour		equ	46h
hours		equ	47h
pausea		equ	48h
pause2		equ	4ch
pauzeb		equ	49h
time1		equ	4ah
time2		equ	4bh
pause2a		equ	4ch


		org	00h
		goto	init
;_____________________________________________________________
		org	04h
		movwf	tempw
		swapf	STATUS,w
		movwf	temps
;_____________________________________________________________
		movlw	10h
		movwf	TRM0
		call 	inc1
;______________________________________________________
		swapf	temps,w
		movwf	STATUS
		swapf	tempw,f
		swapf	tempw,w
		bcf	INTCON,2
		retfie
;_________________________________________________________________
init1		bsf	03,5
		bcf	INTCON,2
		bsf	INTCON,7
		bsf	INTCON,5
		movlw	0fh
		movwf	TRM0	
		movlw	b'01001000'
		movwf	81h
		bcf	03,5
		movlw	0fh
		movwf	TRM0
		return
;___________________________________________________________________
init2		bsf	03,5
		movlw	b'00000000'
		movwf	TRISA
		movlw	b'11000000'
		movwf	TRISB
		bcf	03,5
		return
;___________________________________________________________________
init3		movlw	00h
		movwf	sec
		movwf	secs
		movwf	min
		movwf	mins
		movwf	hour
		movwf	hours
		movwf	time1
		movwf	time2
		return
;____________________________________________________________________
display		clrf	PORTA
		movf	sec,0
		movwf	PORTA
		bsf	PORTB,0
		call	pause1
		bcf	PORTB,0
		clrf	PORTA
		movf	secs,0
		movwf	PORTA
		bsf	PORTB,1
		call	pause1
		bcf	PORTB,1
		clrf	PORTA
		movf	min,0
		movwf	PORTA
		bsf	PORTB,2
		call	pause1
		bcf	PORTB,2
		clrf	PORTA
		movf	mins,0
		movwf	PORTA
		bsf	PORTB,3
		call	pause1
		bcf	PORTB,3
		clrf	PORTA
		movf	hour,0
		movwf	PORTA
		bsf	PORTB,4
		call	pause1
		bcf	PORTB,4
		clrf	PORTA
		movf	hours,0
		movwf	PORTA
		bsf	PORTB,5
		call	pause1
		bcf	PORTB,5
		clrf	PORTA
		return
;____________________________________________________________
check_time1	incf	sec,f
		movlw	00h
		movwf	time1
		movwf	time2
check_time	movlw	d'10'
		subwf	sec,0
		btfsc	STATUS,2
		goto	inc_secs
		movlw	d'06'
		subwf	secs,0
		btfsc	STATUS,2
		goto	inc_min
		movlw	0ah
		subwf	min,0
		btfsc	STATUS,2
		goto	inc_mins
		movlw	06h
		subwf	mins,0
		btfsc	STATUS,2
		goto	inc_hour
		movlw	04h
		subwf	hour,0
		btfsc	STATUS,2
		call	hour_check
		movlw	0ah
		subwf	hour,0
		btfsc	STATUS,2
		call	inc_hours
		return
;______________________________________________________________
hour_check	movlw	02h
		sublw	hours
		btfsc	STATUS,2
		call	reset
		return
;_______________________________________________________________
reset		movlw	00h
		movwf	hours
		movwf	hour
		return
;_______________________________________________________________
inc_secs	incf	secs,f
		clrf	sec
		return
;____________________________________
inc_min		incf	min,f
		clrf	secs
		return
;_____________________________________
inc_mins	incf	mins,1
		clrf	min
		return
;_____________________________________
inc_hour	incf	hour,1
		clrf	mins
		return
;_____________________________________
inc_hours	incf	hours,1
		clrf	hour
		return
;_____________________________________
keypad		btfsc	PORTB,6
		call	incmin
		btfsc	PORTB,7
		call	inchour
		return
;______________________________
incmin		incf	min,1		
		call	check_time2
		call	display
		call	decrout
		return
;___________________________________
inchour		incf	hour,1
		call	check_time2
		call	display
		call	decrout
		return
;____________________________________
decrout		movlw	0fh
		movwf	pause2
verder1		movlw	0ffh
		movwf	pause2a
decrout1	decfsz	pause2a,f
		goto	decrout1
		decfsz	pause2,f
		goto	verder1
		return
;_____________________________________
pause1		movlw	04h
		movwf	pausea
verder		movlw	0ffh
		movwf	pauzeb
decrouta	decfsz	pauzeb,f
		goto	decrouta
		decfsz	pausea,f
		goto	verder
		return
;________________________________________
init		call	init2
		call	init1
		call	init3
		goto	loop
;__________________________________________
loop		call	display
		call	check_time
		call	keypad
		goto	loop
;____________________________________________
inc2		incf	time2,f
		movlw	d'40'
		subwf	time2,w
		btfsc	STATUS,2
		call	check_time1
		return
inc1		incf	time1,f
		movlw	d'250'
		subwf	time1,w
		btfsc	status,2
		call	inc2
		return
;______________________________________________	
		end
;_______________________________________________


; PIC 16f84a op 10 MHZ
; 1 instucktie=400ns (ongeveer)
; 400ns*241*40*250=1sec (ongeveer) loopt nu 4 min per 290 min voor
;_______________________________________________

dit is het eerste programma wat ik heb geschreven en ook werkelijk in een pic geprobeerd heb het werkt dus voor 99
% in een keer maar dat keypadje wil niet wat ik wil.
extra info:
ra0/4 datalijn via 250 ohm naar led naar collector bc 547
rb0/5 multiplexlijnen via 1k naar basis bc547
emittor bc 547 ground
rb0,ra0/ra4 seconden
rb1,ra0/ra4 10 seconden
rb2,ra0/ra4 minuten
rb3,ra0/ra4 10 minuten
enz.

Wow...een hoop code en geen commentaar..Daar is lastig doorheen te komen als je code niet zelf geschreven hebt!

Het is bijna onmogelijk om deze code te lezen maar ik heb wel wat dingen gezien waar ik een ? bij zet.

Op het moment dat de power aangezet wordt, wordt de code gedirigeerd naar de Initialisatie-routines Init1, Init2 en Init3. In Init1 definieer je je interrupt-bron: Interrupt on Timer0-overflow. Da's duidelijk en juist gedeclareerd.
Vervolgens ga je in het optionregister de trigger-edge van poortB definieren. Waarom?
In het optionregister wijs je de prescaler vervolgens toe aan de watchdog-timer, die je volgens mij niet gebruikt.
De watchdogtimer zorgt er (onder andere) voor dat de processor in sleepmode terecht komt.

En je bent zowiezo iets vergeten wat misschien ook wel voor heibel kan zorgen:
Zodra de code in de InterruptServiceRoutine terecht komt, MOET je bit7 (global interrupt enable) DISablen. Dit voorkomt eventuele conflicten.
Ik zie verder zo snel geen 'fouten', maar waar is je debounce routine gebleven?

Grote tip: schrijf je code logisch, voorzie zo veel mogelijk instructies van kort commentaar en maak voor twee instructies geen subroutine aan. Dit zal foutzoeken een stuk eenvoudiger maken.

Dat wat nederland zo vreselijk maakt is precies het gene wat onmisbaar is in assembly: structuur.

Ik vind het nog wel meevallen. Je kunt het best goed lezen zonder commentaar aangezien het is opgedeeld in stukken die een naam hebben of code zoals bijvoorbeeld 'inchour' wat wel een routine zal zijn die het uur met 1 verhoogt. Meestal is commentaar idd wel handig maar het is vanwege zijn vele "subroutines" zeer overzichtelijk en leesbaar opgezet.

Is misschien wel waar, maar ik denk dat ik, mbt assembly, 'over-gestructureerd' ben geworden. De code is inderdaad wel te volgen als je wilt. Het ontbreken van commentaar blijft echter wel lastig.

Op 19 december 2002 18:50:41 schreef DIY:
Wow...een hoop code en geen commentaar..Daar is lastig doorheen te komen als je code niet zelf geschreven hebt!

ja daar was ik al bang voor maar de labels zeggen genoeg

Op het moment dat de power aangezet wordt, wordt de code gedirigeerd naar de Initialisatie-routines Init1, Init2 en Init3. In Init1 definieer je je interrupt-bron: Interrupt on Timer0-overflow. Da's duidelijk en juist gedeclareerd.
Vervolgens ga je in het optionregister de trigger-edge van poortB definieren. Waarom?

foutje is een van mijn debug probeersels

In het optionregister wijs je de prescaler vervolgens toe aan de watchdog-timer, die je volgens mij niet gebruikt.
De watchdogtimer zorgt er (onder andere) voor dat de processor in sleepmode terecht komt.

WTD=uit maar in datasheet staat:"When the prescaler is assigned to the WTD(psa='1'),TRM0 has a 1:1 prescaler assignment"als ik dit niet doe word de prescaler automatisch 1:2

En je bent zowiezo iets vergeten wat misschien ook wel voor heibel kan zorgen:
Zodra de code in de InterruptServiceRoutine terecht komt, MOET je bit7 (global interrupt enable) DISablen. Dit voorkomt eventuele conflicten.
Ik zie verder zo snel geen 'fouten', maar waar is je debounce routine gebleven?

debounce heet hierin Decrout maar ik voorzag al dat dit een beetje slorig was dus voor het voorbeeldje ff herschreven. bit 7 disabelen okee dan dacht echter dat het geen kwaad kon omdat ik maar 1 interupt gebruik nl TRM0

Grote tip: schrijf je code logisch, voorzie zo veel mogelijk instructies van kort commentaar en maak voor twee instructies geen subroutine aan. Dit zal foutzoeken een stuk eenvoudiger maken.

Zo erg is het toch niet het is vrij simpel te lezen
maarje zoals al eerder gezegt heb het ook zelf geschreven

Kun je je code simuleren? Ik denk dat dat ondertussen wel handig kan zijn. Sommige statements lijken wel eens kloppend te zijn, maar tijdens simulatie blijkt soms wel eens het tegendeel. Je kunt stomme dingen over het hoofd zien, net als ik en ieder ander die probeert mee te denken.

Is alleen wel lullig dat je inputs hebt...moet je weer zo'n stimulusfile aanmaken...
Maar goed...In ieder geval blijven volhouden! Het gaat op een gegeven moment echt wel werken!

Succes

Ja ik kan het simuleren ik gebruik MPLAB
maar dat duurt zo verschrikkelijk lang voordat er een seconde voorbij is.
zo heb ik er al wat foutjes uitgekregen
maar rb6/7 input krijg ik niet voor mekaar
en MPLAB genereerd soms een hoge poort terwijl dit niet kan
zelfs als ik de poort laag zet blijft deze hoog (in simulatie dan)

daarom probeer ik het nu eens met de collectieve wijsheid
van het forum

Ik denk zelf dat de fout in mijn debounce(decrout)routine zit dit is nl gewoon een pauzeloop.
dus ik maak een poort hoog increment minuten en ga in pauze
moet iets zijn van maak poort hoog ga in pauze is poort nog hoog ja ga naar increment min nee terug

[Bericht gewijzigd door k.p.meinesz op ]

Jep, dat laatste klopt.

Ik heb een debounce routine gebruikt om een gehele poort te scannen (poortD, alle lijnen individueel met een toets verbonden).
Voorbeeldstukje:

;------MAIN PROGRAM---
start call ReadPortD
...
...
stuk code om actie te ondernemen afhankelijk van de ingelezen waarde
...
...
overige code
...
...
goto start
;-----END OF MAIN-PROGRAM---
;
;
;-----SUBROUTINES-----
ReadPortD movf portD,w
movwf ValueD
call Pause
movf portD,w
subwf ValueD,w
btfss status,2
goto ReadPortD
return
...
...
;-----END OF SUBROUTINES----

Het feit dat het hier om een hele poort gaat ipv een individuele poortlijn maakt qua principe niet uit.
Als Pause-tijd heb ik 300us aangehouden. Doet het goed.
Dit principe werkt, dus...
Het register ValueD (zelfverzonnen variabele) heeft bij terugkomst uit de subroutine de waarde van de poort in zich.

Als je dit principe wilt kopieren moet je effe opletten dat dit stuk code byte-operaties uitvoert en dat is eenvoudiger dan bit-operaties volgens mij.

Je gebruikt dus gewoon een mask(valued)
jij schrijft de waarde van poortx weg naar het register
last een pauze in
lees je poort x nogmaals en haalt daar de mask waarde
weer af
indien 0
poort hetzelfde als begin dus toets
snap ik maar poort b verandert bij mij
dus word het zoiets:


          btfsz portb,6
          call  incmin
          btfsz portb,7
          call  incmin
          return
incmin    movlw 0ffh
          movwf pause1
pauseb    movlw 0ffh
          movwf pause2
pausea    decfsz pause2
          goto pausea
          decfsz pause1
          goto pauseb
          btfsz portb,6
          call incmin2
          return
incmin2   incf min,w
          return

volgens mij gaat dit werken
btw je kunt een poort hoog maken met een 10k in serie met je voeding?
of is die voorschakelweerstand niet nodig bij een input?
bij mij lijkt hij dan nl niet te slikken.

Ziet er inderdaad okey uit. Ik zou het effe proberen!
En ja, ik voorzie ingangen aan Vcc altijd van een weerstandje 10k. Ik neem aan dat poortB7 en B6 dat bij jou toch ook hebben?

Of dat nou voor toetsloze ingangen echt nodig is weet ik niet, ingangsR is hoog, maar ja...Toen ik met PIC's begon zag ik die weerstand in alle applicaties dus deed ik dat ook maar.

Maaruh..laat effe horen of het werkt!

Nou ik heb het geprobeerd maar helaas:'(
als ik poort b hoog probeer te maken via 10k reageert hij niet
als ik hem gewoon 5v voed dan wel.
maar de poort blijft hoog dus een debounce heeft geen enkel nut de poort is hoog blijft hoog dus ook na een debounce gemeten waarde aan de poort=0v
ik moet hem actief laag maken dwz gnd tegen poort houden om de pic te laten stoppen
of BCF portb,6
ook als ik de poort via 1k aan gnd leg blijft hij doorgaan
BTW ik laat nu wel de GIE uitzetten als er een poort hoog gemaakt word
en zet hem weer aan als de poort weer laag is