k.p.meinesz
Een schizofreen is nooit alleen!
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.
Confusion
There are only 10 types of people in the world - those who understand binary, and those who don't
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.
k.p.meinesz
Een schizofreen is nooit alleen!
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.
k.p.meinesz
Een schizofreen is nooit alleen!
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.
k.p.meinesz
Een schizofreen is nooit alleen!
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.
Bastiaan
Bachelor of Engineering -- Microcontrollers AVR, PIC (asm, C), PC applicaties (C, C++), Webpages (HTML, CSS, PHP, SQL), Rail-infra engineer
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.
k.p.meinesz
Een schizofreen is nooit alleen!
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
k.p.meinesz
Een schizofreen is nooit alleen!
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.
k.p.meinesz
Een schizofreen is nooit alleen!
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!
k.p.meinesz
Een schizofreen is nooit alleen!
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