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.

Help !PIC 16F887 Generating 50Hz PWM Frequency for DC Motor Speed Control

Status
Not open for further replies.

twinsratio

New Member
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?

Below is my 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 ? I'm using PIC 16F887 MCU

#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 inadvance

Thank you,
 
You could use timer one preset to 2 and load offset setting with

TMR1 = 15626 which gives 50.09 hz
 
Status
Not open for further replies.

Latest threads

Back
Top