How to Program PWM2 in PIC16F877A
The following code demonstrate, how to write a program to use internal CCP (capture, compare, and PWM) module to generate pulse width modulation.
Timer-2 is used to provide clock to CCP module, so you can not use Timer-2 for any other purpose if you are using CCP module. PWM is very useful feature to control DC motors. In this example, you learn how to control a DC motor. DC motor operating voltage is +5v and frequency is 2.0 khz. Initially 10% duty cycle is applied at startup of DC motor, after that you can increase duty cycle by pressing PWM increment button and decrease duty cycle by pressing PWM decrement button. The PWM duty cycle is shown on oscilloscope. You can visualize duty cycle on oscilloscope. The code is written in “mikroC PRO for PIC v.5.6.1” IDE and simulation is done with Proteus 8.0 SP0. At the end of code, you can find complete project files for download.
Timer-2 is used to provide clock to CCP module, so you can not use Timer-2 for any other purpose if you are using CCP module. PWM is very useful feature to control DC motors. In this example, you learn how to control a DC motor. DC motor operating voltage is +5v and frequency is 2.0 khz. Initially 10% duty cycle is applied at startup of DC motor, after that you can increase duty cycle by pressing PWM increment button and decrease duty cycle by pressing PWM decrement button. The PWM duty cycle is shown on oscilloscope. You can visualize duty cycle on oscilloscope. The code is written in “mikroC PRO for PIC v.5.6.1” IDE and simulation is done with Proteus 8.0 SP0. At the end of code, you can find complete project files for download.
Code in mikroC
// direction signal
sbit PWM2_INC_dir at TRISB.B0;
sbit PWM2_DEC_dir at TRISB.B1;
// bit labels portb
sbit PWM2_INC at PORTB.B0;
sbit PWM2_DEC at PORTB.B1;
void main(void)
{
// min duty cycle 10% ()
unsigned short duty_ratio = 25;
// set direction as input
PWM2_INC_dir = 1;
PWM2_DEC_dir = 1;
// init pwm frequency (Hz)
// pwm2 @ 2khz
PWM2_Init(2000);
// start PWM1
PWM2_Start();
// Set init duty for PWM2
// This function is used to set the duty cycle
// of the PWM. The parameter duty_ratio takes
// values from 0 to 255, ie 0 means 0% ,
// 127 means 50% and 255 means 100% duty cycle.
// 255/100 = 2.55 means step by 1%
PWM2_Set_Duty(duty_ratio);
while(1)
{
// if button on RB0 pressed
if (PWM2_INC == 0)
{
Delay_ms(40);
// increment duty cycle
if(duty_ratio < 255)
duty_ratio++;
// change duty cycle
PWM2_Set_Duty(duty_ratio);
}
// if button on RB1 pressed
if (PWM2_DEC == 0)
{
Delay_ms(40);
// decrement duty cycle
if(duty_ratio > 0)
duty_ratio–;
// change duty cycle
PWM2_Set_Duty(duty_ratio);
}
// slow down change pace a little
Delay_ms(5);
}
}
sbit PWM2_INC_dir at TRISB.B0;
sbit PWM2_DEC_dir at TRISB.B1;
// bit labels portb
sbit PWM2_INC at PORTB.B0;
sbit PWM2_DEC at PORTB.B1;
void main(void)
{
// min duty cycle 10% ()
unsigned short duty_ratio = 25;
// set direction as input
PWM2_INC_dir = 1;
PWM2_DEC_dir = 1;
// init pwm frequency (Hz)
// pwm2 @ 2khz
PWM2_Init(2000);
// start PWM1
PWM2_Start();
// Set init duty for PWM2
// This function is used to set the duty cycle
// of the PWM. The parameter duty_ratio takes
// values from 0 to 255, ie 0 means 0% ,
// 127 means 50% and 255 means 100% duty cycle.
// 255/100 = 2.55 means step by 1%
PWM2_Set_Duty(duty_ratio);
while(1)
{
// if button on RB0 pressed
if (PWM2_INC == 0)
{
Delay_ms(40);
// increment duty cycle
if(duty_ratio < 255)
duty_ratio++;
// change duty cycle
PWM2_Set_Duty(duty_ratio);
}
// if button on RB1 pressed
if (PWM2_DEC == 0)
{
Delay_ms(40);
// decrement duty cycle
if(duty_ratio > 0)
duty_ratio–;
// change duty cycle
PWM2_Set_Duty(duty_ratio);
}
// slow down change pace a little
Delay_ms(5);
}
}
Download Files
For download “mikroC PRO for PIC” project and “Proteus 8.0” simulation files, click here.
Comments
Post a Comment