CCPR1L:CCP1CON<5:4> = ???

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Erik M
Inlägg: 1380
Blev medlem: 23 februari 2012, 18:34:39
Ort: Göteborg

CCPR1L:CCP1CON<5:4> = ???

Inlägg av Erik M »

Med denna (PIC12F683) snutt kod...

Kod: Markera allt

	movlw	0x20
	movwf	CCPR1L
Warm_Up
	incfsz	CCPR1L
	goto	Warm_Up
	movlw	0x20
	movwf	Power
	goto	Warm_Up
...borde jag få en PWM cycle som börjar på 25% och växer till 100%.
När den nått 100% börjar den om på 25% och växer igen.

Det där fungerar, och hjälper till se vad för inverkan andra faktorer har etc.

På en punkt fungerar det dock inte, oavsett vilket värdet är på PR2 etc.
När den nått 100% (0xFF) tar det ett bra tag innan den börjar om på 25% igen.
Den ligger liksom vilar på 100%, som om den fortsätter växa till något dolt läge som den tycker är max.
Det inträffar även om man använder en ren INCF CCPR1L, istället för den ställda.
Och oavsett en massa annat.

Övriga inställningar är:
_INTOSCIO & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON
Samt:

Kod: Markera allt

	bcf	STATUS,5	;	BANK	ZERO
; - - - - - - - - - - - - - - - - - - - - - -
	CLRF	GPIO	; Initiate GPIO.
; - - - - - - - - - - -
	BSF	INTCON,T0IE	; Timer0 intterupt enabled.
	BSF	INTCON,GPIE	; General port interupt enabled.
; - - - - - - - - - - -
	movlw	b'00000111'
	movwf	CMCON0	; Turn off comparator.
; - - - - - - - - - - - - - - - - - - - - - -
	movlw	b'11111100'	; 1:16 postscaler 
	movwf	T2CON	; Timer2 On <|> Prescaler is 1.
; - - - - - - - - - - -
	BCF		CCP1CON,5	; LSB are...
	BCF		CCP1CON,4	; ...both low.
	BSF		CCP1CON,3	; PWM mode is...
	BSF		CCP1CON,2	; ...active high
; - - - - - - - - - - -
	BSF	STATUS,5	;	BANK 	ONES
; - - - - - - - - - - - - - - - - - - - - - -
	MOVLW	0x7F		; <<<<< 1/60µs  -->>	 17kHz
	MOVWF	PR2
; - - - - - - - - - - -
	clrf	ANSEL		; No analog ports used.
; - - - - - - - - - - -
	bcf	OPTION_REG,7		; Enable pull-ups.
	bcf	OPTION_REG,5		; Internal instruction cycle (Fosc/4).
	bcf	OPTION_REG,3		; Prescaler assigned to Timer0.
	bcf	OPTION_REG,2		; Prescaler rate < 1:32.
	bcf	OPTION_REG,1		; Prescaler rate < 1:8. >> 4µs >> 1024µs/T0IF (~1ms)
	bcf	OPTION_REG,0		; Prescaler rate < 1:4 => 1:2 >> 1us >> 256us/T0IF <-------<---<-<<
; - - - - - - - - - - -
	BSF		OSCCON,4		; 8MHz - internal oscillator.
	BSF		OSCCON,0		; Internal oscillator as system clock.
; - - - - - - - - - - -
	movlw	b'00111001'		; Input GP<5 4 3 0>.
	movwf	TRISIO		; Output GP<2 1>.
; - - - - - - - - - - -
	MOVLW	b'00111001'		; Weak Pull-Up @ GP<5 4 (3) 0>.
	MOVWF	WPU
; - - - - - - - - - - -
	BSF		IOC,0		; GP<0> with IOC, interupt on change.
; - - - - - - - - - - -
	bcf		STATUS,5	;	BANK	ZERO
; - - - - - - - - - - -
Spontant känns det som CCPR1L inte behandlas som MSB, utan som en byte LSB.
Givetvis är det inte så, men händelseförloppet på oscilloskopet ser ut som om så.

Vad sysslar PWM-funktionen med?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46971
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av TomasL »

Tja, du har ju sannolikt högre upplösning än 8 bitar.
Vore bra om du redovisade hur du fick fram initieringsvärdena för PR2 och CCPR1L
Snabbt räknat får jag det till att din upplösning är 9 bitar, dvs CCPR1L är den lägre byten och PWM-funktionen fortsätter i den högre byten, dvs CCPR1H
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av bearing »

Om jag förstår rätt är perioden 0x80 (0x7F + 1), d.v.s 7 bitar.

Kod: Markera allt

   movlw   0x20
   movwf   CCPR1L
Warm_Up
   incfsz   CCPR1L
   goto   Warm_Up
   movlw   0x20
   movwf   Power
   goto   Warm_Up

CCPR1L kommer starta på 0x20(25%) första gången. När CCPR1L nått 0x80, är PWM 100%, men CCPR1L är ju 8 bitar och kommer fortsätta räkna till 0xFF, vilket är orsaken till "fördröjningen". Efter 0xFF börjar CCPR1L om från 0, d.v.s inte från 25% (som jag antar att du ville).

Sen är jag förvånad över att koden fungerar över huvud taget. Behöver inte loopen vänta på en ny PWM-period, innan CCPR1L ökas?
Kanske fungerar koden tack vare att CCPR1L är dubbelbuffrat, d.v.s CCPR1L kommer ökas tusentals gånger i loopen utan verkan, eftersom att registret inte ökas förrän det buffrade värdet skrivits.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46971
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av TomasL »

Perieoden är en sak, upplösningen är en annan, med de värdena som används i första posten är upplösningen minst 9 bitar.
Om upplösningen är större än 8 bitar kommer naturligtvis den höga byten att användas också.
Nej CCPR1L kommer inte att fortsätta räkna, då timern nollställs, dock eftersom upplösningen är 9 bitar, så kan det säkert orsaka saker om man inte är medveten om det.

Kod: Markera allt

MOVLW   0x7F      ; <<<<< 1/60µs  -->>    17kHz
   MOVWF   PR2
Detta får jag inte riktigt ihop dock. bör bli 15,6 kHz
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av bearing »

Jag har inte använt just denna modell, så jag får ta dig på orden.
På gamla PIC satt bitarna för "högre upplösning" i ett separat register.

Men i så fall stämmer hans egen beskrivning inte bra. Om upplösningen vore 9 bitar borde ju pulsbreddsförhållandet gå mellan 0 och 50%, utan fördröjning.
Erik M
Inlägg: 1380
Blev medlem: 23 februari 2012, 18:34:39
Ort: Göteborg

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av Erik M »

Power är definierad som CCPR1L, missade rensa ut GFR. Sorry.

CCPR1L är de åtta MSB för PWM.
(Till skillnad från komparatorn.)

De två LSB är med ibland, och ibland inte.
Åsså är det lite olika var de återfinns.

Men OK, ingen som vet alltså.
Koden fungerar och startar om på 0x20, som tänkt.
Frågan var vad PIC hittar på.

För övrigt förefaller antalet bitar ändras med frekvensen.
Hur har jag inte sett någon förklaring på.
... bara hur man räknar ut antalet bitar.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46971
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av TomasL »

Tja, eftersom du skriver till de höga byten, så blir det förmodligen så.
Du måste naturligtvis skriva till den låga byten i stället.
I praktiken skriver du 0x80 till CCPR1L
Erik M
Inlägg: 1380
Blev medlem: 23 februari 2012, 18:34:39
Ort: Göteborg

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av Erik M »

Snälla Tomas, om du vet vad du pratar om så blir jag och andra med mig glada.

Återigen - CCPR1L är MSB för PWM.
Och om jag skriver till CCPR1L så är det just till...
... nej, det går inte att svara på din skrift - eftersom den utgår från vad som inte är.

Om vi båda pratar om samma sak, då kan vi komma framåt.
Men då får du släppa hur det inte är först.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46971
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av TomasL »

Erik, läste du vad jag skrev ovan?
Vilket innebär att om du vill ha 0x20, måste du skriva 0x08 till CCPR1L.
Dessutom står det i databladet rätt tydligt hur du räknar ut periodtid, upplösning och pulskvoten
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av bearing »

Förstår inte vad ni yrar om.
Nu har jag kollat i databladet, och det är nu helt klart att jag hade rätt från början.

"The PWM duty cycle is specified by writing a 10-bit
value to multiple registers: CCPR1L register and
DC1B<1:0> bits of the CCP1CON register. The
CCPR1L contains the eight MSbs and the DC1B<1:0>
bits of the CCP1CON register contain the two LSbs."

Ute på en stor fiskebåt tillsammans i Göteborgs skärgård eller?


Eftersom att du inte använder DC1B<1:0> i runtime, får du se det som att du kör med 7-bit PWM.
Men oavsett om du önskar köra 9-bit eller 7-bit kommer CCPR1L bara innehålla 7 bitar. Pulsbreddsförhållandet är alltså 100% från CCPR1L = 0x80 till 0xFF, vilket är orsaken till "fördröjningen".
CCPR1L kommer inte "snurra runt" efter 0x7F bara för att skrivit den siffran till PR2.


Ingen kommentar till detta? :
bearing skrev: Sen är jag förvånad över att koden fungerar över huvud taget. Behöver inte loopen vänta på en ny PWM-period, innan CCPR1L ökas?
Kanske fungerar koden tack vare att CCPR1L är dubbelbuffrat, d.v.s CCPR1L kommer ökas tusentals gånger i loopen utan verkan, eftersom att registret inte ökas förrän det buffrade värdet skrivits.
Användarvisningsbild
SeniorLemuren
Inlägg: 8426
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av SeniorLemuren »

Ja men du bearing, om man nu tror att PIC bara hittar på
Frågan var vad PIC hittar på.
så är det väl inte så konstigt om det blir konstigt? Fast detta är väl ett typexempel på vad man skulle kunna använda debuggern till. Då ser man ju vad PIC "hittar på".
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av sodjan »

> För övrigt förefaller antalet bitar ändras med frekvensen.
> Hur har jag inte sett någon förklaring på.

Låt oss säga att själva PWM frekvensen är 1 KHz. Om man
vill ha 10 bitars upplösning så måste alltså klockfrekvensen vara
1.000 x 1.024 = 1.024 Mhz. Så långt är allt OK, men det går
att ha mycket högre PWM frekvens än så, om man vill.

Låt oss säga en PWM frekvens på 100 Khz. Om man fortfarande
vill ha 10 bitars upplösning, så måste klockfrekvensen då alltså vara
100.000 x 1024 = 102.4 Mhz och det klarar inte processorn.

Alltså minskar den användbara upplösningen i PWM modulen med
ökande PWM frekvens.

För 200 KHz PWM frekvens anges 5 bitar, alltså 200.000 x 32 =
6.4 Mhz, vilket är OK med tillräckligt hög oscillatorfrekvens.

PR2 = 0x7F och med prescaler = 1 så verkar väl rimligt att det ger
ca 17 KHz vid 8 MHz. Och du får då ca 8 bitars effektiv upplösning.

Nu så ligger ju de två lägsta bitarna i CCP1CON och jag kan inte se att du
ändrar dom senare (nollade), vilket betyder att du har *6* bitar effektivt
i PR2 att "spela med". D.v.s värderna 0x00 - 0x3F (fortfarande "ca.")

(Bitantalet är inte fasta heltal, det beror på den aktuella PWM frekvensen. I ditt
fall blir det nog någonstans mellan 8 och 9 bitar, formeln finns i databladet.)

Om du startar på 0x20 och räknar upp så kommer PWM duty att nå 100%
vid ca 0x3F (eller lite mer eftersom du har drygt 8 bitar), resten av vägen upp
till 0xFF (innan du börjar om på 0x20), så kommer PWM signalen att ligga "låst"
på 100%. D.v.s så som det står på sidan 79 i databladet:

Note: If the pulse width value is greater than the period the assigned
PWM pin(s) will remain unchanged.

> Ingen kommentar till detta? : [d.v.s sättet som CCPR1L uppdateras i en "tight" loop...]

Ja, det är inte helt snyggt. Normalt vill man inte ändra PWM period snabbare än
PWM perioden i sig självt. Det tyder på en miss i designen någonstans. Med 17 Khz
PWM frekvens och 8 MHz systemklocka så kommer loopen att uppdatera CCPR1L
massor av gånger innan ett nytt värde skrivs till CCPR1H och PWM perioden kommer
att hoppa lite okontrollerat. D.v.s då också att PWM perioden *i praktiken* inte kommer
att ha det antal bitars upplösning som man skulle kunna tro.

Loopen tar väl 2 us om jag räknar rätt. D.v.s att CCPR1L ändras varje 2 us.
CCPR1L läses dock bara av var 58 us, ungefär vid 17 KHz PWM frekvens.
D.v.s att enbart var 24'de värde skrivet till CCPR1L faktiskt används i praktiken.

Generellt kan man säga att det aldrig finns någon anledning att uppdatera
CCPR1L snabbare än vad värderna kopieras till CCPR1H, och det sker varje
gång som PR2 "slår runt", d.v.s samma som PWM frekvensen.

> Fast detta är väl ett typexempel på vad man skulle kunna använda debuggern till.

Absolut!
Jag är övertygad om att detta syns tydligt om man stegar programmet i MPSIM...
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av bearing »

>PR2 = 0x7F och med prescaler = 1
...
>Om du startar på 0x20 och räknar upp så kommer PWM duty att nå 100%
>vid ca 0x3F

Den sista siffran stämmer inte.
TMR2 "slår runt"/nollas när den passerar PR2 (0x7F). TMR2 utan prescaler går i 2MHz med 8Mhz oscillatorn. Dessutom utökas TMR2 med en intern räknare på 2 bitar som kör i 8Mhz. Vilket alltså totalt ger en räknare på 10 bitar som kör i 8 Mhz.

PWM-utgången sätts låg när TMR2 >= CCPR1L samt 2-bit-räknaren >= DC1B. Om CCPR1L är högre än PR2 kommer utgången (som du skriver) alltså aldrig sättas låg, vilket ger 100% duty.
Erik M
Inlägg: 1380
Blev medlem: 23 februari 2012, 18:34:39
Ort: Göteborg

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av Erik M »

På en punkt fungerar det dock inte, oavsett vilket värdet är på PR2 etc.
För övrigt förefaller antalet bitar ändras med frekvensen. Hur har jag inte sett någon förklaring på. ... bara hur man räknar ut antalet bitar.
Varken PR2 eller antalet bitar har med saken att göra.
Följdaktligen inte heller någon form av förskjutning av värdet som ges CCPR1L.
Vilket hur som haver inneburit att duty cycle rullat över, lite allmänt slumpmässigt.
Vad för prescaler inverkar inte heller.

Dvs resultatet blir samma oavsett vad dessa ställs till.

Det enda som ändrar är om PR2 ställs för låg - då händer ingenting.
Eller mer exakt, då händer bara.

Vad som möjligen kunde ske är någon form av fördröjning pga snabbare ökning av duty cycle än vad görs av med.
Lite gummiband i samspelet mellan TMR2 och PR2 alltså.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: CCPR1L:CCP1CON<5:4> = ???

Inlägg av sodjan »

> Den sista siffran stämmer inte.
> TMR2 "slår runt"/nollas när den passerar PR2 (0x7F).

Ah, OK. :-) Poängen (och det viktiga) är i alla fall att att man sätter
en "duty cycle" som är längre/större än cykeltiden för själva PWM
signalen/frekvensen. Effekten blir densamma som jag beskrev men
tiden för den fasta 100% PWM signalen blir kortare.

EricM, jag kan inte säga att jag direkt förstår ditt inlägg, det är
väldigt rörigt. Skit samma, det är möjligt att du har rätt... :-)
Skriv svar