Thursday, 16 July 2015

Lesson3 Push Button & PWM With PIC 16F877A (MikroC)

Pulse Width Modulation (PWM) is a technique where digital input is used to control the amount of power transferred to a load. This can be used to control motor speed, LED brightness etc.
                                                                                                                                                          


  
Modulating the duty cycle varies average DC value of the signal can be varied. The energy delivered depends on the ratio of ON and OFF time as well as the frequency of the pulses.

Pulse Width: refers to the amount of time the signal is high.

Duty Cycle: refers to the ratio of ON time to the total time period. It is expressed in Percent, 0% means signal is OFF, 50% means equal ON and OFF time, 100% means signal is high. Other values can be calculated by:
(Percent / 100) * 255 (for 8 bit Resolution)
for e.g to have a 75% duty cycle, (75/100) *255 = 192

PWM is done with the CCP Module in PIC Microcontrollers. CCP stands for Compare Capture Pulse Width Modulation.
MikroC has a rich set of Library Functions to perform this task easily.

MikroC PWM Functions:
  • PWMx_Init
  • PWMx_Start
  • PWMx_Set_Duty
  • PWMx_Stop
Some MCUs have multiple modules (CCPx) where x stands for the module number. In this case (CCP1,CCP2 etc) and also (PWM1_Init, PWM2_Init, etc) depending on the module you are using.
You can read more about this library functions from MikroC help file.

** Before Using this functions make sure that PWM is checked in the Library manager.
*** Remember to check your datasheet to know the port pin associated with each pwm module

MikroC Code:

/********************************** Project Name : Push Button & PWM with 16F877A Author : Promise Description : This project demonstrate using of push button to vary the duty cycle of PWM on CCP1 (PORTC Bit2) Test configuration: MCU: PIC 16F877A Oscillator: XT 8.0000 MHz, 8.0000 MHz Crystal ***********************************/ unsigned short current_duty; void Init() { CMCON = 0x07; // turn off Comparator ADCON1 = 0x06; // digital input PORTA = 0; TRISA = 255; // configure PORTA pins as input PORTC = 0; // set PORTC to 0 TRISC = 0; // PORTC pins as output PWM1_Init(5000); // Initialize PWM1 module at 5KHz } void main() { Init(); current_duty = 200; // current_duty initial value PWM1_Start(); // start PWM1 PWM1_Set_Duty(current_duty); // Set current_duty for PWM1 do { // endless loop if (PORTA.B0==1) { // button on RA0 pressed Delay_ms(20); // Switch debounce  if (PORTA.B0==1){  
current_duty++; // increment current_duty PWM1_Set_Duty(current_duty); // Set duty to Current Duty delay_ms(10); }
} if (PORTA.B1==1) { // button on RA1 is pressed Delay_ms(20);  if (PORTA.B1==1) {  
current_duty--; // decrement current_duty PWM1_Set_Duty(current_duty); delay_ms(10); } } if(current_duty==255){ current_duty = 200; PWM1_Set_Duty(current_duty); Delay_ms(5); // slow down } } } while (1); }


Proteus Schematic :


No comments:

Post a Comment