{"id":1443,"date":"2011-01-04T13:44:18","date_gmt":"2011-01-04T18:44:18","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=1443"},"modified":"2012-07-30T09:29:27","modified_gmt":"2012-07-30T13:29:27","slug":"lab-9-pulse-width-modulation-pwm","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/lab-9-pulse-width-modulation-pwm\/","title":{"rendered":"Lab 9: Pulse Width Modulation (PWM) using PIC CCP module"},"content":{"rendered":"<p><strong>Description<\/strong><\/p>\n<p>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.<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=1481\" rel=\"attachment wp-att-1481\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1481 aligncenter\" title=\"PWM\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/PWM.png\" alt=\"\" width=\"516\" height=\"490\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/PWM.png 516w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/PWM-473x450.png 473w\" sizes=\"auto, (max-width: 516px) 100vw, 516px\" \/><\/a><\/p>\n<p><!--more--><br \/>\n<strong>Theory<\/strong><\/p>\n<p>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.<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=1468\" rel=\"attachment wp-att-1468\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1468 aligncenter\" title=\"CCP1CON\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/CCP1CON.jpg\" alt=\"\" width=\"588\" height=\"493\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/CCP1CON.jpg 588w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/CCP1CON-536x450.jpg 536w\" sizes=\"auto, (max-width: 588px) 100vw, 588px\" \/><\/a><\/p>\n<p>In <em>Capture<\/em> mode, the\u00a0CCPR1L 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:<\/p>\n<ul>\n<li>Every falling edge<\/li>\n<li>Every rising edge<\/li>\n<li>Every 4th rising edge<\/li>\n<li>Every 16th rising edge<\/li>\n<\/ul>\n<p>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.<\/p>\n<p>In <em>Compare<\/em> 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.<\/p>\n<p>In <em>PWM<\/em> mode, the RB3\/CCP1 pin can output a 10-bit resolution periodic digital waveform with\u00a0programmable period and duty cycle. To operate in PWM mode, the CCP1 pin must be configured\u00a0for output. The duty cycle of the waveform to be generated is a 10-bit value of which the upper eight\u00a0bits are stored in the CCPR1L register, whereas the lowest two bits are stored in bit 5 and bit\u00a04 of the CCP1CON register.<\/p>\n<p><strong>Circuit<\/strong><\/p>\n<p>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.<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/PIC16F628A_PWM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1876 aligncenter\" title=\"PIC16F628A_PWM\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/PIC16F628A_PWM-550x397.png\" alt=\"\" width=\"550\" height=\"397\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/PIC16F628A_PWM-550x397.png 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/PIC16F628A_PWM.png 820w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=1444\" rel=\"attachment wp-att-1444\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1444 aligncenter\" title=\"Img_Lab9_CircuitSetup\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_CircuitSetup.jpg\" alt=\"\" width=\"580\" height=\"287\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_CircuitSetup.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_CircuitSetup-550x272.jpg 550w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: center;\">Circuit setup on breadboard<\/p>\n<p><strong>Software<\/strong><\/p>\n<p>The MikroC Pro for PIC compiler provides four library routines for controlling the PWM operation using the CCP module. They are PWM1_Init(<strong>const long<\/strong> frequency), PWM1_Set_Duty(<strong>unsigned short<\/strong> duty_ratio), PWM1_Start(<strong>void<\/strong>), and PWM_Stop(<strong>void<\/strong>). 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.<\/p>\n<pre>\/*\r\n Lab 9: Pulse Width Modulation\r\n Copyright @ Rajendra Bhatt, 2010.\r\n Description: CCP module generating PWM\r\n MCU: PIC16F628A\r\n Oscillator: XT, 4.0 MHz, MCLR Enabled\r\n*\/\r\n sbit UP at RB0_bit;\r\n sbit DOWN at RB1_bit;\r\n unsigned short new_DC, current_DC;\r\n\r\n void debounce(){\r\n  Delay_ms(300);\r\n }\r\n\r\n void main() {\r\n CMCON = 0x07; \/\/ Disable comparators\r\n PORTB = 0x00; \r\n TRISB = 0b00000011; \/\/ RB0, RB1 input, RB3 (PWM1) output\r\n PWM1_Init(5000);    \/\/ PWM module initialization (5KHz)\r\n new_DC = 0;         \/\/ Initial value of variable Duty Cycle\r\n current_DC = 0;\r\n PWM1_Start();       \/\/ Start PWM1 module with Zero DC\r\n PWM1_Set_Duty(current_DC);\r\n do {\r\n  if (!UP){      \/\/ If the button connected to RB0 is pressed\r\n   debounce();\r\n   if (new_DC &lt; 250)      \/\/ Don't go above 250\r\n   new_DC = new_DC + 25 ; \/\/ increment Duty Cycle by 25\r\n  }\r\n  if (!DOWN) {   \/\/ If the button connected to RB1 is pressed\r\n   debounce();\r\n   if (new_DC !=0)        \/\/ Don't go below 0\r\n   new_DC= new_DC - 25 ; \/\/ Decrement Duty Cycle by 25\r\n  }\r\n  if (current_DC != new_DC) {\r\n   current_DC = new_DC ;\r\n   PWM1_Set_Duty(current_DC); \/\/ Change the current DC to new value\r\n  }\r\n } while(1);\r\n}  \/\/ END main()<\/pre>\n<p><a href=\"http:\/\/embedded-lab.com\/uploads\/HexFiles\/PIC16F628A\/Lab9_PWM.zip\"><strong>Download complete source and HEX files<\/strong><\/a><\/p>\n<p>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.<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=1445\" rel=\"attachment wp-att-1445\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1445 aligncenter\" title=\"Img_Lab9_Output1\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output1.jpg\" alt=\"\" width=\"580\" height=\"297\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output1.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output1-550x281.jpg 550w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: center;\">0% Duty Cycle<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=1446\" rel=\"attachment wp-att-1446\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1446 aligncenter\" title=\"Img_Lab9_Output2\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output2.jpg\" alt=\"\" width=\"580\" height=\"297\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output2.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output2-550x281.jpg 550w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: center;\">25 % Duty Cycle<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=1447\" rel=\"attachment wp-att-1447\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1447 aligncenter\" title=\"Img_Lab9_Output3\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output3.jpg\" alt=\"\" width=\"580\" height=\"286\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output3.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output3-550x271.jpg 550w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: center;\">50% Duty Cycle<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=1448\" rel=\"attachment wp-att-1448\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1448 aligncenter\" title=\"Img_Lab9_Output4\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output4.jpg\" alt=\"\" width=\"580\" height=\"297\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output4.jpg 580w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2011\/01\/Img_Lab9_Output4-550x281.jpg 550w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: center;\">~ 100% Duty Cycle<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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,<\/p>\n","protected":false},"author":2,"featured_media":1444,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38],"tags":[155,96,154,153],"class_list":["post-1443","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pic-tutorials","tag-light-dimmer","tag-pic16f628a","tag-pulse-width-modulation","tag-pwm"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/1443","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=1443"}],"version-history":[{"count":37,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/1443\/revisions"}],"predecessor-version":[{"id":5805,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/1443\/revisions\/5805"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/1444"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=1443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=1443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=1443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}