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.

PMW ramp up on PIC16F887 - approach check

Status
Not open for further replies.

dsc

Member
I'm using a PIC16F887 to drive a stepper motor via a dedicated driver. The driver accepts pulse signals and I'm using the hardware PWM on the PIC to deliver this. I'm looking for high start torque, which forced me to implement a ramp up on the stepper motor speed, as steppers offer more torque at low speeds. Motor / driver is set to quarter step operation, which means it needs 800 pulses per rotation, ie. 800Hz PWM signal for 60RPM. I'm planning to ramp up to 240RPM, which would be 3200Hz. I've calculated that using the T2 prescaler I can achieve these frequencies by changing the PR2 register from 77 to 18. Based on this I've put together a short function, using delays:

void slow_ramp(void)
{
//PWM code for slow ramp start
CCPR1L = 0b00000010; //set to 2, so pulse width is 2 x 16 = 32 with 16 prescaler

while (PR2 != 18) //ramp up speed slowly from 60RPM [PR2 = 77] to 240RPM [PR2 = 18]
{
while (TMR2IF == 0) {} //wait for overflow
PR2--;
__delay_ms(5);
}
}

This works, but I'm not sure whether I need to use the "while (TMR2IF == 0) {}" statement, or can I simply change the PR2 whenever?

I was tempted to use interrupts based on the TMR2IF flag, but I already use INTs as a precise 100ms timer, so I'd rather not complicate that.

Regards,
dsc.
 
I believe you can change PR2 whenever you want. It is probably (hopefully) double-buffered register, so the change takes effect when the timer overflows.. or something like that. The datasheet should explains the details.
 
I'm fairly sure thats right too, the pwm module is glitch free when you write to pr2.
 
Thanks for the replies gents, for some reason I didn't get a notification to my email address.

As it turns out, it's not glitch free, have a look at these trends showing a missing pulse on the PWM output:

PWM_analyse.png

This is when the PR2 is modified. Not sure exactly why that is, but I'm guessing it's down to when the update happens and where the TMR2 is in counting up (it's a spurious thing). I've now modified it to do the following:

if(PR2 > 18)
{
TMR2IF = 0;
while (TMR2IF == 0) {}
PR2 = PR2 - 6;
}

and that seems to do the trick. The only issue is waiting for the PWM cycle to finish, which can add even around 1000us to the overall loop length. I have this running in an INT routine which is triggered every 100ms and I'm not so crazy about having to do the while (TMR2IF == 0) {} in the interrupt. Then again I guess 1ms is not a massive amount of time and the PIC is not really busy with anything else at that point (PWM ramp only takes 1sec total).

Regards,
dsc.

EDIT: having thought about this it makes sense to miss a pulse if the following happens:

- you want to change PR2 from 77 to 70
- TMR2 is counting up, goes past 70, say into 71
- you modify the PR2 to be 70
- TMR2 cannot match the new PR2 in this PWM cycle, so it will count up to 255, overflow, starting counting up again from 0 and then match PR2
- the above will effectively make it miss a pulse

The strange thing is that I've seen this even when modifying PR2 by 1 and I'd say that chances of changing the PR2 exactly when it passes through the new PR2-1 value are rather slim to impossible.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top