Revision: 1334 Author: sebastien.lelong Date: Sun Sep 20 15:12:04 2009 Log: pwm tutorial part 1 from jalliblog http://code.google.com/p/jallib/source/detail?r=1334
Added: /trunk/doc/dita/tutorials/code /trunk/doc/dita/tutorials/code/blog_16f88_board_sl_pwm_led.jal /trunk/doc/dita/tutorials/images/pwm_duty.png /trunk/doc/dita/tutorials/images/pwm_freq.png /trunk/doc/dita/tutorials/images/pwm_led_breadboard.jpg /trunk/doc/dita/tutorials/images/pwm_led_details.jpg /trunk/doc/dita/tutorials/images/pwm_led_schematics.png /trunk/doc/dita/tutorials/tutorial_pwm1.xml Modified: /trunk/doc/dita/tutorials/tutorials.ditamap ======================================= --- /dev/null +++ /trunk/doc/dita/tutorials/code/blog_16f88_board_sl_pwm_led.jal Sun Sep 20 15:12:04 2009 @@ -0,0 +1,69 @@ +-- Title: Test program for 1 PWM channel, using a LED +-- Author: Sebastien Lelong, Copyright (c) 2008-2009, all rights reserved. +-- Adapted-by: +-- Compiler: >=2.4i +-- +-- This file is part of jallib (http://jallib.googlecode.com) +-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php) +-- +-- Description: this sample show how to use PWM in low resolution mode. +-- It progressively light up and down a LED. Sweet... +-- +-- +-- +-- +-- This file has been generated on Sun Feb 8 11:05:54 2009, from: +-- * board: board_16f88_sl.jal +-- * test : test_pwm_led.jal +-- + + +;@jallib section chipdef +-- chip setup +include 16f88 + +;-- +-- We'll use internal oscillator. It work @ 8MHz +pragma target clock 8_000_000 +pragma target OSC INTOSC_NOCLKOUT +-- Specify no postscaler, ie. really runs @8MHz +OSCCON_IRCF = 0b_111 +pragma target WDT disabled -- no watchdog +pragma target LVP disabled -- no low-voltage programming +pragma target CCP1MUX RB0 -- ccp1 pin on B0 +pragma bootloader long_start -- for TinyBootloader + +;@jallib section ccp +-- ccp setup +var volatile bit pin_ccp1_direction is pin_b0_direction + +enable_digital_io() + +-- Configure PWM +pin_ccp1_direction = output +include pwm_hardware +pwm_max_resolution(1) +pwm1_on() + +forever loop + var byte i + i = 0 + -- loop up and down, to produce different duty cycle + while i < 250 loop + pwm1_set_dutycycle(i) + _usec_delay(10000) + i = i + 1 + end loop + while i > 0 loop + pwm1_set_dutycycle(i) + _usec_delay(10000) + i = i - 1 + end loop + -- turning off, the LED lights at max. + _usec_delay(500000) + pwm1_off() + _usec_delay(500000) + pwm1_on() + +end loop + ======================================= --- /dev/null +++ /trunk/doc/dita/tutorials/images/pwm_duty.png Sun Sep 20 15:12:04 2009 Binary file, no diff available. ======================================= --- /dev/null +++ /trunk/doc/dita/tutorials/images/pwm_freq.png Sun Sep 20 15:12:04 2009 Binary file, no diff available. ======================================= --- /dev/null +++ /trunk/doc/dita/tutorials/images/pwm_led_breadboard.jpg Sun Sep 20 15:12:04 2009 Binary file, no diff available. ======================================= --- /dev/null +++ /trunk/doc/dita/tutorials/images/pwm_led_details.jpg Sun Sep 20 15:12:04 2009 Binary file, no diff available. ======================================= --- /dev/null +++ /trunk/doc/dita/tutorials/images/pwm_led_schematics.png Sun Sep 20 15:12:04 2009 Binary file, no diff available. ======================================= --- /dev/null +++ /trunk/doc/dita/tutorials/tutorial_pwm1.xml Sun Sep 20 15:12:04 2009 @@ -0,0 +1,107 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This document was created with Syntext Serna Free. --> +<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd" []> +<topic id="topic-1"> + <title>Having fun with PWM and a LED (part 1)</title> + <abstract> + <p>In this "Step-by-Step" tutorial, we're going to (try to) have some fun with PWM. PWM stands for <xref href="http://en.wikipedia.org/wiki/PWM" format="html">Pulse Width Modulation</xref>, and is quite weird when you first face this (this was at least my first feeling).</p> + </abstract> + <prolog> + <author>Sébastien Lelong</author> + <publisher>Jallib Group</publisher> + <copyright> + <copyryear year="2009"/> + <copyrholder>Jallib Group</copyrholder> + </copyright> + </prolog> + <body> + <section> + <title>So, how does PWM look like ?...</title> + <p>PWM is about switching one pin (or more) high and low, at different frequencies and duty cycles. This is a on/off process. You can either vary:<ul> + <li>the <b>frequency</b>,</li> + <li>or the <b>duty cycle</b>, that is the proportion where the pin will be high</li> + </ul><fig> + <title>PWM: same duty cycle, different frequencies.</title> + <image href="images/pwm_freq.png"/> + <p><i>Both have a 50% duty cycle (50% on, 50% off), but the upper one's frequency is twice the bottom</i></p> + </fig><fig> + <title>PWM: same frequency, different duty cycles</title> + <image href="images/pwm_duty.png"/> + <p><i>Three different duty cycle (10%, 50% and 90%), all at the same frequency</i></p> + </fig></p> + <p>But what is PWM for ? What can we do with it ? Many things, like:<ul> + <li>producing variable voltage (to control DC motor speed, for instance)</li> + <li>playing sounds: duty cycle is constant, frequency is variable</li> + <li>playing PCM wave file (PCM is Pulse Code Modulation)</li> + <li>...</li> + </ul></p> + </section> + <section> + <title>One PWM channel + one LED = fun </title> + <p>For now, and for this first part, we're going to see how to <i>control the brightness of a LED</i>. If simply connected to a pin, it will light at its max brightness, because the pin is "just" high (5V).</p> + <p>Now, if we connect this LED on a PWM pin, maybe we'll be able to control the brightness: as previously said, <i>PWM can be used to produce variable voltages</i>. If we provide half the value (2.5V), maybe the LED will be half its brightness (though I guess the relation between voltage and brightness is not linear...). Half the value of 5V. How to do this ? Simply <b>configure the duty cycle to be 50% high, 50% low</b>.</p> + <p>But we also said <i>PWM is just about switching a pin on/off</i>. That is, either the pin will be 0V, or 5V. So how will we be able to produce 2.5V ? Technically speaking, we won't be able to produce a real 2.5V, but if PWM frequency is high enough, then, on the average, and from the LED's context, it's as though the pin outputs 2.5V.</p> + </section> + <section> + <title> Building the whole</title> + <p>Enough theory, let's get our hands dirty. Connecting a LED to a PWM pin on a 16f88 is quite easy. This PIC has quite a nice feature about PWM, it's possible to select which pin, between RB0 and RB3, will carry the PWM signals. Since I use <xref href="http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm" format="html">tinybootloader</xref> to upload my programs, and since tiny's fuses are configured to select the RB0 pin, I'll keep using this one (if you wonder why tinybootloader interferes here, <xref href="http://jallib.blogspot.com/2009/01/common-pitfall-setting-up-registers.html" format="html">read this post</xref>).</p> + <p><fig> + <title>Connecting a LED to a PWM pin</title> + <image href="images/pwm_led_schematics.png"/> + </fig></p> + <p>On a breadboard, this looks like this:<image href="images/pwm_led_breadboard.jpg" width="400" placement="break"/><i>The connector brings +5V on the two bottom lines (+5V on line A, ground on line B).</i></p> + <p><image href="images/pwm_led_details.jpg" placement="break"/><i>LED is connected to RB0</i></p> + </section> + <section> + <title>Writing the software</title> + <p>For this example, I took one of the 16f88's sample included in jallib distribution (<xref href="http://code.google.com/p/jallib/source/browse/trunk/sample/by_device/16f88/16f88_pwm_led.jal" format="html">16f88_pwm_led.jal</xref>), and just adapt it so it runs at 8MHz, using internal clock. It also select RB0 as the PWM pin.</p> + <p>So, step by step... First, as we said, we must select which pin will carry the PWM signals...</p> + <codeblock> +pragma target CCP1MUX RB0 -- ccp1 pin on B0</codeblock> + <p>and configure it as output</p> + <codeblock>var volatile bit pin_ccp1_direction is pin_b0_direction +pin_ccp1_direction = output +-- (simply "pin_b0_direction = output" would do the trick too)</codeblock> + <p>Then we include the PWM library.</p> + <codeblock>include pwm_hardware</codeblock> + <p>Few words here... This library is able to handle <b>up to 10 PWM channels</b> (PIC using CCP1, CCP2, CCP3, CCP4, ... CCP10 registers). Using conditional compilation, it <b>automatically selects the appropriate underlying PWM libraries</b>, for the selected target PIC.</p> + <p>Since 16f88 has only one PWM channel, it just includes "pwm_ccp1" library. If we'd used a 16f877, which has two PWM channels, it would include "pwm_ccp1" <i>and</i> "pwm_ccp2" libraries. What is important is it's transparent to users (you).</p> + <p>OK, let's continue. We now need to configure the <b>resolution</b>. What's the resolution ? Given a frequency, the <b>number of values you can have for the duty cycle</b> can vary (you could have, say, 100 different values at one frequency, and 255 at another frequency). Have a look at the datasheet for more.</p> + <p>What we want here is to have the <b>max number of values we can for the duty cycle</b>, so we can select the exact brightness we want. We also want to <b>have the max frequency</b> we can have (ie. no pre-scaler).</p> + <codeblock>pwm_max_resolution(1)</codeblock> + <p>If you read the <xref href="http://jallib.googlecode.com/svn/trunk/doc/html/pwm_common.html" format="html">jalapi documentation</xref> for this, you'll see that the frequency will be 7.81kHz (we run at 8MHz).</p> + <p>PWM channels can be turned on/off independently, now we want to activate our channel:</p> + <codeblock>pwm1_on()</codeblock> + <p>Before we dive into the forever loop, I forgot to mention PWM can be used in <b>low or high resolution</b>. On <i>low resolution</i>, duty cycles values range from <i>0 to 255</i> (8 bits). On <i>high resolution</i>, values range from <i>0 to 1024</i> (10 bits). In this example, we'll use low resolution PWM. For high resolution, you can have a look at the other sample, <xref href="http://code.google.com/p/jallib/source/browse/trunk/sample/by_device/16f88/16f88_pwm_led_highres.jal" format="html">16f88_pwm_led_highres.jal</xref>. As you'll see, there are very few differences.</p> + <p>Now let's dive into the loop...</p> + <codeblock>forever loop + var byte i + i = 0 + -- loop up and down, to produce different duty cycle + while i < 250 loop + pwm1_set_dutycycle(i) + _usec_delay(10000) + i = i + 1 + end loop + while i > 0 loop + pwm1_set_dutycycle(i) + _usec_delay(10000) + i = i - 1 + end loop + -- turning off, the LED lights at max. + _usec_delay(500000) + pwm1_off() + _usec_delay(500000) + pwm1_on() + +end loop</codeblock> + <p>Quite easy right ? There are <i>two main waves</i>: one will light up the LED progressively (0 to 250), another will turn it off progressively (250 to 0). On each value, we set the duty cycle with <codeph>pwm1_set_dutycycle(i)</codeph> and wait a little so we, humans, can see the result.</p> + <p>About the result, how does this look like ? See this video: <xref href="http://www.youtube.com/watch?v=r9_TfEmUSf0" format="html">http://www.youtube.com/watch?v=r9_TfEmUSf0</xref></p> + </section> + <section> + <title>"I wanna try, where are the files ?"</title> + <p>To run this sample, you'll need the <xref href="http://code.google.com/p/jallib/downloads/list" format="html">last jallib pack</xref> (at least 0.2 version). You'll also find the exact code we used <xref href="http://code.google.com/p/jallib/source/browse/trunk/doc/dita/tutorials/code/blog_16f88_board_sl_pwm_led.jal" format="jal">here</xref>.</p> + </section> + <p><i>Sébastien Lelong</i></p> + </body> +</topic> ======================================= --- /trunk/doc/dita/tutorials/tutorials.ditamap Sat Sep 19 14:18:54 2009 +++ /trunk/doc/dita/tutorials/tutorials.ditamap Sun Sep 20 15:12:04 2009 @@ -3,7 +3,7 @@ <bookmap id="bookmap_tutorials"> <booktitle> <mainbooktitle>The Tutorial Book</mainbooktitle> - <booktitlealt>Have fun with PIC microcontrollers,Jal v2 and Jallib</booktitlealt> + <booktitlealt>Have fun with PIC microcontrollers, Jal v2 and Jallib</booktitlealt> </booktitle> <bookmeta> <author>Sébastien Lelong</author> @@ -22,6 +22,7 @@ </booklists> </frontmatter> <chapter> + <topicref href="tutorial_pwm1.xml"/> <topicref href="tutorial_gp2d02.xml"/> </chapter> </bookmap> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jallib" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jallib?hl=en -~----------~----~----~----~------~----~------~--~---
