Author Topic: PWM Frequency DC Motor Speed Control  (Read 4517 times)

0 Members and 1 Guest are viewing this topic.

Offline twinsratioTopic starter

  • Jr. Member
  • **
  • Posts: 16
  • Helpful? 0
PWM Frequency DC Motor Speed Control
« on: March 16, 2011, 09:37:15 AM »
Hi there,

Is that possible to generate 50Hz PWM frequency with using 20MHz external crystal ?
From what I heard, with 20Mhz crystal frequency it couldn't create such low PWM frequency, it that correct ?

Is the any other method to create PWM 50Hz by using 20MHz external crystal?

Thank you,

Offline Fr0stAngel

  • Full Member
  • ***
  • Posts: 84
  • Helpful? 3
  • [O_O] what??
Re: PWM Frequency DC Motor Speed Control
« Reply #1 on: March 16, 2011, 10:18:00 AM »
well you cant directly use the crystal to create a 50 hz PWM, but use timers, or use time delay loops to generate the PWM on a output port pin

a simple pseudo-code could be

start timer
wait 1/100 seconds
toggle pin state;
wait 1/100 seconds
toggle pin state;

etc
'crazy' is the new hype! =)

Offline twinsratioTopic starter

  • Jr. Member
  • **
  • Posts: 16
  • Helpful? 0
Re: PWM Frequency DC Motor Speed Control
« Reply #2 on: March 16, 2011, 10:53:40 AM »
Thank you for reply, below is mu current coding basically I'm using timer0 to interrupt 1 second for the counter to get the pulse/sec from my motor. As now, my task is to create a PWM frequency at 50Hz to control the speed of the motor for 25%,50% n 75% duty cycle.
How can I edit my code to achieve 50Hz PWM frequency as you suggested?

#include <htc.h>

#include <stdlib.h>
#include <string.h>

__CONFIG( HS & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS & DEBUGDIS & BORV21);

#define RS RE0
#define RW RE1
#define EN RE2
unsigned int reload=76;
unsigned int rpm;
                      //High speed Osc (> 4mhz)   

unsigned long  s, k, w, a, b, c, y;


//LCD instruction function   
   void instruction(char C)     
   {

      PORTE = 0x04; //RS =1 , W/R = 0 , E = 0
      PORTD = C;
      PORTE = 0x00;
      for (s=0;s<30;s++){}
   }


// LCD display function
   void lcd (char C)           
   {

      PORTE = 0x05;   //RS =1 , W/R = 0 , E = 1
      PORTD = C;
      PORTE = 0x01;   //RS =0 , W/R = 0 , E = 1

      PORTE = 0x01;   //RS =0 , W/R = 0 , E = 1
      PORTD = C;
      PORTE = 0x04;   //RS =1 , W/R = 0 , E = 0
   
       for (s=0;s<5;s++){}
   }


/* write a string of chars to the LCD */
// LCD lcdout function for character input   
   void lcdout (const char *C)
   {
   PORTE = 0x04;
   while (*C)
      {
      lcd(*C++);
            }
   }

void out ()
{
   
      unsigned long counter = b;
      char output[12];
      ltoa(output, counter, 10);
      instruction(0x80);
      lcdout("Pulse/sec:");
      lcdout(output);      //output
      instruction (0xC0);
      lcdout("RPM:");
     lcdout(output);
      }
void out2 ()
{   
      instruction(0x80);
    lcdout("Pulse/sec:0      ");
    instruction (0xC0);
    lcdout("RPM:0            ");
}





// Main Function



void main(void)
{
OSCCON= 0b01101110;


TRISA = 0xFF;         //set PORTA as Input
TRISD = 0x00;         //Set PORTD as Output (Data)
TRISE = 0x00;         //Set PORTE as Output (EN, R/W, RS)
TRISC = 0x00;         //Set PORT C as Output
ANSEL = 0x00;
ANSELH = 0x00;
ADCON0 =0x00;          //’disable ADC
CM1CON0 =0x00;          //’disable COMPARATOR 1
CM2CON0 =0x00;          //’disable COMPARATOR 2
T1CON =0x00;          //’disable TIMER1
OPTION = 0x07;
T0IE = 1;             // Enable Timer
GIE = 1;             // Enable Global Interrupt
y=0;               //Initial counter value=0

 

//rpm=((y*60)/(3*20)); //formula for rpm




//LCD Function
instruction(0x0C);     //Display on/off & cursor HEX 08-0F (1st)
instruction(0x38);     //Function Set HEX 20-3F
instruction(0x01);     //Clear Display HEX 01 (last)


while(1)   
   {
   if(w==0)
{   out2();
      }

         


switch (T0IE==1)
{
   case 1:
   if((RA0==0)&&(RA1==0)){
   for(s=0;s<35;s++){}   ////////pulse..
   y++;
   out();
   w=1;
   break;
         }
            
}      




      

         
 
     
}
     

static void interrupt
isr(void)
{
   
   if(reload==0){
   b=y;
   rpm=y;

   T0IE = 0;             // disable Timer
   y=0;
   w=0;
   instruction(0x01);
   T0IE = 1;             // disable Timer   
   reload = 76;
   }
reload--;
T0IF = 0; // Clear Timer Interrupt Flag
}

Thank you

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,919
  • Helpful? 97
Re: PWM Frequency DC Motor Speed Control
« Reply #3 on: March 16, 2011, 11:22:41 AM »
From the htc.h I see you are using a PIC. Which one?

To work out the timing use the MPLAB simulator and a break point.
TMR0 and pre-scaler can time a 20msec period (1/50Hz) so adjust the TMR0 value and pre-scaler to obtain to period your require.
I would use an ISR for the TMR0 interrupt an in the ISR start a second timer, TMR1 or TMR2, to time the output pulse length. In the TMRx ISR the timer is stopped and the output toggled off. When TMR0 interrupts again re-load TMRx with the new value needed for the new duty cycle and repeat.

The advantage of using interrupts for timing the period and duty cycle is that the PIC can do other tasks like updating the LCD without disturbing the PWM timing.

Offline twinsratioTopic starter

  • Jr. Member
  • **
  • Posts: 16
  • Helpful? 0
Re: PWM Frequency DC Motor Speed Control
« Reply #4 on: March 16, 2011, 06:49:10 PM »
Hi Waltr,

Actually I'm using htc.c header.

Thank you for reply, do you have any sample or example so I can take as reference?



Thank you.

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,919
  • Helpful? 97
Re: PWM Frequency DC Motor Speed Control
« Reply #5 on: March 16, 2011, 08:41:54 PM »
I have code for a PIC that uses two hardware timers to output to 6 RC hobby servos but it is written is assembler for a PIC16F87 and has a lot of other code for UART and I2C slave communications. If you think it will be useful let me know and I'll post it here.

The concept and code can be found here:
http://www.best-microcontroller-projects.com/servo-controller.html

There are other sources if you do some searching.

Offline twinsratioTopic starter

  • Jr. Member
  • **
  • Posts: 16
  • Helpful? 0
Re: PWM Frequency DC Motor Speed Control
« Reply #6 on: March 17, 2011, 07:34:15 AM »
Hi waltr,

You suggested to use TIMER0 to time a 20ms interrupt, however I'm using TIMER0 to create an interrupt for RPM counter.......

I really do not understand how can use TIMER 1 and TIMER 2 to create 50Hz PWM frequency ???

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,919
  • Helpful? 97
Re: PWM Frequency DC Motor Speed Control
« Reply #7 on: March 17, 2011, 08:11:06 AM »
Read and study the PIC data sheet on those two timers. Then write some short test code to run in the MPLAB simulator until you understand how they really work. If you a problem with the short test code post it here and if its HiTech C compatible I'll run it in MPLAB Sim.

Alternately, you may need to re-think your timer usage. It is possible that TMR1 will work better for the RPM counter.

TMR2 also has the feature that it can be compared to the PR2 register and automatically reloaded. This is handy for producing a constant period interrupt with very little ISR overhead. However, there is a limit on how long the period is since its pre-scaler is not as large as the TMR0 pre-scaler. But, you can assign a counter that is incremented in the ISR to extend or multiply the timer period and the TMR2 has a post-scaler to cause an interrupt on multiples of the TMR2 period.

You still haven't posted which PIC you are using.......

How you Googled "PIC timers"? There is a lot of info about them including tutorials and calculators as in this link:
http://www.best-microcontroller-projects.com/pic-timer-2.html

Offline twinsratioTopic starter

  • Jr. Member
  • **
  • Posts: 16
  • Helpful? 0
Re: PWM Frequency DC Motor Speed Control
« Reply #8 on: March 17, 2011, 09:36:47 PM »
I'm using PIC 16F887 for the programming.

 


Get Your Ad Here