Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Need help understanding PWM on PIC16F684

Status
Not open for further replies.

GammaRay86

New Member
Hi guys,

I'm trying to understand some code that uses a variable as the values for the PWM duty cycle registers. The CCPR1L register contains the 8 MSbs and bits 5:4 of CCP1CON contain the 2 LSbs of the 10-bit value. Now the code pretty much says the maximum value is 1000 which is 1111101000 in binary. How do I put the number 1000 in these two registers? is it simply 11111010 in CCPR1L and 00 in CCP1CON<5:4>?

Take a look at this section of code:

Code:
if(Cn >= 1000)								// Used to limit duty cycle not to have punch through
	{
		Cn = 1000;
	}
    if(Cn <= -1000)
	{
		Cn = -1000;
	}  
	if(Cn == 0){				// Set the speed of the PWM
		DC1B1 = DC1B1 = 0;
		CCPR1L = 0;
	}
	if(Cn > 0){					// Motor should go forward and set the duty cycle to Cn
		P1M1 = 0;				// Motor is going forward
		temp = Cn;
		if(temp^0b00000001){
			DC1B0 = 1;
		}
		else{
			DC1B0 = 0;
		}
		if(temp^0b00000010){
			DC1B1 = 1;
		}
		else{
			DC1B1 = 0;
		}	
		CCPR1L = Cn >> 2;

What exactly is going on here? It looks like at the end the value is shifted by 2 so it is only an 8-bit value. The equation to get the pulse width is:

Pulse Width = (CCPR1L:CCP1CON<5:4>) / (4*(PR2+1))

According to the rest of the code, the maximum value of the numerator can be is 256. But this is 8-bits. Shouldn't the maximum be 1024 since it's 10-bits?

Also, it can be a negative number so 1 bit must be for the sign. Isn't it then effectively a 9-bit number?

I'd appreciate it so much if anyone could straighten this out for me. Thanks :)
 
Last edited:
...
How do I put the number 1000 in these two registers? is it simply 11111010 in CCPR1L and 00 in CCP1CON<5:4>?
...

Yep that's basically it.
Code:
So if you wanted to load (binary) 1111101000 it is;

MSB          LSB
             54
11111010     00

Hope that helps. :) That code you posted looks like a poor code example to learn from.
 
Last edited:
Hey, thanks for confirming.

But still one thing. Say I need to put a number "Cn" inside the PWM registers. How do I do this when I don't know what Cn actually is? Like how do I code it that is? Thanks :)
 
The value of Cn can go from -1000 to +1000 in that code and that is 11 bits. You didn't include the part of the code that handles negative values so it is hard to tell what is happening.

To put a 10 bit value into the ccpr registers you would do,
Code:
	CCPR1L = Cn >> 2;		//top 8 bits to ccpr1l
	CCP1CON &= 0b11001111;		//zero bits 4 and 5
	CCP1CON |= (Cn & 3) << 4;	//bits 1 and 0 to bits 4 and 5

Mike.
 
Last edited:
...
Code:
	CCPR1L = Cn >> 2;		//top 8 bits to ccpr1l
	CCP1CON &= 0b00110000;		//zero bits 4 and 5
	CCP1CON |= (Cn & 3) << 4;	//bits 1 and 0 to bits 4 and 5

Pommie, shouldn't that be;

Code:
	CCP1CON &= 0b11001111;		//zero bits 4 and 5
 
Yes, that'll teach me to type of the top of my head. Well spotted, I'll edit it.

Mike.
 
Thanks for the help guys. I understand now.

One last thing. Is direct access to the bits in a variable possible? For example my compiler (CC5X) lets me do this:

CCP1CON.4 = Cn.0;
CCP1CON.5 = Cn.1;

Is this actually possible/working? Seems too good to be true.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top