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

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)

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 ?

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.

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.

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

Dit is toch niet de gehele code ?

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....

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%)]

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

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?

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.

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.

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

Het doet niets.
Ik heb net getest maar niets.

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.

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
  }
}

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 !

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.

oke

ik heb net alles ontcijferd.
en ga is snel testen