<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>veys.com &#187; led</title>
	<atom:link href="http://veys.com/tag/led/feed/" rel="self" type="application/rss+xml" />
	<link>http://veys.com</link>
	<description>if I only had a tagline.</description>
	<lastBuildDate>Tue, 27 Sep 2011 21:35:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PIC LED blinker (busy-wait)</title>
		<link>http://veys.com/2002/08/21/pic-led-blinker-busy-wait/</link>
		<comments>http://veys.com/2002/08/21/pic-led-blinker-busy-wait/#comments</comments>
		<pubDate>Thu, 22 Aug 2002 04:18:18 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[howtos]]></category>
		<category><![CDATA[blinker]]></category>
		<category><![CDATA[electronics]]></category>
		<category><![CDATA[led]]></category>
		<category><![CDATA[legacy articles]]></category>
		<category><![CDATA[microcontroller]]></category>
		<category><![CDATA[pic]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.veys.com/blog/?p=120</guid>
		<description><![CDATA[Beyond all doubt, the #1 beginning program in microcontrollers is the LED blinker. It&#8217;s super simple, and teaches the concept of pin voltages and busy-waits. Here is a busy-wait LED blinker program, and a walkthrough building it in MPLab. First, the delay. This is a busy-wait delay program, busy-wait means you just burn instruction cycles [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_226" class="wp-caption alignright" style="width: 160px"><a href="http://www.veys.com/wp-content/uploads/2008/07/pic16_blinker_schem.jpg" rel="lightbox[120]"><img class="size-thumbnail wp-image-226  " title="LED blinker #1 circuit schematic" src="http://www.veys.com/wp-content/uploads/2008/07/pic16_blinker_schem-150x150.jpg" alt="LED blinker #1 circuit schematic" width="150" height="150" /></a><br />
<p class="wp-caption-text">Schematic</p></div>
<p>Beyond all doubt, the #1 beginning program in microcontrollers is the LED blinker. It&#8217;s super simple, and teaches the concept of pin voltages and busy-waits.  Here is a busy-wait LED blinker program, and a walkthrough building it in MPLab.</p>
<p>First, the delay. This is a busy-wait delay program, busy-wait means you just burn instruction cycles for the delay, keeping the MCU &#8220;busy&#8221;. There&#8217;s a tiny bit of math behind them. First, the clock speed is 20MHz, the instruction frequency is (clock/4) so our instructions are executing at 5MHz. This gives us a period of 200ns per cycle.</p>
<p>I created two delay functions, for versatility, and for LCD stuff which will come later but it&#8217;s handy here. One is a &#8220;DELAY_US&#8221; which will delay a specified amount of microseconds. This is done by wasting 5 cycles (5*200ns = 1us) a specified amount of times (less than or equal to 255us, since I only made an 8-bit &#8220;delay&#8221; variable). We can learn the cycle times from the data sheet, and make it work from there.</p>
<p>Next, I created a &#8220;DELAY_MS&#8221; which delays a specified amount of milliseconds. Same 8-bit limitation of max 255ms, but that&#8217;s enough to have fun with&#8230; It simply calls DELAY_US a few times with specified amounts of delay, adding up to 1000us (=1ms) and repeats as many times as we tell it to.</p>
<p>These delays are used to make the LED blinking visible, otherwise it would blink faster than we could see (if at all, it takes a cycle or two for the pin to change state so it might not even change if we just toggle it every other cycle).</p>
<p>Here&#8217;s a little more PIC architecture information. The PIC&#8217;s data registers are broken into &#8220;banks&#8221; (bank 0, 1, 2, 3). Meaning you cannot get at them all at the same time, although some are mapped to all banks so you CAN get at them, important ones. We usually hang out in bank 0&#8230; This usually isn&#8217;t a problem, just something you need to remember. The data sheet illustrates it pretty well. When it comes up I&#8217;ll clarify things about it.</p>
<p>Also, for the I/O pins. Since they&#8217;re bi-directional, you need to choose which direction to set them to. Input or output. This is done by setting the tri-state register for the given port, for example PORTA&#8217;s tris register is called TRISA (not tough!). You set the direction of a specific bit, by setting the bit of the TRIS register to either 0 or 1, 0 meaning OUTPUT and 1 meaning INPUT. Not tough to remember: 0 = Out and 1 = In.</p>
<h3>Source Code</h3>
<p>Ok, first you need to make sure you have MPLab from Microchip.com</p>
<p>Once you have MPLab, download the LED Blinker (busy-wait) source code.</p>
<p>MPLab is a nice IDE, you&#8217;ll need to create a &#8220;project&#8221; and then pick your chip, and add the asm file to it (called a &#8220;node&#8221;). All code is going to be indented 2 spaces, labels will not be indented at all, assembler directives are either 1 or 2 spaces in&#8230;</p>
<p>First few lines are kinda simple, the title directive just sets a title for your project&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"> <span style="color: #000000; font-weight: bold;">title</span>  <span style="color: #7f007f;">&quot;LED Blinker Tutorial 1&quot;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">LIST</span> R=<span style="color: #00007f; font-weight: bold;">DEC</span>
  <span style="color: #000000; font-weight: bold;">INCLUDE</span> <span style="color: #7f007f;">&quot;p16f628.inc&quot;</span>
 __CONFIG _CP_OFF &amp; _WDT_OFF &amp; _HS_OSC &amp; _PWRTE_ON &amp; _LVP_OFF &amp; _MCLRE_ON</pre></div></div>

<p>LIST R = DEC sets the default &#8220;radix&#8221; for the program, meaning the number base. So if I put 100 in a line somewhere, it means 100 DECIMAL. If I changed it to LIST R = HEX, then if I put 100 in somewhere, it means 0&#215;100, TOTALLY different. I find DEC easier to work with, and you can still use 0x whatever and it means HEX so you get the best of both worlds.</p>
<p>Next we INCLUDE the &#8220;p16f628.inc&#8221; which will give us nice little names for our registers so we don&#8217;t need to remember their addresses, how nice of Microchip.</p>
<p>Then the __CONFIG line, arguably the ugliest line of code while still being fairly simple. You can see the list of __CONFIG&#8217;s in the &#8220;p16f628.inc&#8221; file, they&#8217;re simply setting the configuration of certain chip features, the ones I have listed do this: _CP_OFF copyprotect OFF, you can set the copyprotect bits to make your chip unreadable, this is only good for a production product, don&#8217;t use it. _WDT_OFF, watchdog timer off, watchdog timer is there for mission-critical applications, it&#8217;s constantly running and needs to be reset constantly, if it isn&#8217;t reset it will reset the chip (assuming your program has locked up), we don&#8217;t need it here. _HS_OSC specifies a high speed oscillator, it&#8217;s in the data sheet. _PWRTE_ON turns on the power up timer delay, it&#8217;ll make the MCU wait a bit before executing to make sure voltage is stable, oscillator is stable, etc&#8230; _LVP_OFF &#8211; low voltage programming, dun&#8217;need it&#8230; _MCLRE_ON makes us hold MCLR high, instead of letting the chip do it&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
<span style="color: #666666; font-style: italic;">; Variable declarations</span>
<span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
 CBLOCK <span style="color: #0000ff;">0x20</span>
DELAY<span style="color: #339933;">,</span>DELAYTMP			<span style="color: #666666; font-style: italic;">; delay function variables...</span>
 ENDC</pre></div></div>

<p>Now to the variable declarations, the CBLOCK directive lets us just list out our variable names, and the assembler will assign addresses for us, this is handy. The 0&#215;20 is the starting address of general-purpose registers in BANK 0. We list em out, then end it with ENDC.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
<span style="color: #666666; font-style: italic;">; Macro declarations</span>
<span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
BANK0 <span style="color: #000000; font-weight: bold;">macro</span>           		<span style="color: #666666; font-style: italic;">; Switch to BANK0</span>
  bcf STATUS<span style="color: #339933;">,</span>RP1
  bcf STATUS<span style="color: #339933;">,</span>RP0
  <span style="color: #000000; font-weight: bold;">endm</span>
&nbsp;
BANK1 <span style="color: #000000; font-weight: bold;">macro</span>           		<span style="color: #666666; font-style: italic;">; Switch to BANK1</span>
  bcf STATUS<span style="color: #339933;">,</span>RP1
  <span style="color: #00007f; font-weight: bold;">bsf</span> STATUS<span style="color: #339933;">,</span>RP0
  <span style="color: #000000; font-weight: bold;">endm</span>
&nbsp;
DELAY_MILLI <span style="color: #000000; font-weight: bold;">macro</span> TIME
  movlw TIME
  movwf DELAY
  <span style="color: #00007f; font-weight: bold;">call</span> DELAY_MS
  <span style="color: #000000; font-weight: bold;">endm</span>
&nbsp;
DELAY_MICRO <span style="color: #000000; font-weight: bold;">macro</span> TIME
  movlw TIME
  movwf DELAY
  <span style="color: #00007f; font-weight: bold;">call</span> DELAY_US
  <span style="color: #000000; font-weight: bold;">endm</span></pre></div></div>

<p>Next the Macro&#8217;s&#8230; Macro&#8217;s are one of the coolest features of MPLab, it&#8217;s kinda like an inline C function, and kinda like a #define. When called, the code is dumped into where it was called from, but you can use variables in it, and even arguments to customize it&#8217;s compiling, stuff I&#8217;ll show in later programs.</p>
<p>Anyways, you make one by saying: NAME macro in the first column, then code. End it w/a endm. The ones I have are fairly simple and re-usable. BANK0 sets the bank bits to get us into BANK 0, go figure. BANK1 sets them to get us into BANK1, crazy!</p>
<p>DELAY_MILLI takes the TIME argument and loads it into W, next it moves W to the register labeled DELAY. Then it calls our illustrious DELAY_MS function which will be explained in detail down below&#8230; DELAY_MICRO does the same damn thing with DELAY_US!</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
<span style="color: #666666; font-style: italic;">; Program code</span>
<span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
  <span style="color: #000000; font-weight: bold;">PAGE</span>
&nbsp;
 <span style="color: #000000; font-weight: bold;">org</span> <span style="color: #0000ff;">0</span>
  <span style="color: #000000; font-weight: bold;">goto</span> MAIN
&nbsp;
 <span style="color: #000000; font-weight: bold;">org</span> <span style="color: #0000ff;">4</span>
ISR
  <span style="color: #666666; font-style: italic;">; interrupt handler</span>
  retfie</pre></div></div>

<p>PAGE is a pagebreak for printing, though it doesn&#8217;t work for me. <img src='http://veys.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>org 0 tells the assembler to start assembly at address 0, our first instruction is to jump (goto) the label MAIN.</p>
<p>org 4 starts us in the Interrupt address of PIC&#8217;s&#8230; This is kind of strange and will be explained later on, for now just accept it as fact&#8230;</p>
<p>And if you&#8217;re wondering if we lost space for 3 instructions between 0 and 4, you&#8217;re right. <img src='http://veys.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
<span style="color: #666666; font-style: italic;">; Subroutines</span>
<span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
DELAY_US			<span style="color: #666666; font-style: italic;">; busy wait of DELAY us</span>
				<span style="color: #666666; font-style: italic;">; 200ns instruction period assumed</span>
  <span style="color: #00007f; font-weight: bold;">nop</span>				<span style="color: #666666; font-style: italic;">; (1)</span>
  <span style="color: #00007f; font-weight: bold;">nop</span>				<span style="color: #666666; font-style: italic;">; (2)</span>
  decfsz DELAY<span style="color: #339933;">,</span>f		<span style="color: #666666; font-style: italic;">; test DELAY count (3)</span>
    <span style="color: #000000; font-weight: bold;">goto</span> DELAY_US		<span style="color: #666666; font-style: italic;">; loop if not done (4,5)</span>
  return			<span style="color: #666666; font-style: italic;">; gtfo (4,5)</span>
&nbsp;
DELAY_MS			<span style="color: #666666; font-style: italic;">; busy wait of DELAY ms</span>
				<span style="color: #666666; font-style: italic;">; dependant upon DELAY_US being accurate</span>
  movf DELAY<span style="color: #339933;">,</span>w
  movwf DELAYTMP		<span style="color: #666666; font-style: italic;">; save DELAY time</span>
DELAY_MS_LOOP			<span style="color: #666666; font-style: italic;">; inner loop</span>
  movlw <span style="color: #0000ff;">245</span>			<span style="color: #666666; font-style: italic;">; load 245 (1)</span>
  movwf DELAY			<span style="color: #666666; font-style: italic;">; into DELAY (2)</span>
  <span style="color: #00007f; font-weight: bold;">call</span> DELAY_US			<span style="color: #666666; font-style: italic;">; wait 245us (3-249)</span>
  movlw <span style="color: #0000ff;">245</span>			<span style="color: #666666; font-style: italic;">; load 245 (250)</span>
  movwf DELAY			<span style="color: #666666; font-style: italic;">; into DELAY (251)</span>
  <span style="color: #00007f; font-weight: bold;">call</span> DELAY_US			<span style="color: #666666; font-style: italic;">; wait 245us (252-498)</span>
  movlw <span style="color: #0000ff;">245</span>			<span style="color: #666666; font-style: italic;">; load 245 (499)</span>
  movwf DELAY			<span style="color: #666666; font-style: italic;">; into DELAY (500)</span>
  <span style="color: #00007f; font-weight: bold;">call</span> DELAY_US			<span style="color: #666666; font-style: italic;">; wait 245us (501-747)</span>
  movlw <span style="color: #0000ff;">246</span>			<span style="color: #666666; font-style: italic;">; load 246 (748)</span>
  movwf DELAY			<span style="color: #666666; font-style: italic;">; into DELAY (749)</span>
  <span style="color: #00007f; font-weight: bold;">call</span> DELAY_US			<span style="color: #666666; font-style: italic;">; wait 246us (750-997)</span>
  decfsz DELAYTMP<span style="color: #339933;">,</span>f		<span style="color: #666666; font-style: italic;">; test DELAYTMP count (998)</span>
    <span style="color: #000000; font-weight: bold;">goto</span> DELAY_MS_LOOP		<span style="color: #666666; font-style: italic;">; loop if not done (999,1000)</span>
  return			<span style="color: #666666; font-style: italic;">; gtfo (999,1000)</span></pre></div></div>

<p>Next we have our subroutines, the delays, I have these before the main lines of code just out of habit, it&#8217;s not required.</p>
<p>DELAY_US&#8230; Pretty simple really, we start out by burning 2 cycles, so we&#8217;ve waited 400ns so far, next we decrement our counter, and test if it&#8217;s zero, if it isn&#8217;t, we goto DELAY_US, looping again, if not, we return. The test itself takes one cycle (600ns so far) and either the goto or return take 2 cycles (1000ns = 1us) so we have our microsecond delay!</p>
<p>DELAY_MS works on the same principle, it&#8217;s accurate enough for this! <img src='http://veys.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
<span style="color: #666666; font-style: italic;">; Mainline of code</span>
<span style="color: #666666; font-style: italic;">;----------------------------------------------------------------------------------------</span>
MAIN
  BANK1
  bcf TRISA<span style="color: #339933;">,</span><span style="color: #0000ff;">2</span>			<span style="color: #666666; font-style: italic;">; PORT A, bit 2 is our output pin.</span>
  BANK0
&nbsp;
LOOP_BEGIN
  <span style="color: #00007f; font-weight: bold;">bsf</span> PORTA<span style="color: #339933;">,</span><span style="color: #0000ff;">2</span>  			<span style="color: #666666; font-style: italic;">; set her.</span>
  DELAY_MILLI <span style="color: #0000ff;">250</span>		<span style="color: #666666; font-style: italic;">; wait 1/4 sec</span>
  bcf PORTA<span style="color: #339933;">,</span><span style="color: #0000ff;">2</span>			<span style="color: #666666; font-style: italic;">; clear her!</span>
  DELAY_MILLI <span style="color: #0000ff;">250</span>		<span style="color: #666666; font-style: italic;">; wait 1/4 sec!!!!</span>
  <span style="color: #000000; font-weight: bold;">goto</span> LOOP_BEGIN		<span style="color: #666666; font-style: italic;">; forever... :o</span>
&nbsp;
 <span style="color: #000000; font-weight: bold;">end</span></pre></div></div>

<p>MAIN is our label for the beginning of the code, jumped to by the first line up @ org 0. BANK1 gets us into BANK 1 so we can set our bit direction, we clear bit 2 of TRISA making bit 2 of PORTA our output pin, then we hop back to BANK 0&#8230;</p>
<p>Then our introductory programming teachers worst nightmare, a purposely created infinite loop. We label the beginning, then set our pin high, shutting off the LED (as you&#8217;ll see in the wiring diagram). We wait 250ms via our handy delay function, then clear the bit, turning the LED on, we wait again and loop ad nauseum.</p>
<p>&#8216;end&#8217; tells the assembler to give up&#8230;</p>
<h3>Building</h3>
<p>Alright, so we have our program, we run the assembler by clicking the weird funnel icon or by going to Project -&gt; Build Node (or All). It&#8217;ll crunch and come up with no errors (of course).  Then just toss it into the programmer and feed the chip your tasty code.</p>
<h3>Schematic</h3>
<div id="attachment_225" class="wp-caption alignright" style="width: 160px"><a href="http://www.veys.com/wp-content/uploads/2008/07/pic16_blinker.jpg" rel="lightbox[120]"><img class="size-thumbnail wp-image-225" title="The assembled circuit" src="http://www.veys.com/wp-content/uploads/2008/07/pic16_blinker-150x150.jpg" alt="The assembled circuit" width="150" height="150" /></a><p class="wp-caption-text">The assembled circuit</p></div>
<p>Wire up the circuit as in the schematic at the top of the page.  Hopefully it illustrates to you why the LED is on when the bit is off, and off when the bit is on&#8230; The LED is a typical ~2V yellow LED&#8230;  Wired up it should look something like the image.</p>
<h3>Running</h3>
<p>Hook up +5V and Gnd, and fire it up! If everything is set up correctly you&#8217;ll get a steady blinking LED!</p>
<h3>Something to try</h3>
<p>Connect a momentary switch to the _MCLR line, wired to Ground on the other side. Pushing the button will reset the chip, releasing it will start it over from the beginning of the program, of course it will do the same stuff, but this demonstrates how the reset buttons work. I also highly recommend changing the code to add a more interesting blink pattern, longer/shorter delays, and other stuff to get used to modifying code&#8230;</p>
<h3>Downloads</h3>
<ul>
<li><a href="http://www.veys.com/wp-content/uploads/2008/07/busyblinker.zip">Source Code</a> (zip)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://veys.com/2002/08/21/pic-led-blinker-busy-wait/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  veys.com/tag/led/feed/ ) in 0.75291 seconds, on Feb 6th, 2012 at 7:52 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 6th, 2012 at 7:54 am UTC -->
