nonkel_dw
nonkel dw
Goedenmorgen
Ik ben al 2 dagen aan het knoeien met timer 0.
Ik krijg het niet gevonden hoe ik deze aan de praat krijg.
Ik moet om de 50µs een interupt krijgen.
BANK1
; ZET DE INTERUPT AAN TIMER 0
BSF INTCON,GIE ; ZET GLOBAL INTERUPT AAN
BSF INTCON,T0IF ; ZET DE INTERUPT VAN TIMER 0 AAN
;TIMER 0
BCF OPTION_REG,T0CS ; INTERNE CLOCK VAN DE uC
BCF OPTION_REG,PSA ; TIMER 0 MODULE
BANK0
;TIMER 0 VALUE
MOVLW D'50'
MOVWF TMR0 ; ZET DIT IN TIMER 0
Ik werk met een pic 16f870 20MHz.
Ik moet ook in men acht hoofd houden dat ik die tijd moet kunnen aan passen als het programma aan he lopen is.
Dit kan tot max 0 tot 255 aan nemen.
Ik hoop dat jullie mij op goede weg kunnen zetten.
alvast bedankt
Bart Hiddink
Bart Hiddink is Ideetron; electronics and projects, http://www.ideetron.nl. LoRaWAN Nutcase.
Ik mis je ISR en daarin moet je ook de interrupt zelf wissen.
Ik denk dat het daar fout gaat.
Deze code ziet er goed uit.
Maar een interrupt elke 50us is wel erg kort.
De bedoeling van een interrupt is dat het incidenteel en asyncroon het normale programma onderbreekt.
De chip zal het weldoen, want er is geen beperking voor de snelheid, anders dan de tijdsduur voor het uitvoeren van de code in de ISR.
Om een timer0 interrupt te krijgen zul je toch minstens het TOIE bit moeten setten in het INTCON-register.
(en niet het TOIF-bit)
nonkel_dw
nonkel dw
Zo iets dacht ik ook.
Maar ik kan aan de datacheet niet echt aan uit.
Hebben jullie een voorbeeld code ?
En wat is een ISR ?
Bart Hiddink
Bart Hiddink is Ideetron; electronics and projects, http://www.ideetron.nl. LoRaWAN Nutcase.
Een Interrupt Service Routine.
Dat is een stukje code wat op een bepaald adres begint waarin je de afhandeling van de interrupt bepaald.
Het stukje eindigd met RETFIE.
Lees dit maar even.
nonkel_dw
nonkel dw
Dit stuk heb ik.
Maar als de timer 0 geen interupt genereerd ben ik er niets mee.
en dat is nog steets niet 
Je wilt een voorbeeldje van een timer o ISR, hier staat er 1 in. Zoekt en gij zult vinden 
Hint: refresh display.
nonkel_dw
nonkel dw
bedankt
Zo heb ik de routine ook geschreven.
Maar ik krijg geen interupt.
dit is nu de code
ORG 04H
MOVWF W_SAVE ;save context,
MOVF STATUS,W ;save STATUS, PCLATH & W
MOVWF S_SAVE
MOVF PCLATH,W
MOVWF P_SAVE
BCF INTCON,T0IF ;RESETTEN VAN INTERUPT TIMMER 0
INCF TELLER,W ;VERHOOG DE TELLER MET 1
CALL OPTIETBL ; GA NU NAAR DE TABEL
MOVWF CCPR1L
MOVF TELLER,W ; IS DE WAARDE VAN TELLER
XORWF VASTEWAARDE ; GELIJK AAN VASTE WAARDE 200 DUS ALLE SYCLUSSEN VOOR BIJ
BTFSC STATUS,Z
CLRF TELLER ; DAN CLEAREN WE DE TELLER EN BEGINNEN WE OP NIEUW
GOTO EX_INT ; ANDERS GEWOON VERDER DOEN EN EINDE INTERUPT
EX_INT
MOVF P_SAVE,W ;restore context
MOVWF PCLATH
MOVF S_SAVE,W
MOVWF STATUS
SWAPF W_SAVE,F ;
SWAPF W_SAVE,W ;
RETFIE ; BEEINDIG INTERUPT
org 0x00h
INIT
BSF STATUS,RP0 ; GA NAAR BANK 1
MOVLW B'11111111'
MOVWF TRISA
MOVLW B'00000000'
MOVWF TRISB
MOVWF TRISC ;POORT B EN C UITGANGEN
; ZET DE INTERUPT AAN TIMER 0
BSF INTCON,GIE ; ZET GLOBAL INTERUPT AAN
BSF INTCON,T0IE ; ZET DE INTERUPT VAN TIMER 0 AAN (BIJ EEN LEGE INTERUPT SET DE BIT)
;TIMER 0
MOVLW B'11011110'
MOVWF OPTION_REG
;PWM
MOVLW 0x3F ; SET DE PWM
MOVWF PR2
BCF STATUS,RP0 ; TERUG NAAR BANK0
;TIMER 0 VALUE
MOVLW D'50'
MOVWF TMR0 ; ZET DIT IN TIMER 0
;PWM
BSF CCP1CON,4
BSF CCP1CON,5
BSF T2CON,TMR2ON
BCF T2CON,1
BCF T2CON,0 ; ZET DE PRESCALER
CLRF TELLER
MOVLW D'200'
MOVWF VASTEWAARDE
GOTO MAIN
Dit is men code
Ik zie geen fout meer
Ik zie geen fout meer
Maar de assembler wel. Die heeft een dikke fout opgegeven die jij dus negeert?
Bovenaan staat org 004H
Verderop bij INIT staat org 000
Het tweede deel van het programma wodt dus over het eerste heen geschreven....
nonkel_dw
nonkel dw
Ik heb het zo gezet.
Hij asembleert hij alles juist.
Ik heb stukken gecopierd,
omdat anders een hele blz vol staat.
Dit is idd niet de hele code.
Maar hier zie je wel hoe ik alles geset heb.
[Bericht gewijzigd door nonkel_dw op (26%)]
nonkel_dw
nonkel dw
Zo er wert gevraagt heel de code te posten hier is ze dan.
list P=16F870a
#INCLUDE <P16F870.INC>
__CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC & _LVP_OFF
CBLOCK 0X20
W_SAVE
S_SAVE
P_SAVE
TELLER
PCI
VASTEWAARDE
TIJD
ENDC
ORG 00h
GOTO INIT
ORG 04H
MOVWF W_SAVE ;save context,
MOVF STATUS,W ;save STATUS, PCLATH & W
MOVWF S_SAVE
MOVF PCLATH,W
MOVWF P_SAVE
BCF INTCON,T0IF ;RESETTEN VAN INTERUPT TIMMER 0
INCF TELLER,W ;VERHOOG DE TELLER MET 1
MOVF TELLER,W
CALL OPTIETBL ; GA NU NAAR DE TABEL
MOVWF CCPR1L
MOVWF CCPR1H
MOVF TELLER,W ; IS DE WAARDE VAN TELLER
XORWF VASTEWAARDE ; GELIJK AAN VASTE WAARDE 200 DUS ALLE SYCLUSSEN VOOR BIJ
BTFSC STATUS,Z
CLRF TELLER ; DAN CLEAREN WE DE TELLER EN BEGINNEN WE OP NIEUW
GOTO EX_INT ; ANDERS GEWOON VERDER DOEN EN EINDE INTERUPT
OPTIETBL
ADDWF PCI,F ; VERGELIJK DE WAARDE EN VOER UIT
RETLW D'128'
RETLW D'132'
RETLW D'136'
RETLW D'139'
RETLW D'143'
RETLW D'147'
RETLW D'150'
RETLW D'154'
RETLW D'158'
RETLW D'161'
RETLW D'165'
RETLW D'169'
RETLW D'172'
RETLW D'176'
RETLW D'179'
RETLW D'182'
RETLW D'186'
RETLW D'189'
RETLW D'192'
RETLW D'195'
RETLW D'199'
RETLW D'202'
RETLW D'204'
RETLW D'207'
RETLW D'210'
RETLW D'213'
RETLW D'215'
RETLW D'218'
RETLW D'220'
RETLW D'223'
RETLW D'225'
RETLW D'227'
RETLW D'229'
RETLW D'231'
RETLW D'233'
RETLW D'235'
RETLW D'237'
RETLW D'238'
RETLW D'240'
RETLW D'241'
RETLW D'242'
RETLW D'243'
RETLW D'244'
RETLW D'245'
RETLW D'246'
RETLW D'247'
RETLW D'247'
RETLW D'247'
RETLW D'248'
RETLW D'248'
RETLW D'248'
RETLW D'248'
RETLW D'248'
RETLW D'247'
RETLW D'247'
RETLW D'247'
RETLW D'246'
RETLW D'245'
RETLW D'244'
RETLW D'243'
RETLW D'242'
RETLW D'241'
RETLW D'240'
RETLW D'238'
RETLW D'237'
RETLW D'235'
RETLW D'233'
RETLW D'231'
RETLW D'229'
RETLW D'227'
RETLW D'225'
RETLW D'223'
RETLW D'220'
RETLW D'218'
RETLW D'215'
RETLW D'213'
RETLW D'210'
RETLW D'207'
RETLW D'204'
RETLW D'202'
RETLW D'199'
RETLW D'195'
RETLW D'192'
RETLW D'189'
RETLW D'186'
RETLW D'182'
RETLW D'179'
RETLW D'176'
RETLW D'172'
RETLW D'169'
RETLW D'165'
RETLW D'161'
RETLW D'158'
RETLW D'154'
RETLW D'150'
RETLW D'147'
RETLW D'143'
RETLW D'139'
RETLW D'136'
RETLW D'132'
RETLW D'128'
RETLW D'124'
RETLW D'120'
RETLW D'117'
RETLW D'113'
RETLW D'120'
RETLW D'117'
RETLW D'113'
RETLW D'109'
RETLW D'106'
RETLW D'102'
RETLW D'98'
RETLW D'95'
RETLW D'91'
RETLW D'87'
RETLW D'84'
RETLW D'80'
RETLW D'77'
RETLW D'74'
RETLW D'70'
RETLW D'67'
RETLW D'64'
RETLW D'61'
RETLW D'57'
RETLW D'54'
RETLW D'52'
RETLW D'49'
RETLW D'46'
RETLW D'43'
RETLW D'41'
RETLW D'38'
RETLW D'36'
RETLW D'33'
RETLW D'31'
RETLW D'29'
RETLW D'27'
RETLW D'25'
RETLW D'23'
RETLW D'21'
RETLW D'19'
RETLW D'18'
RETLW D'16'
RETLW D'15'
RETLW D'14'
RETLW D'13'
RETLW D'12'
RETLW D'11'
RETLW D'10'
RETLW D'9'
RETLW D'9'
RETLW D'9'
RETLW D'8'
RETLW D'8'
RETLW D'8'
RETLW D'8'
RETLW D'8'
RETLW D'8'
RETLW D'9'
RETLW D'9'
RETLW D'10'
RETLW D'11'
RETLW D'12'
RETLW D'13'
RETLW D'14'
RETLW D'15'
RETLW D'16'
RETLW D'18'
RETLW D'19'
RETLW D'21'
RETLW D'23'
RETLW D'25'
RETLW D'27'
RETLW D'29'
RETLW D'31'
RETLW D'33'
RETLW D'36'
RETLW D'38'
RETLW D'41'
RETLW D'43'
RETLW D'46'
RETLW D'49'
RETLW D'52'
RETLW D'54'
RETLW D'57'
RETLW D'61'
RETLW D'64'
RETLW D'67'
RETLW D'70'
RETLW D'74'
RETLW D'77'
RETLW D'80'
RETLW D'84'
RETLW D'87'
RETLW D'81'
RETLW D'95'
RETLW D'98'
RETLW D'102'
RETLW D'106'
RETLW D'109'
RETLW D'113'
RETLW D'117'
RETLW D'120'
RETLW D'124'
RETURN
INIT
BSF STATUS,RP0 ; GA NAAR BANK 1
MOVLW B'11111111'
MOVWF TRISA
MOVLW B'00000000'
MOVWF TRISB
MOVWF TRISC ;POORT B EN C UITGANGEN
; ZET DE INTERUPT AAN TIMER 0
BSF INTCON,GIE ; ZET GLOBAL INTERUPT AAN
BSF INTCON,T0IE ; ZET DE INTERUPT VAN TIMER 0 AAN (BIJ EEN LEGE INTERUPT SET DE BIT)
;TIMER 0
MOVLW B'11011110'
MOVWF OPTION_REG
;PWM
MOVLW 0x3F ; SET DE PWM
MOVWF PR2
BCF STATUS,RP0 ; TERUG NAAR BANK0
;TIMER 0 VALUE
MOVLW D'50'
MOVWF TMR0 ; ZET DIT IN TIMER 0
;PWM
BSF CCP1CON,4
BSF CCP1CON,5
BSF T2CON,TMR2ON
BCF T2CON,1
BCF T2CON,0 ; ZET DE PRESCALER
CLRF TELLER
MOVLW D'200'
MOVWF VASTEWAARDE
MOVLW D'50'
MOVWF TIJD
GOTO MAIN
MAIN
BSF PORTB,1
CALL DELAY
BCF PORTB,2
GOTO MAIN
EX_INT
MOVF P_SAVE,W ;restore context
MOVWF PCLATH
MOVF S_SAVE,W
MOVWF STATUS
SWAPF W_SAVE,F ;
SWAPF W_SAVE,W ;
RETFIE ; BEEINDIG INTERUPT
DELAY
DECFSZ TIJD,F
GOTO DELAY
RETURN
END
picsels
Volgend project: 7-seg gaming displays; dan dec-1982 labvoeding afmaken, dan funcgen met ad9833 afmaken, dan...
Je hebt staan:
ADDWF PCI,F
Dat moet waarschijlijk:
ADDWF PCL,F
zijn (geen ie maar een el).
<edit>
En je hebt in de OPTION_REG de prescaler aan de WDT toegekend (bit 3 zou een 0 kunnen zijn, tenzij je dit bewust zo hebt gedaan.)
Hoe check je dat je geen interrupt krijgt?
nonkel_dw
nonkel dw
Bedankt
Maar het werkt nog niet en ook geen PWM
Dus er zitten nog fouten in
.
Ik ben volop alles nog eens aan het nakijken.
Maar voorlopig vin ik niets.
gradtje
Ja... en toen ?
Set ook even ergens PIE of PEIE hoe die ook mag heten, je periphial interrupt enable.
Hou er ook rekening mee dat de timer steeds opniew moet worden geladen anders gaan de interrupts na de eerste optreden nadat tmr0 256 heeft geteld ipv het aantal dat je hebt opgegeven.
Ik heb niet je hele programma geanalyseerd maar volgens mij wil je te timer laden met 255-50 ipv 50.
TMR2 heeft een auto-preload functie, dat is waarschijnlijk veel handiger. Je preload wordt daar automatisch na een overflow geladen, hoef je er niet meer naar om te kijken dan.
nonkel_dw
nonkel dw
Dat kan wel best zijn.
Maar die timer2 heb ik nodig voor de hardawre matige PWM
tot stand te brengen
De global interupt is enable.
Bedoel jij het PEIE bitje ?
en timer0 word terug gereset.
BCF INTCON,T0IF ;RESETTEN VAN INTERUPT TIMMER 0
Ik heb geen 16f870, daarom getest op een 16F876A (20 mhz).
Hierbij een werkende timer 0:
(deze moet nog gewijzigd worden zodat je de juiste tijd krijgt)
// Clock . . . . = 20.000.000 Hz
// CLK/4 . . . . = 5.000.000 Hz
// Prescaler 1:16 = 312.500 Hz
// TMR0 value 255 = 1.222 Hz
TMR0 = 0;
OPTION_REG = 0B10000011;
INTCON.F5 = 1;
INTCON.PEIE = 1;
INTCON.GIE = 1;
interrupt:
if (INTCON.F2)
{
Counter = Counter + 1;
if (Counter == 1000)
{
Counter = 0; //Counter waarde op 0 zetten
PORTC.F2 = ~PORTC.F2; //LED knipperd
}
INTCON.F2 = 0; //Clr Timer0 interrupt
}
}
Ik prog in C, maar dat maakt voor de werking niets uit.
nonkel_dw
nonkel dw
Sorry maar ik snap er niets van.
Idd voor de werking maakt het niets uit.
Ik ben nu wel ten einde raad.
Ook in de main heb ik nu ingebouwd dat de poort hoog komt dan een delay en terug laag.
Maar de poort blijft constand hoog:(
Dus hij komt wel in de interupt denk ik.
Maar hij komt er niet meer terug uit.
Zo als ik al zij de PWM doet het ook niet.
Deze lijn blijft laag.
Die timer 0 blijft me ook nog altijd onduidelijk hoe ik deze elke 50µs kan laten interupten en hoe ik deze waarde kan veranderen
[Bericht gewijzigd door nonkel_dw op (14%)]
Waarschijnlijk kan je het beste eerst met een klein nieuwe programma beginnen en daarin Timer 0 aan de gang zien te krijgen.
Daarna deel voor deel er bij proggen...
Edit:
Timer0 wordt telkens verhoogd, zodra deze overloopt kan de interrupt routine opgeroepen worden.
De teller telt gewoon verder...
Nu kan je deze teller waarde wijzigen in een hoger getal.
Stel je maakt de waarde nu 200, dan is de volgende overloopt er een heel stuk sneller...
interrupt:
if (INTCON.F2)
{
TMR0 = TMR0 + 200; //Teller waarde aanpassen
Counter = Counter + 1;
if (Counter == 1000)
{
Counter = 0; //Counter waarde op 0 zetten
PORTC.F2 = ~PORTC.F2; //LED knipperd
}
INTCON.F2 = 0; //Clr Timer0 interrupt
}
}
nonkel_dw
nonkel dw
Even kort samen vatten of ik alles snap.
Timer0 zet ik een waarde in bv 50.
dan blijft hij tellen tot daar 255 in komt en geeft een interupt.
Als ik er waarde 200 in plaats. Dan moet hij maar 55 keer 1 ophogen en geeft hij een interupt.
Heb ik hem zo beet?
En in het register TMR0 zet ik de 8 bit waarde.
Inderdaad.
Zodra de Timer overloopt van 255 -> 0 dan treed er een interrupt op (als je dat ingesteld hebt).
En in het register TMR0 zet ik de 8 bit waarde.
De TMR0 waarde moet wel elke keer verhoogd worden als deze interrupt optreed !
nonkel_dw
nonkel dw
ik ben je code even aan het ontcijferen voor asm 
INTCON.F5 = 1;
Dit vind ik niet in het intcon register.
Of wild dit bit 5 zeggen ?
Zoals je nu alles heb ingestelt doet hij een interupt.
Of vergis ik me?
.F5 is Bit 5 (in mikroC)
Inderdaad de interrupt is vrijgegeven voor Timer 0.
Dus telkens als er een overload van Timer 0 (255->0) optreed, wordt de interrupt routine gestart.