View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 26, 2010 10:23 pm |
|
|
Here's an example that puts out the specified number of pulses on
the CCP1 pin. I don't know if this is the best way to do this (putting
out a specific number of pulses), but it was fun to do. Note that I've
corrected my post above. The interrupt flag that must be checked is
the Timer2 interrupt.
To end the sequence of pulses, you must set the PWM duty cycle to 0.
If you just call setup_ccp1() with CCP_OFF, you will get a short pulse
for the last pulse. But if you set the duty cycle to 0 when the desired
number of pulses has occurred, the last pulse will be the correct duration.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define NUM_PULSES 10
//======================================
void main()
{
int16 count;
// Setup CCP1 for PWM at 244 Hz and 50% duty cycle.
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 255, 1);
set_pwm1_duty(128);
count = 0;
// Do the specified number of pulses on CCP1 and then stop.
while(1)
{
if(interrupt_active(INT_TIMER2))
{
clear_interrupt(INT_TIMER2);
count++;
if(count == NUM_PULSES)
{
set_pwm1_duty(0); // Set PWM output = constant 0
break;
}
}
}
while(1);
}
|
|
|
|
Guest
|
|
Posted: Wed Jan 27, 2010 8:32 am |
|
|
Now i understood !!!
Thank You PCM Programmer !!
I'll put a "printf" function in this code .
When i put the printf to count steps or turns, the motor got VERY slow, thats because i was writing the "printf" function in the middle of the steps of my motor. Now it shouldn't happen because i won't stop the pulse on pwm pin to write on lcd, right???
Best Wishes. |
|
|
bruno.gf
Joined: 26 Jan 2010 Posts: 9
|
|
Posted: Wed Jan 27, 2010 8:33 am |
|
|
The post above was mine, i forgot to login
Sorry. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 27, 2010 12:31 pm |
|
|
The polling method requires a tight loop. You can't put delays in the
loop that are longer than the PWM period. If you want to have the
PIC do something else (other than sit in a polling loop), then you need
to use #int_Timer2 interrupts and have it do this part of the code
inside the isr:
Code: |
count++;
if(count == NUM_PULSES)
{
set_pwm1_duty(0); // Set PWM output = constant 0
}
|
|
|
|
bruno.gf
Joined: 26 Jan 2010 Posts: 9
|
|
Posted: Wed Jan 27, 2010 2:20 pm |
|
|
Ok PCM Programmer, so based on what you said, I made my program, do you see anything that can probably goes wrong??
Code: |
#include <16F628A.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#include <tutorial.c> // Includes my lcd library
#use rs232(baud=9600, xmit=PIN_A6, rcv=PIN_A7, ERRORS)
//======================================
void main()
{
int16 count;
// Setup CCP1 for PWM at 244 Hz and 50% duty cycle.
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 255, 1);
set_pwm1_duty(128);
portb = 0; //reset
set_tris_b(0b11111111); // direction of pins I/O
inicializa_lcd(); // Inicializes the LCD
count = 0;
// Writes on lcd the steps
while(TRUE)
{
if(interrupt_active(INT_TIMER2))
{
clear_interrupt(INT_TIMER2);
count++;
printf(escreve_lcd,("Steps: %Lu", count)); // Writes to LCD the number of steps
}
}
} |
I used part of your code and put some functions.
Thank you !!
Best wishes. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 27, 2010 2:44 pm |
|
|
I don't know what you are trying to do, since you never stop the PWM
after a specified number of pulses. You just let it keep running forever.
Quote: | set_tris_b(0b11111111); |
Also, you are setting the TRIS for PortB to be all inputs. The 16F628A
data sheet specifically says that the CCP1 pin must have the TRIS set
for Pin B3 so it's an output pin. The CCS compiler automatically handles
doing this. Delete that line.
Also, you never reset the X,Y cursor location of the LCD, so it will
soon write characters off the end of the LCD. |
|
|
bruno.gf
Joined: 26 Jan 2010 Posts: 9
|
|
Posted: Wed Jan 27, 2010 3:27 pm |
|
|
I'm trying to count the steps, whitout stopping my motor. I just took of the part where you did "duty cycle = 0".
I have a question: Is there any possibility the function "printf" make slow my motor???
I'll take of that line as you said and i'll correct the lcd error.
Thank You
Best Wishes. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 27, 2010 3:36 pm |
|
|
Quote: |
Is there any possibility the function "printf" make slow my motor??? |
If you want to test if it slows down the motor, then comment it out.
See if the motor speed changes when you do that. In other words,
you control the program. Do some testing. Do some debugging. |
|
|
bruno.gf
Joined: 26 Jan 2010 Posts: 9
|
|
Posted: Wed Jan 27, 2010 3:48 pm |
|
|
Ok i'll send it to PIC, make the tests and post here the results.
Thanks for your help!!
Best Wishes |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Wed Jan 27, 2010 10:51 pm |
|
|
You know, you could run another timer, with a period set to 10 or 100 times the TMR2 repetition rate, and count tens or hundreds of motor steps, then if you get close to the stopping point, drop down to counting every TMR2 pulse. That way you wouldn't be constrained by the TMR2 interval all the time. Just a thought. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 28, 2010 2:29 am |
|
|
If that's what he wants to do, it can also be done by increasing the
postscaler on Timer2. The postscaler affects only the Timer2 interrupt.
At the maximum setting, you will get one interrupt for every 16 PWM
cycles. Currently it's set at 1 in the example program. |
|
|
bruno.gf
Joined: 26 Jan 2010 Posts: 9
|
|
Posted: Thu Jan 28, 2010 4:44 am |
|
|
Thank you John P. thats a good idea, i'll think(and study) more about it.
And PCM Programmer, setting the postscaler to 1 is what i need, since i want to count every pulse, right??
If i set it to 16 i'll only count pulses that are multiples of 16.
Thanks.
Best Wishes. |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Thu Jan 28, 2010 7:20 am |
|
|
Using the postscaler is much more elegant than tying up a second timer and making sure it's coordinated with TMR2. It sounds like a way better solution. Count in 16's until you get close to the goal, then switch over to counting single pulses.
But if this device is to drive a stepper motor, is there a need to slow down at the end of a move? That makes things more complicated. |
|
|
bruno.gf
Joined: 26 Jan 2010 Posts: 9
|
|
Posted: Thu Jan 28, 2010 8:15 am |
|
|
Hi John P.
Quote: | But if this device is to drive a stepper motor, is there a need to slow down at the end of a move? That makes things more complicated. |
Is the opposite, I don't want it to slow down.
I need the interruptions just to do the variable increase (in one unit), and then I want it to run normally.
I know the interrupt function has some delays; about 40 or 50 us ( as PCM Programmer said), but I don't need that precision.
Best Wishes. |
|
|
|