Code: Select all
/******************************************************************************
****************Bi Directional DC motor Control using PIC16F684****************
****************Developed By Raghu Nandan Ravi*********************************
****************Date : 29th March 2006*****************************************
****************Technical Parameters:******************************************
Oscillator Used : Internal Oscillator 8MHz
PWM frequency : To be input by the user
Prescalar : To be input by the user
Duty Cycle : To be input by the user
**********************Important Formula****************************************
PWM Period=(PR2+1)*4*TOSC*PRESCALAR
DC=CCPR1L:CCP1CON<5:4>*TOSC*PRESCALAR
Resolution=log(FOSC/FPWM*prescalar)/log2
*******************************************************************************/
#define MCU_frequency 8000000ul
#define tmr2_prescalar 4
#define PWM_frequency 4880
#define duty_cycle 0.50 //50% duty cycle
void configure_timer2(void);
void pwm_init1(void);
void configure_output(void);
unsigned char duty_cycle1(void);
unsigned char motor_forward(void);
unsigned char motor_reverse(void);
void main(void)
{
pwm_init1();
while (1)
{
motor_forward(); //run motor in forward direction
}
}
//Configure the Port pins as Output by clearing the TRISC pins
void configure_output(void)
{
TRISC.F5=0;
TRISC.F4=0;
TRISC.F3=0;
TRISC.F2=0;
}
void configure_timer2(void)
{
PIR1.TMR2IF=0;
T2CON=0X05; //postscale of 1:1 and prescale of 1:4
asm{
TMR2_OVERFLOW: //LABEL
btfss PIR1,TMR2IF //test for TMR2 overflow
goto TMR2_OVERFLOW //no!TEST AGAIN
bcf PIR1,TMR2IF //clear the flag bit and continue.
}
}
//Run the motor in forward direction
unsigned char motor_forward(void)
{
unsigned int TEMP;
TEMP=duty_cycle1();
CCP1CON=TEMP+0X4C;
configure_timer2();
configure_output();
PORTC.F5=1; //P1A active high continuosuly
PORTC.F4=0;
PORTC.F3=0;
PORTC.F2=1; //P1D modulated ouput
}
unsigned char motor_reverse(void)
{
unsigned int TEMP;
TEMP=duty_cycle1();
CCP1CON=TEMP+0XCC;
configure_timer2();
configure_output();
PORTC.F5=0;
PORTC.F4=1; //P1D modulated ouput
PORTC.F3=1; //P1C active high continuosuly
PORTC.F2=0;
}
void pwm_init1(void)
{
unsigned int period_register;
TRISC=0XFF; //set the ports initially to input
PORTC=0X00;
period_register= MCU_frequency/(PWM_frequency*4*tmr2_prescalar)-1;
PR2=period_register;
T2CON=0X00; //set the timer2 initially to 0
INTCON=0X00;
PIE1=0;
PIR1=0;
OSCCON=0X75;
OSCTUNE=0X00;
TMR2=0;
}
unsigned char duty_cycle1(void)
{
unsigned int TEMP, control_register, CCP1CON_register,val,TEMPX,period_register;
float duty_cycle2;
duty_cycle2=duty_cycle/PWM_frequency;
control_register=duty_cycle2*MCU_frequency/tmr2_prescalar;
CCPR1L=control_register>>2; //upper 8 bits of the 10 bits duty cycle resolution
TEMP=control_register<<8;
CCP1CON_register=TEMP>>8;
CCP1CON_register&=0X03;
switch(CCP1CON_register)
{
case 0:
{
TEMPX==0X00;
break;
}
case 1:
{
TEMPX==0X10;
break;
}
case 2:
{
TEMPX==0X20;
break;
}
case 3:
{
TEMPX==0X30;
break;
}
}
return TEMPX;
}