CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Step Counting using pwm.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 26, 2010 10:23 pm     Reply with quote

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








PostPosted: Wed Jan 27, 2010 8:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 8:33 am     Reply with quote

The post above was mine, i forgot to login
Sorry.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 12:31 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 2:20 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 2:44 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 3:27 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 3:36 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 3:48 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 27, 2010 10:51 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 28, 2010 2:29 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 28, 2010 4:44 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 28, 2010 7:20 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jan 28, 2010 8:15 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group