Frekvens för PIC med intern oscillator?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Frekvens för PIC med intern oscillator?

Inlägg av PHermansson »

Har kopplat upp en PIC12F675 utan kristall, kör enbart med den interna 4MHz oscillatorn. En kod jag skrivit använder Timer1 för att skapa en interrupt 2 ggr per sekund och blinka en led, och i simulatorn tar det 499997 uS mellan interrupten. När jag sedan kör koden i den riktiga kretsen är frekvensen relativt långt ifrån 1Hz, när jag jämför ledblinkandet med väggklockans tick verkar det som dioden blinkar kanske 11-12 ggr per 10 sekunder.
Programmeraren tar hänsyn till Oscal.
Visst ska man använda kristall till tidskritiska applikationer, men ska diffen i frekvens verkligen vara så här stor?
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Avvikelsen som kan finnas står i databladet.

Vad jag vet är PIC16F628A, den har ±1% på den inbyggda 4MHz'en.
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Detta under förutsättning att det fabrikskalibrarade värdet finns kvar intakt i picen.

Prova att läsa ut det och se om det är 00 eller FF. Då kan man ju misstänka att värdet har blivit överskrivet nån gång.

Annars så du väl kallibrera den själv. Det finns en appnot som beskriver en enkel autokallibrerare.
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

Tack för snabba svar! Jag har nu läst appnoten (http://ww1.microchip.com/downloads/en/d ... 31002a.pdf) och testat tipsen där. Har dock inte haft möjlighet att kolla frekvensen.
Jag har läst ut Osccal från Pic'en, värdet blir 84 så jag tror det är korrekt. Jag testade då att sätta Osccal till 0 och CALSLW till 1 vilket ska ge lägsta möjliga frekvens. Men det går fortfarande för fort?! Får nog försöka kolla oscillatorfrekvensen...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

11-12 gånger på 10 sek, är ju 10-20 % för mycket, vilket ser konstigt ut.
Svårt att säga, kanske programbug eller felinställning i MPSIM !?
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

MPSim säger 500.004000 mS och PIC Simulator IDE säger 499997 uS. Själv säger jag att 10 blinkningar tar ca 9s. The search goes on...

Hmm... jag har 'preloadat' Timer1 med Tmr1L=E0 och Tmr1H=0B vilket ger ovanstående värden. Dessa värdet har jag tagit fram med trial'n'error, vilket här verkar bli error. I detta fall räknar Tmr1L 31 steg och Tmr1H 244 steg, vilket med en prescaler på 8 ger 60512 steg.
500000uS / 8 ger 62500. Om jag då preloadar Tmr1H med 03 istället bör tiden bli mer korrekt. Men det går fortfarande för fort!
Tror jag har någon form av hjärnsläpp nu, får nog göra något annat en stund...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Posta ett "test-case" som uppvisar problemet, så får vi se...
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

test-case??
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Ja, en kod-snutt som visar problemet, och som (t.ex) jag kan testa med...
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

aha ok då är jag med :)

Kod: Markera allt

	list p=12f675
	include "p12f675.inc"

 __config B'110010100'

START_USER_MEMORY  EQU 0x20 
w_temp             EQU START_USER_MEMORY    ; for isr context saving
status_temp        EQU START_USER_MEMORY+1  ; for isr context saving

ledstate		equ	0x22

;----------------

    org    0x00
	goto main

; Interrupt handling
    org    0x04

push     movwf w_temp            ;save w & status
            swapf STATUS,W
            movwf status_temp
isr        
           bcf PIR1, TMR1IF ; Clear the flag bit after the interrupt
           ;Toggle led
           movlw	0x10
	   xorwf	ledstate,1
	   movf	ledstate,0
           movwf	GPIO
			
timerload
	   ;Preload timer.
	   movlw 	0xE0
	   movwf	TMR1L
	   ;Preload timer
           movlw 	0x03
           movwf	TMR1H

pop       swapf status_temp,W        ; restore w & status
            movwf STATUS
            swapf w_temp, F
            swapf w_temp, W
            retfie
main:

	clrf GPIO 
	movlw 0x7 
	movwf CMCON ; disable comparator 
	bsf STATUS, RP0 ;Bank1 
	movlw 0x0 
	movwf TRISIO ; All pins outputs 
	bcf STATUS, RP0 ;Bank0

	;Adjust IntOsc
	movlw	b'00000100' 
	movwf	OSCCAL

	;Setup Timer1
	BCF	T1CON, TMR1GE
	BSF	T1CON, T1CKPS1	;Prescaler
	BSF	T1CON, T1CKPS0
	BCF	T1CON, T1OSCEN	;LpOsc
	BCF	T1CON, NOT_T1SYNC
	BCF	T1CON, TMR1CS	;ClockSource

	bcf PIR1, TMR1IF ; Clear the flag bit 

	bsf STATUS,RP0 ;Bank 1
	bsf PIE1, TMR1IE ; Enable Tmr1 interrupt
	BCF STATUS, RP0 ; Bank0
    
	bsf INTCON, PEIE ; 
        bsf INTCON, GIE  ; Enable all interrupts

	;Preload timer
	movlw 	0xE0
	movwf	TMR1L
	;Preload timer
	movlw	0x03
	movwf	TMR1H

	BSF	T1CON, TMR1ON	;Start timer

infinite:
	goto infinite
	
	end
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Nedanstående ger (nästan) 1 Hz i MPSIM och 1.011 Hz på oscilloskopet.
Inga större ändringar.
- Plockade bort "push/pop" eftersom det ändå inte finns något att spara.
- Ändrade till ext-MCLR för att kunna köra med Wisp628. (Använd gärna de riktiga CONFIG symbolerna från INC filern !)
- Nya värden för tmr1-preload (tmr1H_pl och tmr1L_pl).
- La dit korrekt hantering av OSCCAL.

Kod: Markera allt

   list p=12f675
   include "p12f675.inc"

 __config h'01B4'

ledstate      equ   0x22

tmr1H_pl = h'0B'
tmr1L_pl = h'DE'

;----------------

   org    0x00
   goto main

; Interrupt handling
    org    0x04

isr       
   ;Toggle led
   movlw   0x10
   xorwf   ledstate,1
   movf    ledstate,0
   movwf   GPIO
         
timerload
   ;Preload timer.
   movlw   tmr1L_pl
   movwf   TMR1L
   movlw   tmr1H_pl
   movwf   TMR1H

   bcf PIR1, TMR1IF
   retfie

main:

   clrf GPIO
   movlw 0x7
   movwf CMCON ; disable comparator
   bsf STATUS, RP0 ;Bank1
   movlw 0x0
   movwf TRISIO ; All pins outputs
   bcf STATUS, RP0 ;Bank0

   ;Adjust IntOsc
   bsf STATUS, RP0 ;Bank 1
   call 3FFh ;Get the cal value
   movwf OSCCAL ;Calibrate
   bcf STATUS, RP0 ;Bank 0


   ;Setup Timer1
   BCF   T1CON, TMR1GE
   BSF   T1CON, T1CKPS1   ;Prescaler
   BSF   T1CON, T1CKPS0
   BCF   T1CON, T1OSCEN   ;LpOsc
   BCF   T1CON, NOT_T1SYNC
   BCF   T1CON, TMR1CS   ;ClockSource

   bcf PIR1, TMR1IF ; Clear the flag bit

   bsf STATUS,RP0 ;Bank 1
   bsf PIE1, TMR1IE ; Enable Tmr1 interrupt
   BCF STATUS, RP0 ; Bank0
   
   bsf INTCON, PEIE ;
   bsf INTCON, GIE  ; Enable all interrupts

   ;Preload timer
   movlw   tmr1L_pl
   movwf   TMR1L
   movlw   tmr1H_pl
   movwf   TMR1H

   BSF   T1CON, TMR1ON   ;Start timer

infinite:
   goto infinite
   
   end 
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

Tackar! Jag testade din kod och det ser ut att fungera bättre :)
Jag lade till en räknare för att kunna räkna en minut, och har upprepade gånger mätt perioden till 59,4 sekunder. 1,011Hz ger en tid på 0,989s, och tar man detta gånger 60 blir det 59,35. Trots att jag inte har något oscilloskop tillgängligt kan jag konstatera att din kod fungerar. Varför är ju en annan fråga...
Tack för hjälpen!
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Fint.
Måste sticka ut på stan en sväng, men ska titta en extra gång på din kod senare så får vi se om jag ser något...

EDIT: När jag läser om ditt senaste inlägg, så ser jag att du kanske
menade varför *min* kod fungerar !? Ja ja, *det* behöver jag inte kolla
närmare på... :-)
Skriv svar