You are on page 1of 11

Generating PWM with PIC Microcontroller using CCP Module 2

19 Jan 2013 | PIC Microcontroller Tutorials Tutorials Tags:Microcontroller MikroC PIC Proteus Tutorials PWM is a technique used to generate analog output signal using digital signals. It is commonly used to control average power delivered to a load, motor speed control, generating analog voltage levels and for generating analog waveforms. CCP Modules are available with a number of PIC Microcontrollers. CCP stands for Capture/Compare/PWM. Using PWM module is far more easier and cost effective than using extra chips for PWM generation. MikroC Pro for PIC Microcontroller provide built-in library for PWM which makes our task very simple.

MikroC Functions

PWM1_Init(constant long frequency) : This function initializes the PWM module with duty ratio 0. Frequency parameter is the desired frequency in Hz. It should be a numeric constant, should not be a variable. PWM1_Set_Duty(unsigned short duty_ratio) : 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. The PWM1_Init() routine must be called before using this. PWM1_Start() : This function starts the PWM output. PWM1_Init() must be called before calling this routine, PWM1_Stop() : This function stops the PWM output. PWM1_Init() must be called before calling this routine. PWM1_Start() should be called before calling this function otherwise calling this function will not have any effect as PWM module is not running.

Note 1 : For microcontrollers with more than one CCP module, to use the desired CCP module for PWM generation simply change the number 1 in the prototype with desired module number. eg: PWM2_Init(5000), PWM2_Start(). Note 2 : All PWM modules in a PIC Microcontroller uses Timer 2 for its operation, so you cannot set different frequencies for different PWM modules.

In this tutorial we are using PIC 16F877A for demonstrating PWM generation using CCP module. PIC 16F877A contains two CCP modules.

Circuit Diagram Using internal PWM Module of PIC


In the below circuit four switches are provided for controlling the Duty Ratio of PWM generated by two CCP modules of the PIC Microcontroller.

Switch 1 : To increase the Duty Ratio of PWM produced by CCP1 Switch 2 : To decrease the Duty Ratio of PWM produced by CCP1 Switch 3 : To increase the Duty Ratio of PWM produced by CCP2 Switch 4 : To decrease the Duty Ratio of PWM produced by CCP2

Using Internal PWM Module PIC Microcontroller Circuit Diagram

The output of the two CCP modules are given to a CRO to observe the changes in pulse width. It may be given to two LEDs and you can see the changes in brightness as Duty Ratio changes.

MikroC Program
void main() { short current_duty_1 = 16; // initial value for current_duty_1 short current_duty_2 = 16; // initial value for current_duty_2 TRISD = 0xFF; // PORTD as input TRISC = 0x00; // PORTC as output PWM1_Init(5000); PWM2_Init(5000); PWM1_Start(); PWM2_Start(); // Initialize PWM1 // Initialize PWM2

// start PWM1 // start PWM2

PWM1_Set_Duty(current_duty_1); // Set current duty for PWM1 PWM2_Set_Duty(current_duty_2); // Set current duty for PWM2 while (1) // endless loop { if (!RD0_bit) // if button on RD0 pressed { Delay_ms(40); current_duty_1++; // increment current_duty_1 PWM1_Set_Duty(current_duty_1); //Change the duty cycle } if (!RD1_bit) // button on RD1 pressed { Delay_ms(40); current_duty_1--; // decrement current_duty_1 PWM1_Set_Duty(current_duty_1); } if (!RD2_bit) // if button on RD2 pressed { Delay_ms(40); current_duty_2++; // increment current_duty_2 PWM2_Set_Duty(current_duty_2); } if (!RD3_bit) // if button on RD3 pressed { Delay_ms(40); current_duty_2--; // decrement current_duty_2 PWM2_Set_Duty(current_duty_2); }

Delay_ms(10); } }

// slow down change pace a little

I thinks the program is self explanatory, so if you have any doubts please comment below You can download the MikroC Source Code, Proteus files etc here You must be LOGIN or REGISTER to download this file.

Description Pulse width modulation (PWM) is a technique of controlling the amount of power delivered to an electronic load using an on-off digital signal. The fraction of the period for which the signal is on is known as the duty cycle. The average DC value of the signal can be varied by varying the duty cycle. The duty cycle can be anywhere between 0 (signal is always off) to 1 (signal is constantly on). Suppose, if the signal has +5 V while it is on and 0 V during off condition, then by changing the duty cycle of the signal, any voltage between 0-5 V can be simulated. This method is commonly used for controlling speeds of DC motors and brightness of lamps. This lab session will talk about how to generate a PWM signal using the PIC16F628A microcontroller and control the brightness of an LED with it. PIC16F628A has a built-in hardware, called Capture/Compare/PWM (CCP) module, to generate a PWM signal.

Theory The Capture/Compare/PWM (CCP) module in the PIC16F628A microcontroller is very versatile. The Capture and Compare features integrate closely with the 16-bit TMR1 and the PWM feature uses the third timer, the 8-bit TMR2. The CCP module has two 8-bit registers, called CCPR1L and CCPR1H. Together they form a 16-bit register that can be used for capture, compare or to form the duty cycle of a PWM stream. The CCP module is controlled by the CCP1CON register.

In Capture mode, the CCPR1L and CCPR1H registers record the 16-bit value of the TMR1 register when an event occurs on pin RB3/CCP1. An event can take place on:

Every Every Every Every

falling edge rising edge 4th rising edge 16th rising edge

The RB3/CCP1 pin must be configured as an input and Timer1 must be in Timer mode or synchronized Counter mode for this to work. A Capture event can also trigger an interrupt. In Compare mode, the value of the TMR1 register is continuously compared to the value of the 16-bit register made up of CCPR1H and CCPR1L. When a match occurs, the RB3/CCP1 pin is driven high, low or remains unchanged, depending upon the setting of the CCP1CON register. The RB3/CCP1 pin must be configured as an output by clearing the corresponding TRISB bit. The Capture and Compare modes will be discussed later in more detail. In PWM mode, the RB3/CCP1 pin can output a 10-bit resolution periodic digital waveform with programmable period and duty cycle. To operate in PWM mode, the CCP1 pin must be configured for output. The duty cycle of the waveform to be generated is a 10-bit value of which the

upper eight bits are stored in the CCPR1L register, whereas the lowest two bits are stored in bit 5 and bit 4 of the CCP1CON register. Circuit The setup for this experiment is very simple. Two tact switches are connected to pins RB0 and RB1 to provide inputs. An LED is driven by the PWM output from the RB3/CCP1 pin through a current limit resistor of 330R. The duty cycle of the output PWM signal is increased or decreased with the two tact switch inputs, and that will vary the brightness of the LED.

Circuit setup on breadboard Software The MikroC Pro for PIC compiler provides four library routines for controlling the PWM operation using the CCP module. They are PWM1_Init(const long frequency), PWM1_Set_Duty(unsigned short duty_ratio), PWM1_Start(void), and PWM_Stop(void). Read the MikroC manual for further details. The following program gives 10 different brightness levels of LED by varying the duty cycle from 0 to 250 in the step of 25. The duty cycle will be varied by pressing the UP and DOWN tact switches.

/* Lab 9: Pulse Width Modulation Copyright @ Rajendra Bhatt, 2010. Description: CCP module generating PWM MCU: PIC16F628A Oscillator: XT, 4.0 MHz, MCLR Enabled */ sbit UP at RB0_bit; sbit DOWN at RB1_bit; unsigned short new_DC, current_DC; void debounce(){ Delay_ms(300); } void main() { CMCON = 0x07; // Disable comparators PORTB = 0x00; TRISB = 0b00000011; // RB0, RB1 input, RB3 (PWM1) output PWM1_Init(5000); // PWM module initialization (5KHz) new_DC = 0; // Initial value of variable Duty Cycle current_DC = 0;

PWM1_Start(); // Start PWM1 module with Zero DC PWM1_Set_Duty(current_DC); do { if (!UP){ // If the button connected to RB0 is pressed debounce(); if (new_DC < 250) // Don't go above 250 new_DC = new_DC + 25 ; // increment Duty Cycle by 25 } if (!DOWN) { // If the button connected to RB1 is pressed debounce(); if (new_DC !=0) // Don't go below 0 new_DC= new_DC - 25 ; // Decrement Duty Cycle by 25 } if (current_DC != new_DC) { current_DC = new_DC ; PWM1_Set_Duty(current_DC); // Change the current DC to new value } } while(1); } // END main()
Download complete source and HEX files As the circuit is powered, the LED starts with zero brightness, i.e., zero duty cycle. Pressing the UP button increases the duty cycle and the LED will glow. The LED will brighten more and more on every press of the UP button, until the duty cycle reaches close to 1.

0% Duty Cycle

25 % Duty Cycle

50% Duty Cycle

~ 100% Duty Cycle

how to read speed sensor PWM pules using pic 16f877a