<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gregory+McGlynn</id>
	<title>Mech - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gregory+McGlynn"/>
	<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php/Special:Contributions/Gregory_McGlynn"/>
	<updated>2026-04-28T16:39:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=18416</id>
		<title>USB communication with PC</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=18416"/>
		<updated>2010-05-27T07:30:04Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some PIC models have built-in USB transceivers that make it simple to connect the PIC to a computer via USB. One such PIC is the [[PIC 18f4550]], which is similar to the 18f4520 in almost all respects, except that it has hardware support for USB built into it. The 18f4550 will work just fine in one of the [[4520_Board_intro|PIC protoboards]]. &lt;br /&gt;
&lt;br /&gt;
USB software for the PC tends to be OS-specific. &amp;#039;&amp;#039;&amp;#039;This article currently assumes you&amp;#039;re running Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== The USB protocol ==&lt;br /&gt;
USB is a pretty complex protocol with a long specification, but it&amp;#039;s not necessary to understand every part of it to use it. It&amp;#039;s enough to know what wires to hook up and what software libraries to include in your code.&lt;br /&gt;
&lt;br /&gt;
Wikipedia has a detailed and informative [http://en.wikipedia.org/wiki/Usb page on USB]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connectors ===&lt;br /&gt;
USB connectors have four leads; the pictures on Wikipedia show which is which on standard connectors. If you cut open a USB cable, the colors will also tell you which wire is which:&lt;br /&gt;
* +5V (red): the host (computer) provides up to 500mA of current at 5V that you can use for power. If your PIC is self-powered, though, make sure you don&amp;#039;t connect the two +5V sources or bad things may happen.&lt;br /&gt;
* GND (black): ground; make sure you do connect this to your PIC&amp;#039;s ground.&lt;br /&gt;
* D+ (green) and D- (white): data is transmitted on these lines. The exact protocol is complicated and you probably don&amp;#039;t need to know the details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB with the PIC 18F4550 ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
On the 18f4550, the D+ line connects to pin RC5 and the D- line to pin RC4. The ground line of course connects to ground.&lt;br /&gt;
&lt;br /&gt;
Additionally pin 18 on the PIC, called Vusb, should have a capacitor to ground. Try 220 or 470nF.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
On the software side you have some choices. Probably the simplest thing to do is use a preexisting software library that makes the USB connection look like an [[PIC RS232|RS232 connection]]. The CCS compiler has a CDC library that provides functions like &amp;#039;&amp;#039;usb_cdc_getc&amp;#039;&amp;#039; or &amp;#039;&amp;#039;usb_cdc_putc&amp;#039;&amp;#039; that work over USB exactly like regular &amp;#039;&amp;#039;getc&amp;#039;&amp;#039; and &amp;#039;&amp;#039;putc&amp;#039;&amp;#039; work over RS232. CCS also provides a Windows driver for the PC that creates a virtual COM port that you can open in Matlab, Hyperterminal, or any other RS232-capable program and use to talk to the PIC. See [[USB communication with CCS]].&lt;br /&gt;
&lt;br /&gt;
Microchip provides a [[Microchip USB Framework|USB framework]] that works with its C18 compiler and its MPLAB development environment. See [[USB communication with C18 and MPLAB]].&lt;br /&gt;
&lt;br /&gt;
CCS also has an example where the PIC registers itself as a Human Interface Device (HID). USB mice and keyboards use HID. The advantage of this is that doesn&amp;#039;t require the user to install a special driver. The disadvantages are (a) the connection doesn&amp;#039;t look like a simple RS232 link and (b) bandwidth is limited. A HID can only send messages to the computer once every millisecond, and can only send 64 bytes in each message, so the maximum data transfer rate is 64K bytes/second. In theory, USB can go up to 12M bits/second, so HID is fairly slow in comparison. &lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also possible to create one&amp;#039;s own setup from scratch or by modifying a preexisting library. This probably takes some effort.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13469</id>
		<title>USB communication with C18 and MPLAB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13469"/>
		<updated>2009-06-11T13:28:13Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microchip publishes a USB Framework that consists of a number of files that contain code to handle the tedious parts of USB communication, with a few spots where user code can be included to build USB programs.&lt;br /&gt;
&lt;br /&gt;
This code uses Microchip&amp;#039;s CDC library to create a virtual COM port on the computer. Opening this COM port in Hyperterminal or some other terminal program should show numbers appearing once every second or so. The PIC is reading analog voltages from AN0 and writing them out to the terminal.&lt;br /&gt;
&lt;br /&gt;
CDC communication requires a driver on the PC end. You&amp;#039;ll need to download these two files and put them in a folder together somewhere: [[Media:Mchpcdc.inf]] and [[Media:Mchpcdc.cat]]. The first time you run this program on the PIC and plug in into the PC, Windows will need to set up a driver to be able to talk to the PIC. It will probably flounder around a bit and fail to find the driver. When you can, point it to the folder containing these two files and it should find them and set up the driver.&lt;br /&gt;
&lt;br /&gt;
CDC programs can operate in two modes: polling or interrupt. This choice comes from the fact that USB devices must continually monitor the connection to the host, looking for incoming data and handling the sending of data in the output queue. There are two ways to accomplish this: the program can either explicitly call a function periodically to handle USB tasks, or this can be done by a regularly scheduled interrupt. &lt;br /&gt;
&lt;br /&gt;
The framework provides two slots in which user code can be placed: the functions UserInit and ProcessIO. UserInit is called once at the beginning of the program to allow you to do some initialization. ProcessIO is called in a loop; each iteration should be very short and must be non-blocking, if you are using the polling structure. &lt;br /&gt;
&lt;br /&gt;
Below is an example program using the polling structure, showing just the UserInit and ProcessIO functions. &lt;br /&gt;
&lt;br /&gt;
You can download the full MPLAB project here. In the example project the UserInit and ProcessIO functions are jumbled in with a ton of other code in main.c, but you could move them off to their own .c file. Note: this MPLAB project is configured to work with the [[USB Bootloading|USB HID bootloader]]. Using it without a bootloader or with another bootloader will require changes.&lt;br /&gt;
&lt;br /&gt;
The MPLAB project includes code for lots of other setups; Microchip sells demo boards with a variety of chips in them and this code is designed to be able to run on all of them by flipping a few compiler switches. So you&amp;#039;ll see stuff like &amp;quot;#if defined(PIC18F87J50_PIM)&amp;quot; or whatever; the only relevant one is PIC18F4553_SCOPE, and the include file &amp;quot;HardwareProfile - PIC18F4553 Scope.h&amp;quot;, which assume a [[PIC 18f4550|PIC18F4550 or 4553]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;UserInit&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;void UserInit(void)&lt;br /&gt;
{&lt;br /&gt;
    mInitAllLEDs();&lt;br /&gt;
&lt;br /&gt;
    //USER CODE!&lt;br /&gt;
    //ADC initialization:&lt;br /&gt;
    TRISAbits.TRISA0 = 1; //A0 is input&lt;br /&gt;
    ADCON0 = 1;           //enable ADC&lt;br /&gt;
    ADCON1 = 0b00001110;  //only AN0&lt;br /&gt;
    ADCON2 = 0b00010111;  //4 Tad, RC clock&lt;br /&gt;
}//end UserInit&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;ProcessIO&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;char output_buffer[100];&lt;br /&gt;
&lt;br /&gt;
int count = 0;&lt;br /&gt;
void ProcessIO(void)&lt;br /&gt;
{   &lt;br /&gt;
    BYTE numBytesRead;&lt;br /&gt;
&lt;br /&gt;
    //Blink the LEDs according to the USB device status&lt;br /&gt;
    BlinkUSBStatus();&lt;br /&gt;
    // User Application USB tasks&lt;br /&gt;
    if((USBDeviceState &amp;lt; CONFIGURED_STATE)||(USBSuspendControl==1)) return;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //Check if we&amp;#039;re ready to send more data. If not, we can&amp;#039;t wait until we are,&lt;br /&gt;
    //because blocking would screw up the rest of the USB tasks that are going on&lt;br /&gt;
    //in the background. If we&amp;#039;re not ready, we just return from this function and &lt;br /&gt;
    //we&amp;#039;ll loop back around in a bit.&lt;br /&gt;
    if(mUSBUSARTIsTxTrfReady()) {&lt;br /&gt;
        count++;&lt;br /&gt;
        if(count == 10000) {            //this happens every second or so&lt;br /&gt;
            ADCON0bits.GO_DONE = 1;     //initiate ADC conversion&lt;br /&gt;
            while(ADCON0bits.GO_DONE);  //wait for ADC to finish&lt;br /&gt;
&lt;br /&gt;
            //put the result of the ADC conversion in a string:&lt;br /&gt;
            sprintf(output_buffer, (const rom far char *)&amp;quot;%u\r\n&amp;quot;, ADRESH);&lt;br /&gt;
&lt;br /&gt;
            //queues our message up to be sent&lt;br /&gt;
            putsUSBUSART(output_buffer);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    //this needs to be called periodically in order for stuff to get sent out:&lt;br /&gt;
    CDCTxService();&lt;br /&gt;
&lt;br /&gt;
}		//end ProcessIO&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Mchpcdc.inf&amp;diff=13468</id>
		<title>File:Mchpcdc.inf</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Mchpcdc.inf&amp;diff=13468"/>
		<updated>2009-06-11T13:25:32Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Mchpcdc.cat&amp;diff=13467</id>
		<title>File:Mchpcdc.cat</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Mchpcdc.cat&amp;diff=13467"/>
		<updated>2009-06-11T13:25:22Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13466</id>
		<title>USB communication with C18 and MPLAB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13466"/>
		<updated>2009-06-11T13:22:23Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microchip publishes a USB Framework that consists of a number of files that contain code to handle the tedious parts of USB communication, with a few spots where user code can be included to build USB programs.&lt;br /&gt;
&lt;br /&gt;
This code uses Microchip&amp;#039;s CDC library to create a virtual COM port on the computer. Opening this COM port in Hyperterminal or some other terminal program should show numbers appearing once every second or so. The PIC is reading analog voltages from AN0 and writing them out to the terminal.&lt;br /&gt;
&lt;br /&gt;
CDC programs can operate in two modes: polling or interrupt. This choice comes from the fact that USB devices must continually monitor the connection to the host, looking for incoming data and handling the sending of data in the output queue. There are two ways to accomplish this: the program can either explicitly call a function periodically to handle USB tasks, or this can be done by a regularly scheduled interrupt. &lt;br /&gt;
&lt;br /&gt;
The framework provides two slots in which user code can be placed: the functions UserInit and ProcessIO. UserInit is called once at the beginning of the program to allow you to do some initialization. ProcessIO is called in a loop; each iteration should be very short and must be non-blocking, if you are using the polling structure. &lt;br /&gt;
&lt;br /&gt;
Below is an example program using the polling structure, showing just the UserInit and ProcessIO functions. &lt;br /&gt;
&lt;br /&gt;
You can download the full MPLAB project here. Note: this MPLAB project is configured to work with the [[USB Bootloading|USB HID bootloader]]. Using it without a bootloader or with another bootloader will require changes.&lt;br /&gt;
&lt;br /&gt;
The MPLAB project includes code for lots of other setups; Microchip sells demo boards with a variety of chips in them and this code is designed to be able to run on all of them by flipping a few compiler switches. So you&amp;#039;ll see stuff like &amp;quot;#if defined(PIC18F87J50_PIM)&amp;quot; or whatever; the only relevant one is PIC18F4553_SCOPE, and the include file &amp;quot;HardwareProfile - PIC18F4553 Scope.h&amp;quot;, which assume a [[PIC 18f4550|PIC18F4550 or 4553]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;UserInit&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;void UserInit(void)&lt;br /&gt;
{&lt;br /&gt;
    mInitAllLEDs();&lt;br /&gt;
&lt;br /&gt;
    //USER CODE!&lt;br /&gt;
    //ADC initialization:&lt;br /&gt;
    TRISAbits.TRISA0 = 1; //A0 is input&lt;br /&gt;
    ADCON0 = 1;           //enable ADC&lt;br /&gt;
    ADCON1 = 0b00001110;  //only AN0&lt;br /&gt;
    ADCON2 = 0b00010111;  //4 Tad, RC clock&lt;br /&gt;
}//end UserInit&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;ProcessIO&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;char output_buffer[100];&lt;br /&gt;
&lt;br /&gt;
int count = 0;&lt;br /&gt;
void ProcessIO(void)&lt;br /&gt;
{   &lt;br /&gt;
    BYTE numBytesRead;&lt;br /&gt;
&lt;br /&gt;
    //Blink the LEDs according to the USB device status&lt;br /&gt;
    BlinkUSBStatus();&lt;br /&gt;
    // User Application USB tasks&lt;br /&gt;
    if((USBDeviceState &amp;lt; CONFIGURED_STATE)||(USBSuspendControl==1)) return;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //Check if we&amp;#039;re ready to send more data. If not, we can&amp;#039;t wait until we are,&lt;br /&gt;
    //because blocking would screw up the rest of the USB tasks that are going on&lt;br /&gt;
    //in the background. If we&amp;#039;re not ready, we just return from this function and &lt;br /&gt;
    //we&amp;#039;ll loop back around in a bit.&lt;br /&gt;
    if(mUSBUSARTIsTxTrfReady()) {&lt;br /&gt;
        count++;&lt;br /&gt;
        if(count == 10000) {            //this happens every second or so&lt;br /&gt;
            ADCON0bits.GO_DONE = 1;     //initiate ADC conversion&lt;br /&gt;
            while(ADCON0bits.GO_DONE);  //wait for ADC to finish&lt;br /&gt;
&lt;br /&gt;
            //put the result of the ADC conversion in a string:&lt;br /&gt;
            sprintf(output_buffer, (const rom far char *)&amp;quot;%u\r\n&amp;quot;, ADRESH);&lt;br /&gt;
&lt;br /&gt;
            //queues our message up to be sent&lt;br /&gt;
            putsUSBUSART(output_buffer);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    //this needs to be called periodically in order for stuff to get sent out:&lt;br /&gt;
    CDCTxService();&lt;br /&gt;
&lt;br /&gt;
}		//end ProcessIO&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13465</id>
		<title>USB communication with PC</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13465"/>
		<updated>2009-06-11T13:07:17Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some PIC models have built-in USB transceivers that make it simple to connect the PIC to a computer via USB. One such PIC is the [[PIC 18f4550]], which is similar to the 18f4520 in almost all respects, except that it has hardware support for USB built into it. The 18f4550 will work just fine in one of the [[4520_Board_intro|PIC protoboards]]. &lt;br /&gt;
&lt;br /&gt;
USB software for the PC tends to be OS-specific. &amp;#039;&amp;#039;&amp;#039;This article currently assumes you&amp;#039;re running Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== The USB protocol ==&lt;br /&gt;
USB is a pretty complex protocol with a long specification, but it&amp;#039;s not necessary to understand every part of it to use it. It&amp;#039;s enough to know what wires to hook up and what software libraries to include in your code.&lt;br /&gt;
&lt;br /&gt;
Wikipedia has a detailed and informative [http://en.wikipedia.org/wiki/Usb page on USB]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connectors ===&lt;br /&gt;
USB connectors have four leads; the pictures on Wikipedia show which is which on standard connectors.&lt;br /&gt;
* +5V: the host (computer) provides up to 500mA of current at 5V that you can use for power. If your PIC is self-powered, though, make sure you don&amp;#039;t connect the two +5V sources or bad things may happen.&lt;br /&gt;
* GND: ground; make sure you do connect this to your PIC&amp;#039;s ground.&lt;br /&gt;
* D+ and D-: data is transmitted on these lines. The exact protocol is complicated and you probably don&amp;#039;t need to know the details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB with the PIC 18F4550 ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
On the 18f4550, the D+ line connects to pin RC5 and the D- line to pin RC4. The ground line of course connects to ground.&lt;br /&gt;
&lt;br /&gt;
Additionally pin 18, called Vusb, should have a capacitor to ground. Try 220 or 470nF.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
On the software side you have some choices. Probably the simplest thing to do is use a preexisting software library that makes the USB connection look like an [[PIC RS232|RS232 connection]]. The CCS compiler has a CDC library that provides functions like &amp;#039;&amp;#039;usb_cdc_getc&amp;#039;&amp;#039; or &amp;#039;&amp;#039;usb_cdc_putc&amp;#039;&amp;#039; that work over USB exactly like regular &amp;#039;&amp;#039;getc&amp;#039;&amp;#039; and &amp;#039;&amp;#039;putc&amp;#039;&amp;#039; work over RS232. CCS also provides a Windows driver for the PC that creates a virtual COM port that you can open in Matlab, Hyperterminal, or any other RS232-capable program and use to talk to the PIC. See [[USB communication with CCS]].&lt;br /&gt;
&lt;br /&gt;
Microchip provides a [[Microchip USB Framework|USB framework]] that works with its C18 compiler and its MPLAB development environment. See [[USB communication with C18 and MPLAB]].&lt;br /&gt;
&lt;br /&gt;
CCS also has an example where the PIC registers itself as a Human Interface Device (HID). USB mice and keyboards use HID. The advantage of this is that doesn&amp;#039;t require the user to install a special driver. The disadvantages are (a) the connection doesn&amp;#039;t look like a simple RS232 link and (b) bandwidth is limited. A HID can only send messages to the computer once every millisecond, and can only send 64 bytes in each message, so the maximum data transfer rate is 64K bytes/second. In theory, USB can go up to 12M bits/second, so HID is fairly slow in comparison. &lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also possible to create one&amp;#039;s own setup from scratch or by modifying a preexisting library. This probably takes some effort.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13464</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13464"/>
		<updated>2009-06-11T13:04:16Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows. The provided code is intended to be run on a [[PIC 18f4550|PIC18F4550 or 4553]] with a 20Mhz oscillator.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like a [[PIC 18f4550]]. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: if you&amp;#039;re going to load programs onto a PIC with a bootloader, you need to put some special instructions in the PIC code to make it work. See the &amp;quot;Compiling for a bootloader&amp;quot; section.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== CDC Bootloader ==&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested. The bootloader is a slightly modified version of one supplied by Microchip; the changes allow the compiled hex file to fit within the first 0x800 bytes program memory.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. These pins can be easily changed in the bootloader source code. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== HID Bootloader ==&lt;br /&gt;
&lt;br /&gt;
A HID (Human Interface Device) bootloader has the advantage that it doesn&amp;#039;t require any driver installation on the programming computer. Once the bootloader is programmed onto the PIC and the PIC is plugged into the PC, your computer should be able to handle the rest of the setup automatically. A HID bootloader is supplied with the [[Microchip USB Framework]]. This is a slightly modified version of the original HID bootloader project from Microchip. The original project is designed to fit within the first 0x1000 bytes of program memory, but due to changes in the compiler will no longer compile into that space; the modified version goes int he first 0x1100 bytes.&lt;br /&gt;
&lt;br /&gt;
=== PIC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PIC hex file here: [[Media:HID_Bootloader_PIC18_Non_J.hex]].&lt;br /&gt;
&lt;br /&gt;
You can download the full MPLAB project for the PIC program here: [[Media:Mplab-usb-bootloader.zip]]. &lt;br /&gt;
&lt;br /&gt;
=== PC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PC program here (it comes as part of the [[Microchip USB Framework]]): [[Media:HIDBootLoader.zip]]. Unzip the downloaded .zip file to get the HIDBootLoader.exe executable. Running this requires a sufficiently recent version of the .NET Framework, which you may not have if you are running XP or earlier versions of Windows. You can download a sufficiently recent version here (the install takes a while): [http://www.microsoft.com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&amp;amp;displaylang=en .NET Framework download].&lt;br /&gt;
&lt;br /&gt;
When the program is running it should automatically detect when you attach the PIC (if the PIC has been properly programmed). To program the PIC click &amp;quot;Open Hex File,&amp;quot; and browse your compiled hex file. Then click &amp;quot;Program/Verify&amp;quot; and the bootloader should, after a few seconds, report that it has successfully erase, programmed, and verified the PIC. After that you can reset the PIC and it should run your program.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
Like the CDC bootloader, you must have a button wired up to indicate when the PIC should start up in bootloader mode. This bootloader looks at pin RC4; if RC4 is low on reset, the bootloader starts, otherwise the user program starts. The bootloader will use pins D0 and D1 to indicate connection state: leds hooked up to these pins will flash alternately when the connection has been established with the PC. Again, these pins can easily be changed in the bootloader source code.&lt;br /&gt;
&lt;br /&gt;
Note that the first time you plug the PIC into the PC and start it up in bootloader mode, it will take a few seconds for the PC to initialize everything before the lights start flashing, but after that the process should be pretty fast.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Compiling for a bootloader ==&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader (rather than overwriting it). The CDC bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory), while the HID bootloader goes from 0x0000 to 0x10FF (these are hexadecimal numbers). Your program therefore needs to start at address 0x800 or 0x1100, depending on which bootloader you&amp;#039;re using, and not touch the memory from 0x000 to 0x7FF. &lt;br /&gt;
&lt;br /&gt;
With CCS you can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CDC bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x1100, interrupt=0x1108)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x10FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;MPLAB/C18:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
With MPLAB/C18 the required code is a bit longer. So as not to clutter up this page, it&amp;#039;s on a separate one: see [[Compiling for a bootloader in MPLAB]].&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Compiling_for_a_bootloader_in_MPLAB&amp;diff=13463</id>
		<title>Compiling for a bootloader in MPLAB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Compiling_for_a_bootloader_in_MPLAB&amp;diff=13463"/>
		<updated>2009-06-11T13:02:45Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Compiling a program that will be loaded using a bootloader requires a lot of extra code in MPLAB. Basically this code is doing two things:&lt;br /&gt;
*&amp;#039;&amp;#039;Vector remapping:&amp;#039;&amp;#039; Resets, high-priority interrupts, and low-priority interrupts usually make the PIC start executing code at addresses 0x00, 0x08, and 0x18 respectively. However, this is the domain of the bootloader, which is sitting in this first region of memory. So some &amp;quot;remapping&amp;quot; goes on, as explained in the comments to the first chunk of code below.&lt;br /&gt;
*&amp;#039;&amp;#039;Linker script:&amp;#039;&amp;#039; When a hex file is compiled from a source, it contains information about where in program memory it should be written. By default it starts at address 0x00 and continues as far as it needs to go, but this would overwrite the bootloader. So you need something to tell MPLAB where in memory it &amp;#039;&amp;#039;can&amp;#039;&amp;#039; put code; this is done by a &amp;#039;&amp;#039;&amp;#039;linker script&amp;#039;&amp;#039;&amp;#039;. There&amp;#039;s an example of one below.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;All this code assumes you are using the HID bootloader found [[USB bootloading|here]].&amp;#039;&amp;#039;&amp;#039; That bootloader takes up memory up to address 0x10FF (hexadecimal). User code starts at 0x1100. If you are using a bootloader that takes up a different amount of space, such as the CDC bootloader (which only takes up to 0x7FF), you will need to change some numbers. All mentions of numbers like 0x10FF, 0x1100, 0x1108, or 0x1118 will need to be replaced by numbers like 0x7FF, 0x800, 0x808, and 0x818 respectively. &lt;br /&gt;
&lt;br /&gt;
==Vector Remapping==&lt;br /&gt;
This code goes at the top of your code, or in an include file, and accomplishes the first bullet point above. Note the functions where you should place your interrupt-handling code, if you have any!&lt;br /&gt;
&amp;lt;pre&amp;gt;//The following lengthy and involved incantation sets things up so that resets and interrupt&lt;br /&gt;
//handling operate as they should, given the presence of the bootloader. &lt;br /&gt;
//Omitting this incantation will make the code stop working.&lt;br /&gt;
//If you are generating absolutely no interrupts, you can probably leave out just the stuff &lt;br /&gt;
//referring to interrupts.&lt;br /&gt;
//Comments are by Microchip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for&lt;br /&gt;
//the reset, high priority interrupt, and low priority interrupt&lt;br /&gt;
//vectors.  However, the current Microchip USB bootloader &lt;br /&gt;
//examples are intended to occupy addresses 0x00-0x7FF or&lt;br /&gt;
//0x00-0xFFF depending on which bootloader is used.  Therefore,&lt;br /&gt;
//the bootloader code remaps these vectors to new locations&lt;br /&gt;
//as indicated below.  This remapping is only necessary if you&lt;br /&gt;
//wish to program the hex file generated from this project with&lt;br /&gt;
//the USB bootloader.&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//If the output hex file is not programmed with&lt;br /&gt;
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.&lt;br /&gt;
//As a result, if an actual interrupt was enabled and occured, the PC would jump&lt;br /&gt;
//to 0x08 (or 0x18) and would begin executing &amp;quot;0xFFFF&amp;quot; (unprogrammed space).  This&lt;br /&gt;
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
//(0x1000 or 0x800, depending upon bootloader), and would execute the &amp;quot;goto _startup&amp;quot;.  This&lt;br /&gt;
//would effective reset the application.&lt;br /&gt;
&lt;br /&gt;
//To fix this situation, we should always deliberately place a &lt;br /&gt;
//&amp;quot;goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x08, and a&lt;br /&gt;
//&amp;quot;goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x18.  When the output&lt;br /&gt;
//hex file of this project is programmed with the bootloader, these sections do not&lt;br /&gt;
//get bootloaded (as they overlap the bootloader space).  If the output hex file is not&lt;br /&gt;
//programmed using the bootloader, then the below goto instructions do get programmed,&lt;br /&gt;
//and the hex file still works like normal.  The below section is only required to fix this&lt;br /&gt;
//scenario.	&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.&lt;br /&gt;
}	//This return will be a &amp;quot;retfie fast&amp;quot;, since this is in a #pragma interrupt section &lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.	&lt;br /&gt;
}	//This return will be a &amp;quot;retfie&amp;quot;, since this is in a #pragma interruptlow section &lt;br /&gt;
&lt;br /&gt;
//End incantation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a shorter version of the same thing, stripped of most explanatory comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void) { _asm goto _startup _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void) { _asm goto YourHighPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void) { _asm goto YourLowPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void) { _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void) { _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode() {&lt;br /&gt;
    //high priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode() {&lt;br /&gt;
    //low priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
If you wish to use the CDC bootloader with MPLAB source code, you only need to change three lines of the above, where the REMAPPED_VECTOR_ADDRESS constants are defined:&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x800&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x808&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x818&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Linker Script==&lt;br /&gt;
Here is a sample linker script. Save it in a file with a &amp;quot;.lkr&amp;quot; extension and include it in your MPLAB project. All MPLAB projects have a linker script. Often it&amp;#039;s just the default one provided by the C18 compiler, which this one replaces.&lt;br /&gt;
&amp;lt;pre&amp;gt;// Sample linker script for the PIC18F4550 processor&lt;br /&gt;
&lt;br /&gt;
LIBPATH .&lt;br /&gt;
&lt;br /&gt;
FILES c018i.o&lt;br /&gt;
FILES clib.lib&lt;br /&gt;
FILES p18f4550.lib  //change if you&amp;#039;re not using the 4550&lt;br /&gt;
&lt;br /&gt;
//non-bootloader lines:&lt;br /&gt;
CODEPAGE   NAME=boot       START=0x0               END=0x10FF         PROTECTED //don&amp;#039;t overwrite the bootloader&lt;br /&gt;
CODEPAGE   NAME=vectors    START=0x1100            END=0x1129         PROTECTED //put reset/interrupt vectors here&lt;br /&gt;
CODEPAGE   NAME=page       START=0x112A            END=0x7FFF                   //code goes after bootloader&lt;br /&gt;
&lt;br /&gt;
//the reset of these lines do something unrelated to the bootloader:&lt;br /&gt;
CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=config     START=0x300000          END=0x30000D       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=eedata     START=0xF00000          END=0xF000FF       PROTECTED&lt;br /&gt;
&lt;br /&gt;
ACCESSBANK NAME=accessram  START=0x0            END=0x5F&lt;br /&gt;
DATABANK   NAME=gpr0       START=0x60           END=0xFF&lt;br /&gt;
DATABANK   NAME=gpr1       START=0x100          END=0x1FF&lt;br /&gt;
DATABANK   NAME=gpr2       START=0x200          END=0x2FF&lt;br /&gt;
DATABANK   NAME=gpr3       START=0x300          END=0x3FF&lt;br /&gt;
DATABANK   NAME=usb4       START=0x400          END=0x4FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb5       START=0x500          END=0x5FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb6       START=0x600          END=0x6FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb7       START=0x700          END=0x7FF          PROTECTED&lt;br /&gt;
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED&lt;br /&gt;
&lt;br /&gt;
SECTION    NAME=CONFIG     ROM=config&lt;br /&gt;
&lt;br /&gt;
STACK SIZE=0x100 RAM=gpr3&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Compiling_for_a_bootloader_in_MPLAB&amp;diff=13462</id>
		<title>Compiling for a bootloader in MPLAB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Compiling_for_a_bootloader_in_MPLAB&amp;diff=13462"/>
		<updated>2009-06-11T13:01:47Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Compiling a program that will be loaded using a bootloader requires a lot of extra code in MPLAB. Basically this code is doing two things:&lt;br /&gt;
*&amp;#039;&amp;#039;Vector remapping:&amp;#039;&amp;#039; Resets, high-priority interrupts, and low-priority interrupts usually make the PIC start executing code at addresses 0x00, 0x08, and 0x18 respectively. However, this is the domain of the bootloader, which is sitting in this first region of memory. So some &amp;quot;remapping&amp;quot; goes on, as explained in the comments to the first chunk of code below.&lt;br /&gt;
*&amp;#039;&amp;#039;Linker script:&amp;#039;&amp;#039; When a hex file is compiled from a source, it contains information about where in program memory it should be written. By default it starts at address 0x00 and continues as far as it needs to go, but this would overwrite the bootloader. So you need something to tell MPLAB where in memory it &amp;#039;&amp;#039;can&amp;#039;&amp;#039; put code; this is done by a &amp;#039;&amp;#039;&amp;#039;linker script&amp;#039;&amp;#039;&amp;#039;. There&amp;#039;s an example of one below.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;All this code assumes you are using the HID bootloader found [[USB bootloading|here]].&amp;#039;&amp;#039;&amp;#039; That bootloader takes up memory up to address 0x10FF (hexadecimal). User code starts at 0x1100. If you are using a bootloader that takes up a different amount of space, such as the CDC bootloader (which only takes up to 0x7FF), you will need to change some numbers. All mentions of numbers like 0x10FF, 0x1100, 0x1108, or 0x1118 will need to be replaced by numbers like 0x7FF, 0x800, 0x808, and 0x818 respectively. &lt;br /&gt;
&lt;br /&gt;
==Vector Remapping==&lt;br /&gt;
This code goes at the top of your code, or in an include file, and accomplishes the first bullet point above. Note the functions where you should place your interrupt-handling code, if you have any!&lt;br /&gt;
&amp;lt;pre&amp;gt;//The following lengthy and involved incantation sets things up so that resets and interrupt&lt;br /&gt;
//handling operate as they should, given the presence of the bootloader. &lt;br /&gt;
//Omitting this incantation will make the code stop working.&lt;br /&gt;
//If you are generating absolutely no interrupts, you can probably leave out just the stuff &lt;br /&gt;
//referring to interrupts.&lt;br /&gt;
//Comments are by Microchip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for&lt;br /&gt;
//the reset, high priority interrupt, and low priority interrupt&lt;br /&gt;
//vectors.  However, the current Microchip USB bootloader &lt;br /&gt;
//examples are intended to occupy addresses 0x00-0x7FF or&lt;br /&gt;
//0x00-0xFFF depending on which bootloader is used.  Therefore,&lt;br /&gt;
//the bootloader code remaps these vectors to new locations&lt;br /&gt;
//as indicated below.  This remapping is only necessary if you&lt;br /&gt;
//wish to program the hex file generated from this project with&lt;br /&gt;
//the USB bootloader.&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//If the output hex file is not programmed with&lt;br /&gt;
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.&lt;br /&gt;
//As a result, if an actual interrupt was enabled and occured, the PC would jump&lt;br /&gt;
//to 0x08 (or 0x18) and would begin executing &amp;quot;0xFFFF&amp;quot; (unprogrammed space).  This&lt;br /&gt;
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
//(0x1000 or 0x800, depending upon bootloader), and would execute the &amp;quot;goto _startup&amp;quot;.  This&lt;br /&gt;
//would effective reset the application.&lt;br /&gt;
&lt;br /&gt;
//To fix this situation, we should always deliberately place a &lt;br /&gt;
//&amp;quot;goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x08, and a&lt;br /&gt;
//&amp;quot;goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x18.  When the output&lt;br /&gt;
//hex file of this project is programmed with the bootloader, these sections do not&lt;br /&gt;
//get bootloaded (as they overlap the bootloader space).  If the output hex file is not&lt;br /&gt;
//programmed using the bootloader, then the below goto instructions do get programmed,&lt;br /&gt;
//and the hex file still works like normal.  The below section is only required to fix this&lt;br /&gt;
//scenario.	&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.&lt;br /&gt;
}	//This return will be a &amp;quot;retfie fast&amp;quot;, since this is in a #pragma interrupt section &lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.	&lt;br /&gt;
}	//This return will be a &amp;quot;retfie&amp;quot;, since this is in a #pragma interruptlow section &lt;br /&gt;
&lt;br /&gt;
//End incantation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a shorter version of the same thing, stripped of most explanatory comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void) { _asm goto _startup _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void) { _asm goto YourHighPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void) { _asm goto YourLowPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void) { _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void) { _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode() {&lt;br /&gt;
    //high priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode() {&lt;br /&gt;
    //low priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
If you wish to use the CDC bootloader with MPLAB source code, you only need to change three lines of the above, where the REMAPPED_VECTOR_ADDRESS constants are defined:&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x800&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x808&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x818&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Linker Script==&lt;br /&gt;
Here is a sample linker script. Save it in a file with a &amp;quot;.lkr&amp;quot; extension and include it in your MPLAB project:&lt;br /&gt;
&amp;lt;pre&amp;gt;// Sample linker script for the PIC18F4550 processor&lt;br /&gt;
&lt;br /&gt;
LIBPATH .&lt;br /&gt;
&lt;br /&gt;
FILES c018i.o&lt;br /&gt;
FILES clib.lib&lt;br /&gt;
FILES p18f4550.lib  //change if you&amp;#039;re not using the 4550&lt;br /&gt;
&lt;br /&gt;
//non-bootloader lines:&lt;br /&gt;
CODEPAGE   NAME=boot       START=0x0               END=0x10FF         PROTECTED //don&amp;#039;t overwrite the bootloader&lt;br /&gt;
CODEPAGE   NAME=vectors    START=0x1100            END=0x1129         PROTECTED //put reset/interrupt vectors here&lt;br /&gt;
CODEPAGE   NAME=page       START=0x112A            END=0x7FFF                   //code goes after bootloader&lt;br /&gt;
&lt;br /&gt;
//the reset of these lines do something unrelated to the bootloader:&lt;br /&gt;
CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=config     START=0x300000          END=0x30000D       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=eedata     START=0xF00000          END=0xF000FF       PROTECTED&lt;br /&gt;
&lt;br /&gt;
ACCESSBANK NAME=accessram  START=0x0            END=0x5F&lt;br /&gt;
DATABANK   NAME=gpr0       START=0x60           END=0xFF&lt;br /&gt;
DATABANK   NAME=gpr1       START=0x100          END=0x1FF&lt;br /&gt;
DATABANK   NAME=gpr2       START=0x200          END=0x2FF&lt;br /&gt;
DATABANK   NAME=gpr3       START=0x300          END=0x3FF&lt;br /&gt;
DATABANK   NAME=usb4       START=0x400          END=0x4FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb5       START=0x500          END=0x5FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb6       START=0x600          END=0x6FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb7       START=0x700          END=0x7FF          PROTECTED&lt;br /&gt;
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED&lt;br /&gt;
&lt;br /&gt;
SECTION    NAME=CONFIG     ROM=config&lt;br /&gt;
&lt;br /&gt;
STACK SIZE=0x100 RAM=gpr3&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Compiling_for_a_bootloader_in_MPLAB&amp;diff=13461</id>
		<title>Compiling for a bootloader in MPLAB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Compiling_for_a_bootloader_in_MPLAB&amp;diff=13461"/>
		<updated>2009-06-11T13:01:06Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Compiling a program that will be loaded using a bootloader requires a lot of extra code in MPLAB. Basically this code is doing two things:&lt;br /&gt;
*Resets, high-priority interrupts, and low-priority interrupts usually make the PIC start executing code at addresses 0x00, 0x08, and 0x18 respectively. However, this is the domain of the bootloader, which is sitting in this first region of memory. So some &amp;quot;remapping&amp;quot; goes on, as explained in the comments to the first chunk of code below.&lt;br /&gt;
*When a hex file is compiled from a source, it contains information about where in program memory it should be written. By default it starts at address 0x00 and continues as far as it needs to go, but this would overwrite the bootloader. So you need something to tell MPLAB where in memory it &amp;#039;&amp;#039;can&amp;#039;&amp;#039; put code; this is done by a &amp;#039;&amp;#039;&amp;#039;linker script&amp;#039;&amp;#039;&amp;#039;. There&amp;#039;s an example of one below.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;All this code assumes you are using the HID bootloader found [[USB bootloading|here]].&amp;#039;&amp;#039;&amp;#039; That bootloader takes up memory up to address 0x10FF (hexadecimal). User code starts at 0x1100. If you are using a bootloader that takes up a different amount of space, such as the CDC bootloader (which only takes up to 0x7FF), you will need to change some numbers. All mentions of numbers like 0x10FF, 0x1100, 0x1108, or 0x1118 will need to be replaced by numbers like 0x7FF, 0x800, 0x808, and 0x818 respectively. &lt;br /&gt;
&lt;br /&gt;
==Vector Remapping==&lt;br /&gt;
This code goes at the top of your code, or in an include file, and accomplishes the first bullet point above. Note the functions where you should place your interrupt-handling code, if you have any!&lt;br /&gt;
&amp;lt;pre&amp;gt;//The following lengthy and involved incantation sets things up so that resets and interrupt&lt;br /&gt;
//handling operate as they should, given the presence of the bootloader. &lt;br /&gt;
//Omitting this incantation will make the code stop working.&lt;br /&gt;
//If you are generating absolutely no interrupts, you can probably leave out just the stuff &lt;br /&gt;
//referring to interrupts.&lt;br /&gt;
//Comments are by Microchip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for&lt;br /&gt;
//the reset, high priority interrupt, and low priority interrupt&lt;br /&gt;
//vectors.  However, the current Microchip USB bootloader &lt;br /&gt;
//examples are intended to occupy addresses 0x00-0x7FF or&lt;br /&gt;
//0x00-0xFFF depending on which bootloader is used.  Therefore,&lt;br /&gt;
//the bootloader code remaps these vectors to new locations&lt;br /&gt;
//as indicated below.  This remapping is only necessary if you&lt;br /&gt;
//wish to program the hex file generated from this project with&lt;br /&gt;
//the USB bootloader.&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//If the output hex file is not programmed with&lt;br /&gt;
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.&lt;br /&gt;
//As a result, if an actual interrupt was enabled and occured, the PC would jump&lt;br /&gt;
//to 0x08 (or 0x18) and would begin executing &amp;quot;0xFFFF&amp;quot; (unprogrammed space).  This&lt;br /&gt;
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
//(0x1000 or 0x800, depending upon bootloader), and would execute the &amp;quot;goto _startup&amp;quot;.  This&lt;br /&gt;
//would effective reset the application.&lt;br /&gt;
&lt;br /&gt;
//To fix this situation, we should always deliberately place a &lt;br /&gt;
//&amp;quot;goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x08, and a&lt;br /&gt;
//&amp;quot;goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x18.  When the output&lt;br /&gt;
//hex file of this project is programmed with the bootloader, these sections do not&lt;br /&gt;
//get bootloaded (as they overlap the bootloader space).  If the output hex file is not&lt;br /&gt;
//programmed using the bootloader, then the below goto instructions do get programmed,&lt;br /&gt;
//and the hex file still works like normal.  The below section is only required to fix this&lt;br /&gt;
//scenario.	&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.&lt;br /&gt;
}	//This return will be a &amp;quot;retfie fast&amp;quot;, since this is in a #pragma interrupt section &lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.	&lt;br /&gt;
}	//This return will be a &amp;quot;retfie&amp;quot;, since this is in a #pragma interruptlow section &lt;br /&gt;
&lt;br /&gt;
//End incantation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a shorter version of the same thing, stripped of most explanatory comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void) { _asm goto _startup _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void) { _asm goto YourHighPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void) { _asm goto YourLowPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void) { _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void) { _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode() {&lt;br /&gt;
    //high priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode() {&lt;br /&gt;
    //low priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
If you wish to use the CDC bootloader with MPLAB source code, you only need to change three lines of the above, where the REMAPPED_VECTOR_ADDRESS constants are defined:&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x800&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x808&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x818&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Linker Script==&lt;br /&gt;
Here is a sample linker script. Save it in a file with a &amp;quot;.lkr&amp;quot; extension and include it in your MPLAB project:&lt;br /&gt;
&amp;lt;pre&amp;gt;// Sample linker script for the PIC18F4550 processor&lt;br /&gt;
&lt;br /&gt;
LIBPATH .&lt;br /&gt;
&lt;br /&gt;
FILES c018i.o&lt;br /&gt;
FILES clib.lib&lt;br /&gt;
FILES p18f4550.lib  //change if you&amp;#039;re not using the 4550&lt;br /&gt;
&lt;br /&gt;
//non-bootloader lines:&lt;br /&gt;
CODEPAGE   NAME=boot       START=0x0               END=0x10FF         PROTECTED //don&amp;#039;t overwrite the bootloader&lt;br /&gt;
CODEPAGE   NAME=vectors    START=0x1100            END=0x1129         PROTECTED //put reset/interrupt vectors here&lt;br /&gt;
CODEPAGE   NAME=page       START=0x112A            END=0x7FFF                   //code goes after bootloader&lt;br /&gt;
&lt;br /&gt;
//the reset of these lines do something unrelated to the bootloader:&lt;br /&gt;
CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=config     START=0x300000          END=0x30000D       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED&lt;br /&gt;
CODEPAGE   NAME=eedata     START=0xF00000          END=0xF000FF       PROTECTED&lt;br /&gt;
&lt;br /&gt;
ACCESSBANK NAME=accessram  START=0x0            END=0x5F&lt;br /&gt;
DATABANK   NAME=gpr0       START=0x60           END=0xFF&lt;br /&gt;
DATABANK   NAME=gpr1       START=0x100          END=0x1FF&lt;br /&gt;
DATABANK   NAME=gpr2       START=0x200          END=0x2FF&lt;br /&gt;
DATABANK   NAME=gpr3       START=0x300          END=0x3FF&lt;br /&gt;
DATABANK   NAME=usb4       START=0x400          END=0x4FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb5       START=0x500          END=0x5FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb6       START=0x600          END=0x6FF          PROTECTED&lt;br /&gt;
DATABANK   NAME=usb7       START=0x700          END=0x7FF          PROTECTED&lt;br /&gt;
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED&lt;br /&gt;
&lt;br /&gt;
SECTION    NAME=CONFIG     ROM=config&lt;br /&gt;
&lt;br /&gt;
STACK SIZE=0x100 RAM=gpr3&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13460</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13460"/>
		<updated>2009-06-11T12:46:04Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows. The provided code is intended to be run on a [[PIC 18f4550|PIC18F4550 or 4553]] with a 20Mhz oscillator.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like a [[PIC 18f4550]]. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: if you&amp;#039;re going to load programs onto a PIC with a bootloader, you need to put some special instructions in the PIC code to make it work. See the &amp;quot;Compiling for a bootloader&amp;quot; section.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== CDC Bootloader ==&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested. The bootloader is a slightly modified version of one supplied by Microchip; the changes allow the compiled hex file to fit within the first 0x800 bytes program memory.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. These pins can be easily changed in the bootloader source code. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== HID Bootloader ==&lt;br /&gt;
&lt;br /&gt;
A HID (Human Interface Device) bootloader has the advantage that it doesn&amp;#039;t require any driver installation on the programming computer. Once the bootloader is programmed onto the PIC and the PIC is plugged into the PC, your computer should be able to handle the rest of the setup automatically. A HID bootloader is supplied with the [[Microchip USB Framework]]. This is a slightly modified version of the original HID bootloader project from Microchip. The original project is designed to fit within the first 0x1000 bytes of program memory, but due to changes in the compiler will no longer compile into that space; the modified version goes int he first 0x1100 bytes.&lt;br /&gt;
&lt;br /&gt;
=== PIC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PIC hex file here: [[Media:HID_Bootloader_PIC18_Non_J.hex]].&lt;br /&gt;
&lt;br /&gt;
You can download the full MPLAB project for the PIC program here: [[Media:Mplab-usb-bootloader.zip]]. &lt;br /&gt;
&lt;br /&gt;
=== PC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PC program here (it comes as part of the [[Microchip USB Framework]]): [[Media:HIDBootLoader.zip]]. Unzip the downloaded .zip file to get the HIDBootLoader.exe executable. Running this requires a sufficiently recent version of the .NET Framework, which you may not have if you are running XP or earlier versions of Windows. You can download a sufficiently recent version here (the install takes a while): [http://www.microsoft.com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&amp;amp;displaylang=en .NET Framework download].&lt;br /&gt;
&lt;br /&gt;
When the program is running it should automatically detect when you attach the PIC (if the PIC has been properly programmed). To program the PIC click &amp;quot;Open Hex File,&amp;quot; and browse your compiled hex file. Then click &amp;quot;Program/Verify&amp;quot; and the bootloader should, after a few seconds, report that it has successfully erase, programmed, and verified the PIC. After that you can reset the PIC and it should run your program.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
Like the CDC bootloader, you must have a button wired up to indicate when the PIC should start up in bootloader mode. This bootloader looks at pin RC4; if RC4 is low on reset, the bootloader starts, otherwise the user program starts. The bootloader will use pins D0 and D1 to indicate connection state: leds hooked up to these pins will flash alternately when the connection has been established with the PC. Again, these pins can easily be changed in the bootloader source code.&lt;br /&gt;
&lt;br /&gt;
Note that the first time you plug the PIC into the PC and start it up in bootloader mode, it will take a few seconds for the PC to initialize everything before the lights start flashing, but after that the process should be pretty fast.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Compiling for a bootloader ==&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader (rather than overwriting it). The CDC bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory), while the HID bootloader goes from 0x0000 to 0x10FF (these are hexadecimal numbers). Your program therefore needs to start at address 0x800 or 0x1100, depending on which bootloader you&amp;#039;re using, and not touch the memory from 0x000 to 0x7FF. &lt;br /&gt;
&lt;br /&gt;
With CCS you can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CDC bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x1100, interrupt=0x1108)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x10FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With MPLAB/C18 the required code is a bit longer. So as not to clutter up this page, it&amp;#039;s on a separate one: see [[Compiling for a bootloader in MPLAB]].&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with MPLAB:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;//The following lengthy and involved incantation sets things up so that resets and interrupt&lt;br /&gt;
//handling operate as they should, given the presence of the bootloader. &lt;br /&gt;
//Omitting this incantation will make the code stop working.&lt;br /&gt;
//If you are generating absolutely no interrupts, you can probably leave out just the stuff &lt;br /&gt;
//referring to interrupts.&lt;br /&gt;
//Comments are by Microchip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for&lt;br /&gt;
//the reset, high priority interrupt, and low priority interrupt&lt;br /&gt;
//vectors.  However, the current Microchip USB bootloader &lt;br /&gt;
//examples are intended to occupy addresses 0x00-0x7FF or&lt;br /&gt;
//0x00-0xFFF depending on which bootloader is used.  Therefore,&lt;br /&gt;
//the bootloader code remaps these vectors to new locations&lt;br /&gt;
//as indicated below.  This remapping is only necessary if you&lt;br /&gt;
//wish to program the hex file generated from this project with&lt;br /&gt;
//the USB bootloader.&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//If the output hex file is not programmed with&lt;br /&gt;
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.&lt;br /&gt;
//As a result, if an actual interrupt was enabled and occured, the PC would jump&lt;br /&gt;
//to 0x08 (or 0x18) and would begin executing &amp;quot;0xFFFF&amp;quot; (unprogrammed space).  This&lt;br /&gt;
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
//(0x1000 or 0x800, depending upon bootloader), and would execute the &amp;quot;goto _startup&amp;quot;.  This&lt;br /&gt;
//would effective reset the application.&lt;br /&gt;
&lt;br /&gt;
//To fix this situation, we should always deliberately place a &lt;br /&gt;
//&amp;quot;goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x08, and a&lt;br /&gt;
//&amp;quot;goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x18.  When the output&lt;br /&gt;
//hex file of this project is programmed with the bootloader, these sections do not&lt;br /&gt;
//get bootloaded (as they overlap the bootloader space).  If the output hex file is not&lt;br /&gt;
//programmed using the bootloader, then the below goto instructions do get programmed,&lt;br /&gt;
//and the hex file still works like normal.  The below section is only required to fix this&lt;br /&gt;
//scenario.	&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.&lt;br /&gt;
}	//This return will be a &amp;quot;retfie fast&amp;quot;, since this is in a #pragma interrupt section &lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.	&lt;br /&gt;
}	//This return will be a &amp;quot;retfie&amp;quot;, since this is in a #pragma interruptlow section &lt;br /&gt;
&lt;br /&gt;
//End incantation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a shorter version of the same thing, stripped of most explanatory comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void) { _asm goto _startup _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void) { _asm goto YourHighPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void) { _asm goto YourLowPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void) { _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void) { _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode() {&lt;br /&gt;
    //high priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode() {&lt;br /&gt;
    //low priority interrupt code&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you wish to use the CDC bootloader with MPLAB source code, you only need to change three lines of the above, where the REMAPPED_VECTOR_ADDRESS constants are defined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x800&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x808&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x818&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Mplab-usb-bootloader.zip&amp;diff=13459</id>
		<title>File:Mplab-usb-bootloader.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Mplab-usb-bootloader.zip&amp;diff=13459"/>
		<updated>2009-06-11T12:43:15Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:HID_Bootloader_PIC18_Non_J.hex&amp;diff=13458</id>
		<title>File:HID Bootloader PIC18 Non J.hex</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:HID_Bootloader_PIC18_Non_J.hex&amp;diff=13458"/>
		<updated>2009-06-11T12:41:43Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13457</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13457"/>
		<updated>2009-06-11T12:40:36Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows. The provided code is intended to be run on a [[PIC 18f4550|PIC18F4550 or 4553]] with a 20Mhz oscillator.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like a [[PIC 18f4550]]. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: if you&amp;#039;re going to load programs onto a PIC with a bootloader, you need to put some special instructions in the PIC code to make it work. See the &amp;quot;Compiling for a bootloader&amp;quot; section.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== CDC Bootloader ==&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested. The bootloader is a slightly modified version of one supplied by Microchip; the changes allow the compiled hex file to fit within the first 0x800 bytes program memory.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. These pins can be easily changed in the bootloader source code. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== HID Bootloader ==&lt;br /&gt;
&lt;br /&gt;
A HID (Human Interface Device) bootloader has the advantage that it doesn&amp;#039;t require any driver installation on the programming computer. Once the bootloader is programmed onto the PIC and the PIC is plugged into the PC, your computer should be able to handle the rest of the setup automatically. A HID bootloader is supplied with the [[Microchip USB Framework]]. This is a slightly modified version of the original HID bootloader project from Microchip. The original project is designed to fit within the first 0x1000 bytes of program memory, but due to changes in the compiler will no longer compile into that space; the modified version goes int he first 0x1100 bytes.&lt;br /&gt;
&lt;br /&gt;
=== PIC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PIC hex file here.&lt;br /&gt;
You can download the full MPLAB project for the PIC program here. &lt;br /&gt;
&lt;br /&gt;
=== PC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PC program here (it comes as part of the [[Microchip USB Framework]]): [[Media:HIDBootLoader.zip]]. Unzip the downloaded .zip file to get the HIDBootLoader.exe executable. Running this requires a sufficiently recent version of the .NET Framework, which you may not have if you are running XP or earlier versions of Windows. You can download a sufficiently recent version here (the install takes a while): [http://www.microsoft.com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&amp;amp;displaylang=en .NET Framework download].&lt;br /&gt;
&lt;br /&gt;
When the program is running it should automatically detect when you attach the PIC (if the PIC has been properly programmed). To program the PIC click &amp;quot;Open Hex File,&amp;quot; and browse your compiled hex file. Then click &amp;quot;Program/Verify&amp;quot; and the bootloader should, after a few seconds, report that it has successfully erase, programmed, and verified the PIC. After that you can reset the PIC and it should run your program.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
Like the CDC bootloader, you must have a button wired up to indicate when the PIC should start up in bootloader mode. This bootloader looks at pin RC4; if RC4 is low on reset, the bootloader starts, otherwise the user program starts. The bootloader will use pins D0 and D1 to indicate connection state: leds hooked up to these pins will flash alternately when the connection has been established with the PC. Again, these pins can easily be changed in the bootloader source code.&lt;br /&gt;
&lt;br /&gt;
Note that the first time you plug the PIC into the PC and start it up in bootloader mode, it will take a few seconds for the PC to initialize everything before the lights start flashing, but after that the process should be pretty fast.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Compiling for a bootloader ==&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader (rather than overwriting it). The CDC bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory), while the HID bootloader goes from 0x0000 to 0x10FF (these are hexadecimal numbers). Your program therefore needs to start at address 0x800 or 0x1100, depending on which bootloader you&amp;#039;re using, and not touch the memory from 0x000 to 0x7FF. &lt;br /&gt;
&lt;br /&gt;
With CCS you can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CDC bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x1100, interrupt=0x1108)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x10FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With MPLAB/C18 the required code is a bit longer:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with MPLAB:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;//The following lengthy and involved incantation sets things up so that resets and interrupt&lt;br /&gt;
//handling operate as they should, given the presence of the bootloader. &lt;br /&gt;
//Omitting this incantation will make the code stop working.&lt;br /&gt;
//If you are generating absolutely no interrupts, you can probably leave out just the stuff &lt;br /&gt;
//referring to interrupts.&lt;br /&gt;
//Comments are by Microchip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for&lt;br /&gt;
//the reset, high priority interrupt, and low priority interrupt&lt;br /&gt;
//vectors.  However, the current Microchip USB bootloader &lt;br /&gt;
//examples are intended to occupy addresses 0x00-0x7FF or&lt;br /&gt;
//0x00-0xFFF depending on which bootloader is used.  Therefore,&lt;br /&gt;
//the bootloader code remaps these vectors to new locations&lt;br /&gt;
//as indicated below.  This remapping is only necessary if you&lt;br /&gt;
//wish to program the hex file generated from this project with&lt;br /&gt;
//the USB bootloader.&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//If the output hex file is not programmed with&lt;br /&gt;
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.&lt;br /&gt;
//As a result, if an actual interrupt was enabled and occured, the PC would jump&lt;br /&gt;
//to 0x08 (or 0x18) and would begin executing &amp;quot;0xFFFF&amp;quot; (unprogrammed space).  This&lt;br /&gt;
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
//(0x1000 or 0x800, depending upon bootloader), and would execute the &amp;quot;goto _startup&amp;quot;.  This&lt;br /&gt;
//would effective reset the application.&lt;br /&gt;
&lt;br /&gt;
//To fix this situation, we should always deliberately place a &lt;br /&gt;
//&amp;quot;goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x08, and a&lt;br /&gt;
//&amp;quot;goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x18.  When the output&lt;br /&gt;
//hex file of this project is programmed with the bootloader, these sections do not&lt;br /&gt;
//get bootloaded (as they overlap the bootloader space).  If the output hex file is not&lt;br /&gt;
//programmed using the bootloader, then the below goto instructions do get programmed,&lt;br /&gt;
//and the hex file still works like normal.  The below section is only required to fix this&lt;br /&gt;
//scenario.	&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.&lt;br /&gt;
}	//This return will be a &amp;quot;retfie fast&amp;quot;, since this is in a #pragma interrupt section &lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.	&lt;br /&gt;
}	//This return will be a &amp;quot;retfie&amp;quot;, since this is in a #pragma interruptlow section &lt;br /&gt;
&lt;br /&gt;
//End incantation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a shorter version of the same thing, stripped of most explanatory comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void) { _asm goto _startup _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void) { _asm goto YourHighPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void) { _asm goto YourLowPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void) { _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void) { _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode() {&lt;br /&gt;
    //high priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode() {&lt;br /&gt;
    //low priority interrupt code&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you wish to use the CDC bootloader with MPLAB source code, you only need to change three lines of the above, where the REMAPPED_VECTOR_ADDRESS constants are defined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x800&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x808&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x818&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:HIDBootLoader.zip&amp;diff=13456</id>
		<title>File:HIDBootLoader.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:HIDBootLoader.zip&amp;diff=13456"/>
		<updated>2009-06-11T12:35:26Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: Unzip this to obtain HIDBootLoader.exe, the bootloader executable. This is a Windows program and requires a sufficiently recent version of the .NET Framework to run. If you are running XP you may need to download and install a newer version; see the [[USB&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Unzip this to obtain HIDBootLoader.exe, the bootloader executable. This is a Windows program and requires a sufficiently recent version of the .NET Framework to run. If you are running XP you may need to download and install a newer version; see the [[USB Bootloading]] page.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13452</id>
		<title>USB communication with C18 and MPLAB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13452"/>
		<updated>2009-06-11T12:26:37Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microchip publishes a USB Framework that consists of a number of files that contain code to handle the tedious parts of USB communication, with a few spots where user code can be included to build USB programs.&lt;br /&gt;
&lt;br /&gt;
When using the Microchip USB Framework, programs can operate in two modes: polling or interrupt. This choice comes from the fact that USB devices must continually monitor the connection to the host, looking for incoming data and handling the sending of data in the output queue. There are two ways to accomplish this: the program can either explicitly call a function periodically to handle USB tasks, or this can be done by a regularly scheduled interrupt. &lt;br /&gt;
&lt;br /&gt;
The framework provides two slots in which user code can be placed: the functions UserInit and ProcessIO. UserInit is called once at the beginning of the program to allow you to do some initialization. ProcessIO is called in a loop; each iteration should be very short and must be non-blocking, if you are using the polling structure. &lt;br /&gt;
&lt;br /&gt;
Below is an example program using the polling structure, showing just the UserInit and ProcessIO functions. You can download the full MPLAB project here. Note: this MPLAB project is configured to work with the [[USB Bootloading|USB HID bootloader]]. Using it without a bootloader or with another bootloader will require changes.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13451</id>
		<title>PIC USB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13451"/>
		<updated>2009-06-11T12:19:14Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;During the spring quarter of 2009, Greg McGlynn worked on USB communication and bootloading with PICs as a 399 project with professors Lynch and Peshkin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Project Documentation ==&lt;br /&gt;
[[PIC 18f4550]] -- only certain PICs are USB-capable, and the 18F4550 is probably the simplest one to transition to from the 4520.&lt;br /&gt;
&lt;br /&gt;
[[USB communication with PC]] -- including example code for both the CCS and C18 compilers.&lt;br /&gt;
&lt;br /&gt;
* [[USB communication with CCS]]&lt;br /&gt;
* [[USB communication with C18 and MPLAB]]&lt;br /&gt;
&lt;br /&gt;
[[USB Bootloading]] -- loading programs onto PICs using just a simple USB cable as opposed to an ICD or other programmer.&lt;br /&gt;
&lt;br /&gt;
[[USB communication between PICs]] -- requires a more powerful PIC than the 4550.&lt;br /&gt;
&lt;br /&gt;
[[Microchip USB Framework]] -- A collection of example MPLAB/C18 USB projects, published by Microchip.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
[[PIC_Microcontrollers_with_C18_Compiler]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13450</id>
		<title>USB communication with PC</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13450"/>
		<updated>2009-06-11T12:16:45Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some PIC models have built-in USB transceivers that make it simple to connect the PIC to a computer via USB. One such PIC is the [[PIC 18f4550]], which is similar to the 18f4520 in almost all respects, except that it has hardware support for USB built into it. The 18f4550 will work just fine in one of the [[4520_Board_intro|PIC protoboards]]. &lt;br /&gt;
&lt;br /&gt;
USB software for the PC tends to be OS-specific. &amp;#039;&amp;#039;&amp;#039;This article currently assumes you&amp;#039;re running Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== The USB protocol ==&lt;br /&gt;
USB is a pretty complex protocol with a long specification, but it&amp;#039;s not necessary to understand every part of it to use it. It&amp;#039;s enough to know what wires to hook up and what software libraries to include in your code.&lt;br /&gt;
&lt;br /&gt;
Wikipedia has a detailed and informative [http://en.wikipedia.org/wiki/Usb page on USB]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Connectors ===&lt;br /&gt;
USB connectors have four leads; the pictures on Wikipedia show which is which on standard connectors.&lt;br /&gt;
* +5V: the host (computer) provides up to 500mA of current at 5V that you can use for power. If your PIC is self-powered, though, make sure you don&amp;#039;t connect the two +5V sources or bad things may happen.&lt;br /&gt;
* GND: ground; make sure you do connect this to your PIC&amp;#039;s ground.&lt;br /&gt;
* D+ and D-: data is transmitted on these lines. The exact protocol is complicated and you probably don&amp;#039;t need to know the details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB with the PIC 18F4550 ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
On the 18f4550, the D+ line connects to pin RC5 and the D- line to pin RC4. The ground line of course connects to ground.&lt;br /&gt;
&lt;br /&gt;
Additionally pin 18, called Vusb, should have a capacitor to ground. Try 220 or 470nF.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
On the software side you have some choices. Probably the simplest thing to do is use a preexisting software library that makes the USB connection look like an [[PIC RS232|RS232 connection]]. The CCS compiler has a CDC library that provides functions like &amp;#039;&amp;#039;usb_cdc_getc&amp;#039;&amp;#039; or &amp;#039;&amp;#039;usb_cdc_putc&amp;#039;&amp;#039; that work over USB exactly like regular &amp;#039;&amp;#039;getc&amp;#039;&amp;#039; and &amp;#039;&amp;#039;putc&amp;#039;&amp;#039; work over RS232. CCS also provides a Windows driver for the PC that creates a virtual COM port that you can open in Matlab, Hyperterminal, or any other RS232-capable program and use to talk to the PIC. See [[USB communication with CCS]].&lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework that works with its C18 compiler and its MPLAB development environment. See [[USB communication with C18 and MPLAB]].&lt;br /&gt;
&lt;br /&gt;
CCS also has an example where the PIC registers itself as a Human Interface Device (HID). USB mice and keyboards use HID. The advantage of this is that doesn&amp;#039;t require the user to install a special driver. The disadvantages are (a) the connection doesn&amp;#039;t look like a simple RS232 link and (b) bandwidth is limited. A HID can only send messages to the computer once every millisecond, and can only send 64 bytes in each message, so the maximum data transfer rate is 64K bytes/second. In theory, USB can go up to 12M bits/second, so HID is fairly slow in comparison. &lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework for use with its [[PIC Microcontrollers with C18 Compiler|C18 compiler]]. &lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also possible to create one&amp;#039;s own setup from scratch or by modifying a preexisting library. This probably takes some effort.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13449</id>
		<title>PIC USB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13449"/>
		<updated>2009-06-11T12:15:29Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;During the spring quarter of 2009, Greg McGlynn worked on USB communication and bootloading with PICs as a 399 project with professors Lynch and Peshkin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Project Documentation ==&lt;br /&gt;
[[PIC 18f4550]] -- only certain PICs are USB-capable, and the 18F4550 is probably the simplest one to transition to from the 4520.&lt;br /&gt;
&lt;br /&gt;
[[USB communication with PC]] -- including example code for both the CCS and C18 compilers.&lt;br /&gt;
&lt;br /&gt;
[[USB Bootloading]] -- loading programs onto PICs using just a simple USB cable as opposed to an ICD or other programmer.&lt;br /&gt;
&lt;br /&gt;
[[USB communication between PICs]] -- requires a more powerful PIC than the 4550.&lt;br /&gt;
&lt;br /&gt;
[[Microchip USB Framework]] -- A collection of example MPLAB/C18 USB projects.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13338</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13338"/>
		<updated>2009-06-07T14:40:13Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows. The provided code is intended to be run on a [[PIC 18f4550|PIC18F4550 or 4553]] with a 20Mhz oscillator.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like a [[PIC 18f4550]]. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: if you&amp;#039;re going to load programs onto a PIC with a bootloader, you need to put some special instructions in the PIC code to make it work. See the &amp;quot;Compiling for a bootloader&amp;quot; section.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== CDC Bootloader ==&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested. The bootloader is a slightly modified version of one supplied by Microchip; the changes allow the compiled hex file to fit within the first 0x800 bytes program memory.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. These pins can be easily changed in the bootloader source code. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== HID Bootloader ==&lt;br /&gt;
&lt;br /&gt;
A HID (Human Interface Device) bootloader has the advantage that it doesn&amp;#039;t require any driver installation on the programming computer. Once the bootloader is programmed onto the PIC and the PIC is plugged into the PC, your computer should be able to handle the rest of the setup automatically. A HID bootloader is supplied with the [[Microchip USB Framework]]. This is a slightly modified version of the original HID bootloader project from Microchip. The original project is designed to fit within the first 0x1000 bytes of program memory, but due to changes in the compiler will no longer compile into that space; the modified version goes int he first 0x1100 bytes.&lt;br /&gt;
&lt;br /&gt;
=== PIC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PIC hex file here.&lt;br /&gt;
You can download the full MPLAB project for the PIC program here. &lt;br /&gt;
&lt;br /&gt;
=== PC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PC program here. It also comes as part of the [[Microchip USB Framework]]. When the program is running it should automatically detect when you attach the PIC (if the PIC has been properly programmed). To program the PIC click &amp;quot;Open Hex File,&amp;quot; and browse your compiled hex file. Then click &amp;quot;Program/Verify&amp;quot; and the bootloader should, after a few seconds, report that it has successfully erase, programmed, and verified the PIC. After that you can reset the PIC and it should run your program.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
Like the CDC bootloader, you must have a button wired up to indicate when the PIC should start up in bootloader mode. This bootloader looks at pin RC4; if RC4 is low on reset, the bootloader starts, otherwise the user program starts. The bootloader will use pins D0 and D1 to indicate connection state: leds hooked up to these pins will flash alternately when the connection has been established with the PC. Again, these pins can easily be changed in the bootloader source code.&lt;br /&gt;
&lt;br /&gt;
Note that the first time you plug the PIC into the PC and start it up in bootloader mode, it will take a few seconds for the PC to initialize everything before the lights start flashing, but after that the process should be pretty fast.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Compiling for a bootloader ==&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader (rather than overwriting it). The CDC bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory), while the HID bootloader goes from 0x0000 to 0x10FF (these are hexadecimal numbers). Your program therefore needs to start at address 0x800 or 0x1100, depending on which bootloader you&amp;#039;re using, and not touch the memory from 0x000 to 0x7FF. &lt;br /&gt;
&lt;br /&gt;
With CCS you can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CDC bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x1100, interrupt=0x1108)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x10FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With MPLAB/C18 the required code is a bit longer:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with MPLAB:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;//The following lengthy and involved incantation sets things up so that resets and interrupt&lt;br /&gt;
//handling operate as they should, given the presence of the bootloader. &lt;br /&gt;
//Omitting this incantation will make the code stop working.&lt;br /&gt;
//If you are generating absolutely no interrupts, you can probably leave out just the stuff &lt;br /&gt;
//referring to interrupts.&lt;br /&gt;
//Comments are by Microchip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for&lt;br /&gt;
//the reset, high priority interrupt, and low priority interrupt&lt;br /&gt;
//vectors.  However, the current Microchip USB bootloader &lt;br /&gt;
//examples are intended to occupy addresses 0x00-0x7FF or&lt;br /&gt;
//0x00-0xFFF depending on which bootloader is used.  Therefore,&lt;br /&gt;
//the bootloader code remaps these vectors to new locations&lt;br /&gt;
//as indicated below.  This remapping is only necessary if you&lt;br /&gt;
//wish to program the hex file generated from this project with&lt;br /&gt;
//the USB bootloader.&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//If the output hex file is not programmed with&lt;br /&gt;
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.&lt;br /&gt;
//As a result, if an actual interrupt was enabled and occured, the PC would jump&lt;br /&gt;
//to 0x08 (or 0x18) and would begin executing &amp;quot;0xFFFF&amp;quot; (unprogrammed space).  This&lt;br /&gt;
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
//(0x1000 or 0x800, depending upon bootloader), and would execute the &amp;quot;goto _startup&amp;quot;.  This&lt;br /&gt;
//would effective reset the application.&lt;br /&gt;
&lt;br /&gt;
//To fix this situation, we should always deliberately place a &lt;br /&gt;
//&amp;quot;goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x08, and a&lt;br /&gt;
//&amp;quot;goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x18.  When the output&lt;br /&gt;
//hex file of this project is programmed with the bootloader, these sections do not&lt;br /&gt;
//get bootloaded (as they overlap the bootloader space).  If the output hex file is not&lt;br /&gt;
//programmed using the bootloader, then the below goto instructions do get programmed,&lt;br /&gt;
//and the hex file still works like normal.  The below section is only required to fix this&lt;br /&gt;
//scenario.	&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.&lt;br /&gt;
}	//This return will be a &amp;quot;retfie fast&amp;quot;, since this is in a #pragma interrupt section &lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.	&lt;br /&gt;
}	//This return will be a &amp;quot;retfie&amp;quot;, since this is in a #pragma interruptlow section &lt;br /&gt;
&lt;br /&gt;
//End incantation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a shorter version of the same thing, stripped of most explanatory comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void) { _asm goto _startup _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void) { _asm goto YourHighPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void) { _asm goto YourLowPriorityISRCode _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void) { _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void) { _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm }&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode() {&lt;br /&gt;
    //high priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode() {&lt;br /&gt;
    //low priority interrupt code&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you wish to use the CDC bootloader with MPLAB source code, you only need to change three lines of the above, where the REMAPPED_VECTOR_ADDRESS constants are defined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x800&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x808&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x818&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13336</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13336"/>
		<updated>2009-06-07T14:36:48Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: /* Compiling for a bootloader */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows. The provided code is intended to be run on a [[PIC 18f4550|PIC18F4550 or 4553]] with a 20Mhz oscillator.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like a [[PIC 18f4550]]. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: if you&amp;#039;re going to load programs onto a PIC with a bootloader, you need to put some special instructions in the PIC code to make it work. See the &amp;quot;Compiling for a bootloader&amp;quot; section.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== CDC Bootloader ==&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested. The bootloader is a slightly modified version of one supplied by Microchip; the changes allow the compiled hex file to fit within the first 0x800 bytes program memory.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. These pins can be easily changed in the bootloader source code. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== HID Bootloader ==&lt;br /&gt;
&lt;br /&gt;
A HID (Human Interface Device) bootloader has the advantage that it doesn&amp;#039;t require any driver installation on the programming computer. Once the bootloader is programmed onto the PIC and the PIC is plugged into the PC, your computer should be able to handle the rest of the setup automatically. A HID bootloader is supplied with the [[Microchip USB Framework]]. This is a slightly modified version of the original HID bootloader project from Microchip. The original project is designed to fit within the first 0x1000 bytes of program memory, but due to changes in the compiler will no longer compile into that space; the modified version goes int he first 0x1100 bytes.&lt;br /&gt;
&lt;br /&gt;
=== PIC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PIC hex file here.&lt;br /&gt;
You can download the full MPLAB project for the PIC program here. &lt;br /&gt;
&lt;br /&gt;
=== PC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PC program here. It also comes as part of the [[Microchip USB Framework]]. When the program is running it should automatically detect when you attach the PIC (if the PIC has been properly programmed). To program the PIC click &amp;quot;Open Hex File,&amp;quot; and browse your compiled hex file. Then click &amp;quot;Program/Verify&amp;quot; and the bootloader should, after a few seconds, report that it has successfully erase, programmed, and verified the PIC. After that you can reset the PIC and it should run your program.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
Like the CDC bootloader, you must have a button wired up to indicate when the PIC should start up in bootloader mode. This bootloader looks at pin RC4; if RC4 is low on reset, the bootloader starts, otherwise the user program starts. The bootloader will use pins D0 and D1 to indicate connection state: leds hooked up to these pins will flash alternately when the connection has been established with the PC. Again, these pins can easily be changed in the bootloader source code.&lt;br /&gt;
&lt;br /&gt;
Note that the first time you plug the PIC into the PC and start it up in bootloader mode, it will take a few seconds for the PC to initialize everything before the lights start flashing, but after that the process should be pretty fast.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Compiling for a bootloader ==&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader (rather than overwriting it). The CDC bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory), while the HID bootloader goes from 0x0000 to 0x10FF (these are hexadecimal numbers). Your program therefore needs to start at address 0x800 or 0x1100, depending on which bootloader you&amp;#039;re using, and not touch the memory from 0x000 to 0x7FF. &lt;br /&gt;
&lt;br /&gt;
With CCS you can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CDC bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with CCS:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x1100, interrupt=0x1108)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x10FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With MPLAB/C18 the required code is a bit longer:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader with MPLAB:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;//The following lengthy and involved incantation sets things up so that resets and interrupt&lt;br /&gt;
//handling operate as they should, given the presence of the bootloader. &lt;br /&gt;
//Omitting this incantation will make the code stop working.&lt;br /&gt;
//If you are generating absolutely no interrupts, you can probably leave out just the stuff &lt;br /&gt;
//referring to interrupts.&lt;br /&gt;
//Comments are by Microchip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for&lt;br /&gt;
//the reset, high priority interrupt, and low priority interrupt&lt;br /&gt;
//vectors.  However, the current Microchip USB bootloader &lt;br /&gt;
//examples are intended to occupy addresses 0x00-0x7FF or&lt;br /&gt;
//0x00-0xFFF depending on which bootloader is used.  Therefore,&lt;br /&gt;
//the bootloader code remaps these vectors to new locations&lt;br /&gt;
//as indicated below.  This remapping is only necessary if you&lt;br /&gt;
//wish to program the hex file generated from this project with&lt;br /&gt;
//the USB bootloader.&lt;br /&gt;
#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//If the output hex file is not programmed with&lt;br /&gt;
//the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.&lt;br /&gt;
//As a result, if an actual interrupt was enabled and occured, the PC would jump&lt;br /&gt;
//to 0x08 (or 0x18) and would begin executing &amp;quot;0xFFFF&amp;quot; (unprogrammed space).  This&lt;br /&gt;
//executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
//(0x1000 or 0x800, depending upon bootloader), and would execute the &amp;quot;goto _startup&amp;quot;.  This&lt;br /&gt;
//would effective reset the application.&lt;br /&gt;
&lt;br /&gt;
//To fix this situation, we should always deliberately place a &lt;br /&gt;
//&amp;quot;goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x08, and a&lt;br /&gt;
//&amp;quot;goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&amp;quot; at address 0x18.  When the output&lt;br /&gt;
//hex file of this project is programmed with the bootloader, these sections do not&lt;br /&gt;
//get bootloaded (as they overlap the bootloader space).  If the output hex file is not&lt;br /&gt;
//programmed using the bootloader, then the below goto instructions do get programmed,&lt;br /&gt;
//and the hex file still works like normal.  The below section is only required to fix this&lt;br /&gt;
//scenario.	&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.&lt;br /&gt;
}	//This return will be a &amp;quot;retfie fast&amp;quot;, since this is in a #pragma interrupt section &lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
		//Check which interrupt flag caused the interrupt.&lt;br /&gt;
		//Service the interrupt&lt;br /&gt;
		//Clear the interrupt flag&lt;br /&gt;
		//Etc.	&lt;br /&gt;
}	//This return will be a &amp;quot;retfie&amp;quot;, since this is in a #pragma interruptlow section &lt;br /&gt;
&lt;br /&gt;
//End incantation&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a shorter version of the same thing, stripped of most explanatory comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x1100&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x1108&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x1118&lt;br /&gt;
&lt;br /&gt;
void YourHighPriorityISRCode();&lt;br /&gt;
void YourLowPriorityISRCode();&lt;br /&gt;
&lt;br /&gt;
extern void _startup (void);        // See c018i.c in your C18 compiler dir&lt;br /&gt;
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS&lt;br /&gt;
void _reset (void)&lt;br /&gt;
{&lt;br /&gt;
    _asm goto _startup _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourHighPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS&lt;br /&gt;
void Remapped_Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto YourLowPriorityISRCode _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code HIGH_INTERRUPT_VECTOR = 0x08&lt;br /&gt;
void High_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
#pragma code LOW_INTERRUPT_VECTOR = 0x18&lt;br /&gt;
void Low_ISR (void)&lt;br /&gt;
{&lt;br /&gt;
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma code&lt;br /&gt;
&lt;br /&gt;
#pragma interrupt YourHighPriorityISRCode&lt;br /&gt;
void YourHighPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
    //high priority interrupt code&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pragma interruptlow YourLowPriorityISRCode&lt;br /&gt;
void YourLowPriorityISRCode()&lt;br /&gt;
{&lt;br /&gt;
    //low priority interrupt code&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you wish to use the CDC bootloader with MPLAB source code, you only need to change three lines of the above, where the REMAPPED_VECTOR_ADDRESS constants are defined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#define REMAPPED_RESET_VECTOR_ADDRESS			0x800&lt;br /&gt;
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS	0x808&lt;br /&gt;
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS	0x818&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13333</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13333"/>
		<updated>2009-06-07T14:29:29Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows. The provided code is intended to be run on a [[PIC 18f4550|PIC18F4550 or 4553]] with a 20Mhz oscillator.&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like a [[PIC 18f4550]]. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: if you&amp;#039;re going to load programs onto a PIC with a bootloader, you need to put some special instructions in the PIC code to make it work. See the &amp;quot;Compiling for a bootloader&amp;quot; section.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== CDC Bootloader ==&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested. The bootloader is a slightly modified version of one supplied by Microchip; the changes allow the compiled hex file to fit within the first 0x800 bytes program memory.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. These pins can be easily changed in the bootloader source code. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== HID Bootloader ==&lt;br /&gt;
&lt;br /&gt;
A HID (Human Interface Device) bootloader has the advantage that it doesn&amp;#039;t require any driver installation on the programming computer. Once the bootloader is programmed onto the PIC and the PIC is plugged into the PC, your computer should be able to handle the rest of the setup automatically. A HID bootloader is supplied with the [[Microchip USB Framework]]. This is a slightly modified version of the original HID bootloader project from Microchip. The original project is designed to fit within the first 0x1000 bytes of program memory, but due to changes in the compiler will no longer compile into that space; the modified version goes int he first 0x1100 bytes.&lt;br /&gt;
&lt;br /&gt;
=== PIC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PIC hex file here.&lt;br /&gt;
You can download the full MPLAB project for the PIC program here. &lt;br /&gt;
&lt;br /&gt;
=== PC software ===&lt;br /&gt;
&lt;br /&gt;
You can download the PC program here. It also comes as part of the [[Microchip USB Framework]]. When the program is running it should automatically detect when you attach the PIC (if the PIC has been properly programmed). To program the PIC click &amp;quot;Open Hex File,&amp;quot; and browse your compiled hex file. Then click &amp;quot;Program/Verify&amp;quot; and the bootloader should, after a few seconds, report that it has successfully erase, programmed, and verified the PIC. After that you can reset the PIC and it should run your program.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
Like the CDC bootloader, you must have a button wired up to indicate when the PIC should start up in bootloader mode. This bootloader looks at pin RC4; if RC4 is low on reset, the bootloader starts, otherwise the user program starts. The bootloader will use pins D0 and D1 to indicate connection state: leds hooked up to these pins will flash alternately when the connection has been established with the PC. Again, these pins can easily be changed in the bootloader source code.&lt;br /&gt;
&lt;br /&gt;
Note that the first time you plug the PIC into the PC and start it up in bootloader mode, it will take a few seconds for the PC to initialize everything before the lights start flashing, but after that the process should be pretty fast.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Compiling for a bootloader ==&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader (rather than overwriting it). The CDC bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory), while the HID bootloader goes from 0x0000 to 0x10FF (these are hexadecimal numbers). Your program therefore needs to start at address 0x800 or 0x1100, depending on which bootloader you&amp;#039;re using, and not touch the memory from 0x000 to 0x7FF. &lt;br /&gt;
&lt;br /&gt;
With CCS you can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CDC bootloader:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;HID bootloader:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x1100, interrupt=0x1108)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x10FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With MPLAB/C18 the required code is a bit longer:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Microchip_USB_Framework&amp;diff=13332</id>
		<title>Microchip USB Framework</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Microchip_USB_Framework&amp;diff=13332"/>
		<updated>2009-06-07T14:06:17Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microchip provides a USB Framework free for download, which includes MPLAB/C18 projects to get you started with USB programming for PICs. These projects are generally intended to be run on one of Microchip&amp;#039;s many demo boards, but most of the code can be taken and used for any USB project. The framework also includes both PIC and PC software for [[USB Bootloading|two USB bootloaders]].&lt;br /&gt;
&lt;br /&gt;
You can download the framework from Microchip as one part of the &amp;quot;Microchip Applications Libraries,&amp;quot; bundled with some other stuff like a &amp;quot;Graphics Library&amp;quot; and a &amp;quot;Memory Disk Drive Library&amp;quot;: [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=2680&amp;amp;dDocName=en540668 framework download]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_between_PICs&amp;diff=13331</id>
		<title>USB communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_between_PICs&amp;diff=13331"/>
		<updated>2009-06-07T13:56:31Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The USB protocol identifies two sides of a communication: the host and the device. The host controls the communication and does more work than the device. Generally the host is a computer, and the PIC is the device. However, if you configure a PIC as a host you can do certain new things:&lt;br /&gt;
&lt;br /&gt;
* Plug in a flash drive USB device to use as storage.&lt;br /&gt;
* Configure another PIC as a USB device and use USB to communicate between them.&lt;br /&gt;
&lt;br /&gt;
The [[Microchip USB Framework]] includes an embedded host stack that provides code for running a PIC as a USB host. The [[PIC 18f4550]] is &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; able to run as an embedded host: to run the embedded host stack requires a 16-bit or 32-bit PIC. The 4550 is a mere 8-bit chip.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13330</id>
		<title>PIC USB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13330"/>
		<updated>2009-06-07T13:48:20Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;During the spring quarter of 2009, Greg McGlynn worked on USB communication and bootloading with PICs as a 399 project with professors Lynch and Peshkin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Project Documentation ==&lt;br /&gt;
[[PIC 18f4550]] -- only certain PICs are USB-capable, and the 18F4550 is probably the simplest one to transition to from the 4520.&lt;br /&gt;
&lt;br /&gt;
[[USB communication with PC]] -- including example code for both the CCS and C18 compilers.&lt;br /&gt;
&lt;br /&gt;
[[USB Bootloading]] -- loading programs onto PICs using just a simple USB cable as opposed to an ICD or other programmer.&lt;br /&gt;
&lt;br /&gt;
[[USB communication between PICs]] -- requires a more powerful PIC than the 4550.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13329</id>
		<title>PIC USB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_USB&amp;diff=13329"/>
		<updated>2009-06-07T13:35:44Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;During the spring quarter of 2009, Greg McGlynn worked on USB communication and bootloading with PICs as a 399 project with professors Lynch and Peshkin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Project Documentation ==&lt;br /&gt;
[[PIC 18f4550]] -- only certain PICs are USB-capable, and the 18F4550 is probably the simplest one to transition to from the 4520.&lt;br /&gt;
&lt;br /&gt;
[[USB communication with PC]] -- including example code for both the CCS and C18 compilers.&lt;br /&gt;
&lt;br /&gt;
[[USB Bootloading]] -- loading programs onto PICs using just a simple USB cable as opposed to an ICD or other programmer.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Projects_and_miscellaneous&amp;diff=13328</id>
		<title>Projects and miscellaneous</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Projects_and_miscellaneous&amp;diff=13328"/>
		<updated>2009-06-07T13:31:02Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*[[ME 333 final projects]]&lt;br /&gt;
*[[PIC Motor Control with EEPROM and Interactive Menu Example]]&lt;br /&gt;
*[[Machine Vision Localization System]]&lt;br /&gt;
*[[Swarm Robot Project]]&lt;br /&gt;
*[[Swarm Project E-puck Code]]&lt;br /&gt;
*[[Swarm Robot Project Documentation]]&lt;br /&gt;
*[[Machine Vision Localization System]]&lt;br /&gt;
*[[Indoor Localization System | Indoor Localization System (Obsolete)]]&lt;br /&gt;
*[[Robot Helicopter Project]]&lt;br /&gt;
*[[E-Puck Color Sensing Project]]&lt;br /&gt;
*[[Guitar Tuning Project]]&lt;br /&gt;
*[[Mohr&amp;#039;s Circle]]&lt;br /&gt;
*[[E-puck Mobile Robot]]&lt;br /&gt;
*[[Bearings]]&lt;br /&gt;
*[[Indoor Localization System]]&lt;br /&gt;
*[[Using the Basic Stamp Microcontroller]]&lt;br /&gt;
*[[Basic Stamp]]&lt;br /&gt;
*[[Solderboard]]&lt;br /&gt;
*[[Battery disaster]]&lt;br /&gt;
*[[LIMS Air Hockey Table]]&lt;br /&gt;
*[[Rotational Stiffness]]&lt;br /&gt;
*[[Swarm E-puck Quickstart Guide]]&lt;br /&gt;
*[[High Speed Vision System and Object Tracking]]&lt;br /&gt;
*[[PIC USB]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13324</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13324"/>
		<updated>2009-06-07T01:33:03Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB Bootloading with the [[PIC 18f4553]] ==&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like an 18f4553. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
== HID Bootloader ==&lt;br /&gt;
&lt;br /&gt;
A HID (Human Interface Device) bootloader has the advantage that it doesn&amp;#039;t require any driver installation on the programming computer. Once the bootloader is programmed onto the PIC and the PIC is plugged into the PC, your computer should be able to handle the rest of the setup automatically. A HID bootloader is supplied with the Microchip USB Framework. You can download the PC program here. You can download the PIC hex file here. You can download the full MPLAB project for the PIC program here. This is a slightly modified version of the original HID bootloader project from Microchip. The original project is designed to fit within the first 0x1000 bytes of program memory, but due to changes in the compiler will no longer compile into that space; the modified version goes int he first 0x1100 bytes.&lt;br /&gt;
&lt;br /&gt;
== CDC Bootloader ==&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested. The bootloader is a slightly modified version of one supplied by Microchip; the changes allow the compiled hex file to fit within the first 0x800 bytes program memory.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Compiling for a bootloader ===&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader. Our bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory). Your program therefore needs to start at address 0x800 and not touch the memory from 0x000 to 0x7FF. You can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13321</id>
		<title>USB communication with C18 and MPLAB</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_C18_and_MPLAB&amp;diff=13321"/>
		<updated>2009-06-07T00:56:56Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microchip publishes a USB Framework that consists of a number of files that contain code to handle the tedious parts of USB communication, with a few spots where user code can be included to build USB programs.&lt;br /&gt;
&lt;br /&gt;
When using the Microchip USB Framework, programs can operate in two modes: polling or interrupt. This choice comes from the fact that USB devices must continually monitor the connection to the host, looking for incoming data and handling the sending of data in the output queue. There are two ways to accomplish this: the program can either explicitly call a function periodically to handle USB tasks, or this can be done by a regularly scheduled interrupt. &lt;br /&gt;
&lt;br /&gt;
The framework provides two slots in which user code can be placed: the functions UserInit and ProcessIO. UserInit is called once at the beginning of the program to allow you to do some initialization. ProcessIO is called in a loop; each iteration should be very short and must be non-blocking, if you are using the polling structure. &lt;br /&gt;
&lt;br /&gt;
Below is an example program using the polling structure, showing just the UserInit and ProcessIO functions. You can download the full MPLAB project here.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13318</id>
		<title>USB communication with PC</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13318"/>
		<updated>2009-06-06T23:57:29Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some PIC models have built-in USB transceivers that make it simple to connect the PIC to a computer via USB. One such PIC is the [[PIC 18f4550]], which is similar to the 18f4520 in almost all respects, except that it has hardware support for USB built into it. The 18f4550 will work just fine in one of the [[4520_Board_intro|PIC protoboards]]. &lt;br /&gt;
&lt;br /&gt;
USB software for the PC tends to be OS-specific. &amp;#039;&amp;#039;&amp;#039;This article currently assumes you&amp;#039;re running Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== The USB protocol ==&lt;br /&gt;
USB is a pretty complex protocol with a long specification, but it&amp;#039;s not necessary to understand every part of it to use it. It&amp;#039;s enough to know what wires to hook up and what software libraries to include in your code.&lt;br /&gt;
&lt;br /&gt;
Wikipedia has a detailed and informative [http://en.wikipedia.org/wiki/Usb page on USB]. &lt;br /&gt;
&lt;br /&gt;
USB connectors have four leads; the pictures on Wikipedia show which is which on standard connectors.&lt;br /&gt;
* +5V: the host (computer) provides up to 500mA of current at 5V that you can use for power. If your PIC is self-powered, though, make sure you don&amp;#039;t connect the two +5V sources or bad things may happen.&lt;br /&gt;
* GND: ground; make sure you do connect this to your PIC&amp;#039;s ground.&lt;br /&gt;
* D+ and D-: data is transmitted on these lines. The exact protocol is complicated and you probably don&amp;#039;t need to know the details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB with the PIC 18F4550 ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
On the 18f4550, the D+ line connects to pin RC5 and the D- line to pin RC4. The ground line of course connects to ground.&lt;br /&gt;
&lt;br /&gt;
Additionally pin 18, called Vusb, should have a capacitor to ground. Try 220 or 470nF.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
On the software side you have some choices. Probably the simplest thing to do is use a preexisting software library that makes the USB connection look like an [[PIC RS232|RS232 connection]]. The CCS compiler has a CDC library that provides functions like &amp;#039;&amp;#039;usb_cdc_getc&amp;#039;&amp;#039; or &amp;#039;&amp;#039;usb_cdc_putc&amp;#039;&amp;#039; that work over USB exactly like regular &amp;#039;&amp;#039;getc&amp;#039;&amp;#039; and &amp;#039;&amp;#039;putc&amp;#039;&amp;#039; work over RS232. CCS also provides a Windows driver for the PC that creates a virtual COM port that you can open in Matlab, Hyperterminal, or any other RS232-capable program and use to talk to the PIC. See [[USB communication with CCS]].&lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework that works with its C18 compiler and its MPLAB development environment. See [[USB communication with C18 and MPLAB]].&lt;br /&gt;
&lt;br /&gt;
CCS also has an example where the PIC registers itself as a Human Interface Device (HID). USB mice and keyboards use HID. The advantage of this is that doesn&amp;#039;t require the user to install a special driver. The disadvantages are (a) the connection doesn&amp;#039;t look like a simple RS232 link and (b) bandwidth is limited. A HID can only send messages to the computer once every millisecond, and can only send 64 bytes in each message, so the maximum data transfer rate is 64K bytes/second. In theory, USB can go up to 12M bits/second, so HID is fairly slow in comparison. &lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework for use with its [[PIC Microcontrollers with C18 Compiler|C18 compiler]]. &lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also possible to create one&amp;#039;s own setup from scratch or by modifying a preexisting library. This probably takes some effort.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13317</id>
		<title>PIC 18f4550</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13317"/>
		<updated>2009-06-06T23:48:21Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PIC 18F4550 is a chip very similar to the 18f4520, differing in one important respect: it has a built-in USB transceiver, so you can do USB communication with it. See [[USB communication with PC]] or [[USB Bootloading]].&lt;br /&gt;
&lt;br /&gt;
== PIC 18F4553 ==&lt;br /&gt;
&lt;br /&gt;
The PIC 18F4553 is different from the 4550 in only one respect: it has a 12-bit analog-digital converter (ADC) as opposed to a mere 10-bit one. Code written for the 4550 will likely run without changes on the 4553, and vice versa.&lt;br /&gt;
&lt;br /&gt;
== Programming the 18f4553 ==&lt;br /&gt;
If your version of the CCS compiler does not list the 4553 as a supported device, you can just program for the 4550, which is almost exactly the same except that it has only a 10-bit ADC. However you will need to update your ICD firmware so that it recognizes the PIC. Save this file to your &amp;quot;C:\Program Files\PICC&amp;quot; directory: [Image:icd-images-firmware-02-51.fw]. Then plug in your ICD and run &amp;quot;C:\Program Files\PICC\icd.exe&amp;quot;. Click &amp;quot;Update Firmware&amp;quot;, then select &amp;quot;Other&amp;quot; and browse to the file you save. Then hit &amp;quot;Ok&amp;quot; to update the firmware. &lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re programming for the 18f4550, when you hit Program in CCS you&amp;#039;ll need to confirm that it&amp;#039;s OK that the code wants a 18f4550 while the detected target is a 18f4553.&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_18f4553&amp;diff=13316</id>
		<title>PIC 18f4553</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_18f4553&amp;diff=13316"/>
		<updated>2009-06-06T23:45:19Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: PIC 18f4553 moved to PIC 18f4550&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[PIC 18f4550]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13315</id>
		<title>PIC 18f4550</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13315"/>
		<updated>2009-06-06T23:45:19Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: PIC 18f4553 moved to PIC 18f4550&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PIC 18f4553 is a chip very similar to the 18f4520, differing in two important respects:&lt;br /&gt;
*It has a built-in USB transceiver, so you can do USB communication with it.&lt;br /&gt;
*It has a 12-bit analog-digital converter (ADC) as opposed to a mere 10-bit one.&lt;br /&gt;
&lt;br /&gt;
== Programming the 18f4553 ==&lt;br /&gt;
If your version of the CCS compiler does not list the 4553 as a supported device, you can just program for the 4550, which is almost exactly the same except that it has only a 10-bit ADC. However you will need to update your ICD firmware so that it recognizes the PIC. Save this file to your &amp;quot;C:\Program Files\PICC&amp;quot; directory: [Image:icd-images-firmware-02-51.fw]. Then plug in your ICD and run &amp;quot;C:\Program Files\PICC\icd.exe&amp;quot;. Click &amp;quot;Update Firmware&amp;quot;, then select &amp;quot;Other&amp;quot; and browse to the file you save. Then hit &amp;quot;Ok&amp;quot; to update the firmware. &lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re programming for the 18f4550, when you hit Program in CCS you&amp;#039;ll need to confirm that it&amp;#039;s OK that the code wants a 18f4550 while the detected target is a 18f4553.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_CCS&amp;diff=13287</id>
		<title>USB communication with CCS</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_CCS&amp;diff=13287"/>
		<updated>2009-05-12T07:45:46Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A sample program using CCS&amp;#039;s CDC library is shown below. The program waits for some input and then responds to it. When you first plug in the PIC to the computer, Windows will need to install a driver to talk to it. If you&amp;#039;re running XP or earlier, point it to the directory C:\Program Files\PICC\Drivers, where it will find what it needs. If you&amp;#039;re running Vista the driver may not be there; download [[Image:Cdc_NTXPVista.inf]], save it somewhere, and point Windows to it. Once the driver is installed a virtual COM port will be created (it will be visible in the device manager) and you&amp;#039;ll be able to talk to the PIC in Hyperterminal, Matlab, or anything else that communications over RS232.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;lt;18f4550.h&amp;gt; //if your version of the compiler doesn&amp;#039;t support the 4553, you can put the 4550 in your code, which is almost exactly the same.&lt;br /&gt;
#use delay(clock=48000000) //because of tricky fuses a 20Mhz oscillator will make the PIC run at 48Mhz&lt;br /&gt;
#fuses HS, NOWDT, NOLVP, NOPROTECT //standard fuses&lt;br /&gt;
&lt;br /&gt;
//these fuses are critical. they assume a 20Mhz oscillator:&lt;br /&gt;
#fuses PLL5     //The USB module must run at 48Mhz. This tells the PIC to take the oscillator, divide the frequency by 5, then multiply by 12. The result must be 48Mhz. &lt;br /&gt;
#fuses HSPLL    //I&amp;#039;m not exactly sure what this fuses does, but it&amp;#039;s probably necessary.&lt;br /&gt;
#fuses VREGEN   //The USB module must run at 3.3V. This tells the PIC to accomplish this by using an internal voltage regulator.&lt;br /&gt;
#fuses CPUDIV1  //This tells the PIC to run at a frequency of 48Mhz / 1 = 48Mhz. It may or may not be necessary.&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;usb_cdc.h&amp;gt; //Include the USB CDC library. If you want to see all the functions available look at usb_cdc.h and usb.h.&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
   int c;&lt;br /&gt;
&lt;br /&gt;
   //these lines do some initialization, obviously:&lt;br /&gt;
   usb_cdc_init();&lt;br /&gt;
   usb_init();&lt;br /&gt;
   usb_wait_for_enumeration();   &lt;br /&gt;
&lt;br /&gt;
   while(true) {&lt;br /&gt;
       usb_task(); //handles connections to and disconnections from the computer, registering the PIC with the computer, etc. call this pretty often so that the PIC responds to being plugged in. &lt;br /&gt;
       &lt;br /&gt;
       if(usb_cdc_kbhit()) { //did we get some incoming data? &lt;br /&gt;
           c = usb_cdc_getc(); //get one character of input&lt;br /&gt;
           printf(usb_cdc_putc, &amp;quot;you typed: %c\r\n&amp;quot;, c); //print out a response over usb&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_CCS&amp;diff=13286</id>
		<title>USB communication with CCS</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_CCS&amp;diff=13286"/>
		<updated>2009-05-12T07:43:48Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A sample program using CCS&amp;#039;s CDC library is shown below. The program waits for some input and then responds to it. When you first plug in the PIC to the computer, Windows will need to install a driver to talk to it. If you&amp;#039;re running XP or earlier, point it to the directory C:\Program Files\PICC\Drivers, where it will find what it needs. If you&amp;#039;re running Vista the driver may not be there; download [[Image:Cdc_NTXPVista.inf]], save it somewhere, and point Windows to it. Once the driver is installed a virtual COM port will be created (it will be visible in the device manager) and you&amp;#039;ll be able to talk to the PIC in Hyperterminal, Matlab, or anything else that communications over RS232.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;lt;18f4550.h&amp;gt; //if your version of the compiler doesn&amp;#039;t support the 4553, you can put the 4550 in your code, which is almost exactly the same.&lt;br /&gt;
#use delay(clock=48000000) //because of tricky fuses a 20Mhz oscillator will make the PIC run at 48Mhz&lt;br /&gt;
#fuses HS, NOWDT, NOLVP, NOPROTECT //standard fuses&lt;br /&gt;
&lt;br /&gt;
//these fuses are critical. they assume a 20Mhz oscillator:&lt;br /&gt;
#fuses PLL5     //The USB module must run at 48Mhz. This tells the PIC to take the oscillator, divide the frequency by 5, then multiply by 12. The result must be 48Mhz. &lt;br /&gt;
#fuses HSPLL    //I&amp;#039;m not exactly sure what this fuses does, but it&amp;#039;s probably necessary.&lt;br /&gt;
#fuses VREGEN   //The USB module must run at 3.3V. This tells the PIC to accomplish this by using an internal voltage regulator.&lt;br /&gt;
#fuses CPUDIV1  //This tells the PIC to run at a frequency of 48Mhz / 1 = 48Mhz. It may or may not be necessary.&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;usb_cdc.h&amp;gt; //Include the CCS USB library. If you want to see all the functions available look at usb_cdc.h and usb.h.&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
   int c;&lt;br /&gt;
&lt;br /&gt;
   //these lines do some initialization, obviously:&lt;br /&gt;
   usb_cdc_init();&lt;br /&gt;
   usb_init();&lt;br /&gt;
   usb_wait_for_enumeration();   &lt;br /&gt;
&lt;br /&gt;
   while(true) {&lt;br /&gt;
       usb_task(); //handles connections to and disconnections from the computer, registering the PIC with the computer, etc. call this pretty often so that the PIC responds to being plugged in. &lt;br /&gt;
       &lt;br /&gt;
       if(usb_cdc_kbhit()) { //did we get some incoming data? &lt;br /&gt;
           c = usb_cdc_getc(); //get one character of input&lt;br /&gt;
           printf(usb_cdc_putc, &amp;quot;you typed: %c\r\n&amp;quot;, c); //print out a response over usb&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13285</id>
		<title>USB communication with PC</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13285"/>
		<updated>2009-05-12T07:43:23Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some PIC models have built-in USB transceivers that make it simple to connect the PIC to a computer via USB. One such PIC is the [[PIC 18f4553]], which is similar to the 18f4520 in almost all respects, except that it has hardware support for USB built into it. The 18f4553 will work just fine in one of the [[4520_Board_intro|PIC protoboards]]. &lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m not clear on how cross-platform USB software tends to be. &amp;#039;&amp;#039;&amp;#039;This article currently assumes you&amp;#039;re running Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== The USB protocol ==&lt;br /&gt;
USB is a pretty complex protocol with a long specification, but it&amp;#039;s not necessary to understand every part of it to use it. It&amp;#039;s enough to know what wires to hook up and what software libraries to include in your code, and using USB will be easy. &lt;br /&gt;
&lt;br /&gt;
Wikipedia has a detailed and informative [http://en.wikipedia.org/wiki/Usb page on USB]. &lt;br /&gt;
&lt;br /&gt;
USB connectors have four leads; the pictures on Wikipedia show which is which on standard connectors.&lt;br /&gt;
* +5V: the host [computer] provides up to 500mA of current at 5V that you can use for power. If your PIC is self-powered, though, make sure you don&amp;#039;t connect the two +5V sources or bad things may happen.&lt;br /&gt;
* GND: ground; make sure you do connect this to your PIC&amp;#039;s ground.&lt;br /&gt;
* D+ and D-: data is transmitted on these lines. The exact protocol is complicated and you probably don&amp;#039;t need to know the details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB with the PIC 18F4553 ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
On the 18f4553, the D+ line connects to pin RC5 and the D- line to pin RC4. The ground line of course connects to ground.&lt;br /&gt;
&lt;br /&gt;
Additionally pin 18, called Vusb, should have a capacitor to ground. Try 220 or 470nF.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
On the software side you have some choices. Probably the simplest thing to do is use a preexisting software library that makes the USB connection look like an [[PIC RS232|RS232 connection]]. The CCS compiler has a CDC library that provides functions like usb_cdc_getc or usb_cdc_putc that work over USB exactly like regular getc and putc work over RS232. CCS also provides a Windows driver for the PC that creates a virtual COM port that you can open in Matlab or Hyperterminal and use to talk to the PIC. See [[USB communication with CCS]].&lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework that works with its C18 compiler and its MPLAB development environment. See [[USB communication with C18 and MPLAB]].&lt;br /&gt;
&lt;br /&gt;
CCS also has an example where the PIC registers itself as a Human Interface Device (HID). USB mice and keyboards use HID. The advantage of this is that doesn&amp;#039;t require the user to install a special driver. The disadvantages are (a) the connection doesn&amp;#039;t look like a simple RS232 link and (b) bandwidth is limited. A HID can only send messages to the computer once every millisecond, and can only send 64 bytes in each message, so the maximum data transfer rate is 64K bytes/second. In theory, USB can go up to 12M bits/second, so HID is fairly slow in comparison. &lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework for use with its [[PIC Microcontrollers with C18 Compiler|C18 compiler]]. &lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also possible to create one&amp;#039;s own setup from scratch or by modifying a preexisting library. This probably takes some effort.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13284</id>
		<title>USB communication with PC</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13284"/>
		<updated>2009-05-12T07:42:59Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some PIC models have built-in USB transceivers that make it simple to connect the PIC to a computer via USB. One such PIC is the [[PIC 18f4553]], which is similar to the 18f4520 in almost all respects, except that it has hardware support for USB built into it. The 18f4553 will work just fine in one of the [[4520_Board_intro|PIC protoboards]]. &lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m not clear on how cross-platform USB software tends to be. &amp;#039;&amp;#039;&amp;#039;This article currently assumes you&amp;#039;re running Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== The USB protocol ==&lt;br /&gt;
USB is a pretty complex protocol with a long specification, but it&amp;#039;s not necessary to understand every part of it to use it. It&amp;#039;s enough to know what wires to hook up and what software libraries to include in your code, and using USB will be easy. &lt;br /&gt;
&lt;br /&gt;
Wikipedia has a detailed and informative [http://en.wikipedia.org/wiki/Usb page on USB]. &lt;br /&gt;
&lt;br /&gt;
USB connectors have four leads; the pictures on Wikipedia show which is which on standard connectors.&lt;br /&gt;
* +5V: the host [computer] provides up to 500mA of current at 5V that you can use for power. If your PIC is self-powered, though, make sure you don&amp;#039;t connect the two +5V sources or bad things may happen.&lt;br /&gt;
* GND: ground; make sure you do connect this to your PIC&amp;#039;s ground.&lt;br /&gt;
* D+ and D-: data is transmitted on these lines. The exact protocol is complicated and you probably don&amp;#039;t need to know the details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB with the PIC 18F4553 ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
On the 18f4553, the D+ line connects to pin RC5 and the D- line to pin RC4. The ground line of course connects to ground.&lt;br /&gt;
&lt;br /&gt;
Additionally pin 18, called Vusb, should have a capacitor to ground. Try 220 or 470nF.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
On the software side you have some choices. Probably the simplest thing to do is use a preexisting software library that makes the USB connection look like an [[PIC RS232|RS232 connection]]. The CCS compiler has a CDC library that provides functions like usb_cdc_getc or usb_cdc_putc that work over USB exactly like regular getc and putc work over RS232. CCS also provides a Windows driver for the PC that creates a virtual COM port that you can open in Matlab or Hyperterminal and use to talk to the PIC. See [USB communication with CCS]].&lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework that works with its C18 compiler and its MPLAB development environment. See [[USB communication with C18 and MPLAB]].&lt;br /&gt;
&lt;br /&gt;
CCS also has an example where the PIC registers itself as a Human Interface Device (HID). USB mice and keyboards use HID. The advantage of this is that doesn&amp;#039;t require the user to install a special driver. The disadvantages are (a) the connection doesn&amp;#039;t look like a simple RS232 link and (b) bandwidth is limited. A HID can only send messages to the computer once every millisecond, and can only send 64 bytes in each message, so the maximum data transfer rate is 64K bytes/second. In theory, USB can go up to 12M bits/second, so HID is fairly slow in comparison. &lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework for use with its [[PIC Microcontrollers with C18 Compiler|C18 compiler]]. &lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also possible to create one&amp;#039;s own setup from scratch or by modifying a preexisting library. This probably takes some effort.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=SPI_communication_between_PICs&amp;diff=13230</id>
		<title>SPI communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=SPI_communication_between_PICs&amp;diff=13230"/>
		<updated>2009-05-05T07:53:29Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Overview ==&lt;br /&gt;
SPI or [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus Serial Peripheral Interface] is a communication method that was once used to connect devices such as printers, cameras, scanners, etc. to a desktop computer. This function has largely  been taken over by USB, but SPI can still be a useful communication tool for some applications. SPI runs using a master/slave set-up and can run in full duplex mode, meaning that signals can be transmitted between the master and the slave simultaneously. There is no standard communication protocol for SPI.&lt;br /&gt;
&lt;br /&gt;
SPI is still used to control some peripheral devices and has some advantages over [[I2C communication between PICs|I2C]] (another type of serial data communication). SPI can communicate at much higher data rates than I2C. Furthermore, when multiple slaves are present, SPI requires no addressing to differentiate between these slaves. Compared to parallel buses, SPI has the additional benefit of requiring only simple wiring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Peripheral devices that still use SPI:&lt;br /&gt;
&lt;br /&gt;
•	Converters (ADC and DAC)&lt;br /&gt;
&lt;br /&gt;
•	Memories (EEPROM and FLASH)&lt;br /&gt;
&lt;br /&gt;
•	Real Time Clocks (RTC)&lt;br /&gt;
&lt;br /&gt;
•	Sensors (temperature, pressure, etc.)&lt;br /&gt;
&lt;br /&gt;
•	Others (signal mixer, potentiometer, LCD controller, UART, CAN controller, USB controller, amplifier)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Basic Operation&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SPI requires four lines, and is therefore often termed the “four wire” serial bus. These four lines are described in the table below.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;2&amp;quot; cellpadding=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Line!! Name!! Description&lt;br /&gt;
|-&lt;br /&gt;
|SCLK||Serial Clock||Output from master&lt;br /&gt;
|-&lt;br /&gt;
|MOSI/SIMO||Master Output, Slave Input||Output from master&lt;br /&gt;
|-&lt;br /&gt;
|MISO/SOMI||Master Input, Slave Output||Output from slave&lt;br /&gt;
|-&lt;br /&gt;
|SS||Slave Select||Output from master (active low)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The master, as its name suggests, controls all communication. By controlling the clock, the master decides when data is sent and received. Within each clock cycle a full duplex communication is carried out; each side sends and receives one bit of information. Because there is no standard communication protocol, the master can either send data or both send and receive data, depending on the needs of the application. Likewise, the slave can either receive data or both receive and send data back to the master.&lt;br /&gt;
&lt;br /&gt;
Using the “Slave Select” line, the master chooses which slave with which to communicate. Note that more than one slave may be selected, simply by applying a logic low to the desired SS lines, as illustrated in the schematic diagram shown above. If a given slave is not selected (its SS is high) it disregards signals sent by the master. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;References&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://www.totalphase.com/support/articles/article03/ SPI Background](www.totalphase.com)&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI Wikipedia Article] (www.wikipedia.org)&lt;br /&gt;
&lt;br /&gt;
[http://www.mct.net/faq/spi.html More Information] (www.mct.net)&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&amp;lt;b&amp;gt;Master connected to three slaves:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:spi-diagram.png]]&lt;br /&gt;
&lt;br /&gt;
Here each slave must be enabled through the slave select pin in order to communicate with the Master. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;One PIC master and one PIC slave:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:spi.jpg]]&lt;br /&gt;
&lt;br /&gt;
The master, on the left, and the slave, on the right, are connected as shown above. Be sure you also connect grounds!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
SPI communication on the PIC is accomplished via the functions spi_read() and spi_write(), which read and write one byte at a time over SPI. In the example below, the master reads an 8-bit value from the analog-to-digital converter and sends it to the slave via SPI. The slave reads the value and displays it on an LCD display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The code given below does not work perfectly: the slave failed to received 10-20% of the messages sent by the master. In this example that failure rate was not critical, as the slave just missed an update of the ADC reading when it missed a message. If more accurate data transmission is required, the failure rate inherent in this system may be unacceptable. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SPI Mode Numbers&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are four SPI &amp;quot;modes&amp;quot; which describe the relationship between the phase of the clock line and the phase of the MISO/MOSI lines. In order to successfully communicate using SPI, the master and slave must operate using the same mode. [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_Numbers Wikipedia] has a good explanation of these mode numbers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;The Slave Select Line&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to being used to select which slave is active during a communication, the slave select (SS) line, is vital for synchronization. A slave&amp;#039;s SS line should be high except when the master is talking to it. When the SS line is pulled low, the slave knows that a new communication is starting. &lt;br /&gt;
&lt;br /&gt;
If a slave fails to receive a message properly, it will be reset when the SS line goes high at the end of the message and the slave will be prepared for a new message when the SS line goes low again. If the SS line is not used (e.g. by disabling it or running it directly to ground) there is a risk of the slave becoming out of sync with the master; if the slave misses a bit, it will always be one bit off in the future. Effective use of the SS line allows the slave and master to realign themselves at the beginning of each communication, in case of a transmission error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master Code:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#fuses EC,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#device ADC=8&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
&lt;br /&gt;
//These define the different SPI modes in terms of constants the compiler knows about&lt;br /&gt;
//NOTE: our PICs only seemed to work in modes 1 and 3, though they are supposed to work with any modes&lt;br /&gt;
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)&lt;br /&gt;
#define SPI_MODE_1 (SPI_L_TO_H)&lt;br /&gt;
#define SPI_MODE_2 (SPI_H_TO_L)&lt;br /&gt;
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) &lt;br /&gt;
&lt;br /&gt;
#define SS_PIN PIN_D0         //this can be any output pin on the master&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   int val;&lt;br /&gt;
&lt;br /&gt;
   //Set up the ADC to read from A0&lt;br /&gt;
   setup_adc_ports(AN0);&lt;br /&gt;
   setup_adc(ADC_CLOCK_INTERNAL);&lt;br /&gt;
   set_adc_channel(0);&lt;br /&gt;
&lt;br /&gt;
   //The next statement sets up the SPI hardware, with this PIC as a master using mode 1&lt;br /&gt;
   //SPI_CLK_DIV_64 sets the speed of the SPI clock pulses--this is the slowest speed&lt;br /&gt;
   setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_64); &lt;br /&gt;
   &lt;br /&gt;
   while(true) {&lt;br /&gt;
       val = read_adc();      //read the value to be sent&lt;br /&gt;
       &lt;br /&gt;
       output_low(SS_PIN);    //pull the slave select line low to select the slave&lt;br /&gt;
       delay_us(10);          //give the slave time to notice this (may be unnecessary)&lt;br /&gt;
       &lt;br /&gt;
       spi_write(val);        //send the value&lt;br /&gt;
       &lt;br /&gt;
       delay_us(10);          //(may be unnecessary)&lt;br /&gt;
       output_high(SS_PIN);   //deselect the slave. &lt;br /&gt;
       &lt;br /&gt;
       delay_ms(10);&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave Code:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#fuses EC,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;LCD.C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)&lt;br /&gt;
#define SPI_MODE_1 (SPI_L_TO_H)&lt;br /&gt;
#define SPI_MODE_2 (SPI_H_TO_L)&lt;br /&gt;
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   setup_spi(SPI_SLAVE | SPI_MODE_1); //set up SPI hardware as a slave in mode 1&lt;br /&gt;
   &lt;br /&gt;
   lcd_init();&lt;br /&gt;
   &lt;br /&gt;
   while(true) {&lt;br /&gt;
       val = spi_read(0); //spi_read must be passed an argument. The argument value is sent&lt;br /&gt;
                          //back to the master whenever the master sends us a message again. &lt;br /&gt;
                          //This allows two-way communication, but here the master ignores&lt;br /&gt;
                          //whatever the slave sends back, so just send a 0.&lt;br /&gt;
&lt;br /&gt;
       //display the value read:&lt;br /&gt;
       lcd_gotoxy(1, 1);&lt;br /&gt;
       printf(lcd_putc, &amp;quot;Pot at: %u   &amp;quot;, val);&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Alternative Slave Code, Using Interrupts:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#fuses EC,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;LCD.C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)&lt;br /&gt;
#define SPI_MODE_1 (SPI_L_TO_H)&lt;br /&gt;
#define SPI_MODE_2 (SPI_H_TO_L)&lt;br /&gt;
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)&lt;br /&gt;
&lt;br /&gt;
#int_ssp //this interrupt will occur whenever we receive an SPI message (or an I2C message, actually)&lt;br /&gt;
void message_receieved() {&lt;br /&gt;
    unsigned int val;&lt;br /&gt;
&lt;br /&gt;
    val = spi_read(); //When you don&amp;#039;t pass an argument, spi_read just returns the most&lt;br /&gt;
                      //recently received SPI message. We can do this here because we know&lt;br /&gt;
                      //that we just received a new message.&lt;br /&gt;
&lt;br /&gt;
    //display the value:&lt;br /&gt;
    lcd_gotoxy(1, 1);&lt;br /&gt;
    printf(lcd_putc, &amp;quot;Pot at: %u   &amp;quot;, val);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   setup_spi(SPI_SLAVE | SPI_MODE_1); //setup the PIC as a slave in mode 1&lt;br /&gt;
   enable_interrupts(INT_SSP); //enable interrupts on SPI messages&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
   &lt;br /&gt;
   lcd_init();&lt;br /&gt;
   &lt;br /&gt;
   while(true); //sit and wait for a message&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Two-way communication [This code has not been successfully tested!]&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Though not shown above, it is possible to use SPI for two-way communication between master and slave. If the slave calls&lt;br /&gt;
&amp;lt;pre&amp;gt;message_from_master = spi_read(123);&amp;lt;/pre&amp;gt;&lt;br /&gt;
It will wait for the master to send some clock pulses; when the clock pulses come the slave will simultaneously read the message being sent by the master and send its own message (the number 123). The master, for its part, will call&lt;br /&gt;
&amp;lt;pre&amp;gt;message_from_slave = spi_read(22);&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will cause the master to send the number 22 to the slave and simultaneously read the message sent back by the slave (in this case the number 123). So the master and slave have exchanged one byte of information. If you are the master and you just want to get a byte from the slave without sending one, just send a junk value, which the slave will discard: &lt;br /&gt;
&amp;lt;pre&amp;gt;message_from_slave = spi_read(0);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Useful resources&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CCS user manual&lt;br /&gt;
&lt;br /&gt;
[http://www.ccsinfo.com/forum/ CCS forum]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus Wikipedia article]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13159</id>
		<title>USB bootloading</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_bootloading&amp;diff=13159"/>
		<updated>2009-04-27T01:51:20Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;This article assumes you are using Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Bootloading allows you to reprogram your PIC without the need for an expensive hardware programmer like an ICD. &lt;br /&gt;
&lt;br /&gt;
Bootloading works like this:&lt;br /&gt;
* You compile your program on the computer, which generates a file with a .hex extension. This is the compiled code for your program, which you want to get onto the PIC. &lt;br /&gt;
* You connect the PIC to the computer, in this case with a simple USB cable. &lt;br /&gt;
* You fire up a PC program that takes your hex file and sends it to the PIC.&lt;br /&gt;
* Sitting on the PIC there is a small program called a bootloader. It takes the hex file that is coming from the computer and writes it into memory. &lt;br /&gt;
* You reset the PIC, and your program starts running!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB Bootloading with the [[PIC 18f4553]] ==&lt;br /&gt;
USB bootloading is bootloading over a USB cable. To do this you need to be working with a PIC that talks USB, like an 18f4553. Then you need to have a bootloader on the PIC. The only way to put a bootloader in place is with a hardware programmer like an ICD, but you only need to do this once: afterwards, all you&amp;#039;ll need is a regular USB cable. See [[USB communication with PC|here]] for how to connect a USB cable to a PIC.&lt;br /&gt;
&lt;br /&gt;
=== Loading the bootloader ===&lt;br /&gt;
Here is a USB bootloader hex file that works for the 18f4553 with a 20Mhz oscillator: [[Image:FW_B_20.hex]]. It comes from http://www.schmalzhaus.com/UBW , where you can find the source it was built from, if you&amp;#039;re interested.&lt;br /&gt;
To load this precompiled hex file onto the PIC using the CCS ICD, use the icd.exe program in the C:\Program Files\PICC directory. Now the bootloader is itself loaded.&lt;br /&gt;
&lt;br /&gt;
=== The PC software ===&lt;br /&gt;
There needs to be a program on the PC that sends your hex files to bootloader on the PIC. This bootloader uses a program from the Microchip USB Framework. You can download the framework installer [http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe here]. It will create some folders in the C:\ directory. The loader program is at C:\MCHPFSUSB\Pc\Pdfsusb\PDFSUSB.exe.&lt;br /&gt;
&lt;br /&gt;
=== Required circuitry ===&lt;br /&gt;
You need some sort of button or switch hooked up to pin RC2 so that it is normally high. If you reset the PIC and pin RC2 is high, the bootloader will run whatever program you&amp;#039;ve loaded onto it. But if RC2 is low, because you&amp;#039;re pressing the button, the bootloader will run, allowing you to load a new program onto the PIC. You don&amp;#039;t need to keep holding the button down, C2 just has to be low at the time the PIC resets. So whenever you want to put the PIC into bootloader mode, press and hold the reset button, then press your bootloading button, then release the reset button, then release the bootloading button. You can attach an LED to pin RC1 and the bootloader will flash it when it runs. &lt;br /&gt;
&lt;br /&gt;
=== Installing Drivers ===&lt;br /&gt;
When you first connect the PIC to the PC and make the bootloader run, Windows will need to install a driver. Point it to &amp;quot;C:\MCHPFSUSB\Pc\MCHPUSB Driver\Release&amp;quot; and it will install the right driver. Now you&amp;#039;re all set up.&lt;br /&gt;
&lt;br /&gt;
=== Compiling for a bootloader ===&lt;br /&gt;
A bootloader takes up part of the available program memory, and you need to take this into account when you write your program. Generally, the bootloader takes up a small chunk of memory at the beginning of space available for program memory. You need to tell the compiler to place your code just after the bootloader. Our bootloader takes up the memory from 0x000 to 0x7FF (the first two kilobytes of program memory). Your program therefore needs to start at address 0x800 and not touch the memory from 0x000 to 0x7FF. You can accomplish this by adding the following two lines at the top of your code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#build (reset=0x800, interrupt=0x808)  //code starts right after the bootloader&lt;br /&gt;
#org 0, 0x7FF {}                       //don&amp;#039;t overwrite the bootloader&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootloading ===&lt;br /&gt;
Now that everything&amp;#039;s set up, here are the steps to load your program onto your PIC:&lt;br /&gt;
&lt;br /&gt;
* Compile your program with the two lines mentioned above.&lt;br /&gt;
* Fire up PDFSUSB.exe. &lt;br /&gt;
* Put your PIC into bootloading mode. You should now be able to select &amp;quot;PICDEM FS USB 0&amp;quot; from the PDFSUSB.exe drop-down list.&lt;br /&gt;
* Click &amp;quot;Load Hex File&amp;quot; and go find the hex file that you created when you compiled your program.&lt;br /&gt;
* Click &amp;quot;Program Device&amp;quot; to load your program. &lt;br /&gt;
* Reset your PIC and your program should run.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[Wireless PIC bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13158</id>
		<title>USB communication with PC</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=USB_communication_with_PC&amp;diff=13158"/>
		<updated>2009-04-27T01:51:03Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some PIC models have built-in USB transceivers that make it simple to connect the PIC to a computer via USB. One such PIC is the [[PIC 18f4553]], which is similar to the 18f4520 in almost all respects, except that it has hardware support for USB built into it. The 18f4553 will work just fine in one of the [[4520_Board_intro|PIC protoboards]]. &lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m not clear on how cross-platform USB software tends to be. &amp;#039;&amp;#039;&amp;#039;This article currently assumes you&amp;#039;re running Windows.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== The USB protocol ==&lt;br /&gt;
USB is a pretty complex protocol with a long specification, but it&amp;#039;s not necessary to understand every part of it to use it. It&amp;#039;s enough to know what wires to hook up and what software libraries to include in your code, and using USB will be easy. &lt;br /&gt;
&lt;br /&gt;
Wikipedia has a detailed and informative [http://en.wikipedia.org/wiki/Usb page on USB]. &lt;br /&gt;
&lt;br /&gt;
USB connectors have four leads; the pictures on Wikipedia show which is which on standard connectors.&lt;br /&gt;
* +5V: the host [computer] provides up to 500mA of current at 5V that you can use for power. If your PIC is self-powered, though, make sure you don&amp;#039;t connect the two +5V sources or bad things may happen.&lt;br /&gt;
* GND: ground; make sure you do connect this to your PIC&amp;#039;s ground.&lt;br /&gt;
* D+ and D-: data is transmitted on these lines. The exact protocol is complicated and you probably don&amp;#039;t need to know the details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USB with the PIC 18F4553 ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
On the 18f4553, the D+ line connects to pin RC5 and the D- line to pin RC4. The ground line of course connects to ground.&lt;br /&gt;
&lt;br /&gt;
Additionally pin 18, called Vusb, should have a capacitor to ground. Try 220 or 470nF.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
On the software side you have some choices. Probably the simplest thing to do is use a preexisting software library that makes the USB connection look like an [[PIC RS232|RS232 connection]]. The CCS compiler has a CDC library that provides functions like usb_cdc_getc or usb_cdc_putc that work over USB exactly like regular getc and putc work over RS232. CCS also provides a Windows driver for the PC that creates a virtual COM port that you can open in Matlab or Hyperterminal and use to talk to the PIC.&lt;br /&gt;
&lt;br /&gt;
A sample program using CCS&amp;#039;s CDC library is shown below. The program waits for some input and then responds to it. When you first plug in the PIC to the computer, Windows will need to install a driver to talk to it. If you&amp;#039;re running XP or earlier, point it to the directory C:\Program Files\PICC\Drivers, where it will find what it needs. If you&amp;#039;re running Vista the driver may not be there; download [[Image:Cdc_NTXPVista.inf]], save it somewhere, and point Windows to it. Once the driver is installed a virtual COM port will be created (it will be visible in the device manager) and you&amp;#039;ll be able to talk to the PIC in Hyperterminal, Matlab, or anything else that communications over RS232.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;lt;18f4550.h&amp;gt; //if your version of the compiler doesn&amp;#039;t support the 4553, you can put the 4550 in your code, which is almost exactly the same.&lt;br /&gt;
#use delay(clock=48000000) //because of tricky fuses a 20Mhz oscillator will make the PIC run at 48Mhz&lt;br /&gt;
#fuses HS, NOWDT, NOLVP, NOPROTECT //standard fuses&lt;br /&gt;
&lt;br /&gt;
//these fuses are critical. they assume a 20Mhz oscillator:&lt;br /&gt;
#fuses PLL5     //The USB module must run at 48Mhz. This tells the PIC to take the oscillator, divide the frequency by 5, then multiply by 12. The result must be 48Mhz. &lt;br /&gt;
#fuses HSPLL    //I&amp;#039;m not exactly sure what this fuses does, but it&amp;#039;s probably necessary.&lt;br /&gt;
#fuses VREGEN   //The USB module must run at 3.3V. This tells the PIC to accomplish this by using an internal voltage regulator.&lt;br /&gt;
#fuses CPUDIV1  //This tells the PIC to run at a frequency of 48Mhz / 1 = 48Mhz. It may or may not be necessary.&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;usb_cdc.h&amp;gt; //Include the CCS USB library. If you want to see all the functions available look at usb_cdc.h and usb.h.&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
   int c;&lt;br /&gt;
&lt;br /&gt;
   //these lines do some initialization, obviously:&lt;br /&gt;
   usb_cdc_init();&lt;br /&gt;
   usb_init();&lt;br /&gt;
   usb_wait_for_enumeration();   &lt;br /&gt;
&lt;br /&gt;
   while(true) {&lt;br /&gt;
       usb_task(); //handles connections to and disconnections from the computer, registering the PIC with the computer, etc. call this pretty often so that the PIC responds to being plugged in. &lt;br /&gt;
       &lt;br /&gt;
       if(usb_cdc_kbhit()) { //did we get some incoming data? &lt;br /&gt;
           c = usb_cdc_getc(); //get one character of input&lt;br /&gt;
           printf(usb_cdc_putc, &amp;quot;you typed: %c\r\n&amp;quot;, c); //print out a response over usb&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CCS also has an example where the PIC registers itself as a Human Interface Device (HID). USB mice and keyboards use HID. The advantage of this is that doesn&amp;#039;t require the user to install a special driver. The disadvantages are (a) the connection doesn&amp;#039;t look like a simple RS232 link and (b) bandwidth is limited. A HID can only send messages to the computer once every millisecond, and can only send 64 bytes in each message, so the maximum data transfer rate is 64K bytes/second. In theory, USB can go up to 12M bits/second, so HID is fairly slow in comparison. &lt;br /&gt;
&lt;br /&gt;
Microchip provides a USB framework for use with its [[PIC Microcontrollers with C18 Compiler|C18 compiler]]. &lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also possible to create one&amp;#039;s own setup from scratch or by modifying a preexisting library. This probably takes some effort.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13157</id>
		<title>PIC 18f4550</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13157"/>
		<updated>2009-04-27T01:50:32Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PIC 18f4553 is a chip very similar to the 18f4520, differing in two important respects:&lt;br /&gt;
*It has a built-in USB transceiver, so you can do USB communication with it.&lt;br /&gt;
*It has a 12-bit analog-digital converter (ADC) as opposed to a mere 10-bit one.&lt;br /&gt;
&lt;br /&gt;
== Programming the 18f4553 ==&lt;br /&gt;
If your version of the CCS compiler does not list the 4553 as a supported device, you can just program for the 4550, which is almost exactly the same except that it has only a 10-bit ADC. However you will need to update your ICD firmware so that it recognizes the PIC. Save this file to your &amp;quot;C:\Program Files\PICC&amp;quot; directory: [Image:icd-images-firmware-02-51.fw]. Then plug in your ICD and run &amp;quot;C:\Program Files\PICC\icd.exe&amp;quot;. Click &amp;quot;Update Firmware&amp;quot;, then select &amp;quot;Other&amp;quot; and browse to the file you save. Then hit &amp;quot;Ok&amp;quot; to update the firmware. &lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re programming for the 18f4550, when you hit Program in CCS you&amp;#039;ll need to confirm that it&amp;#039;s OK that the code wants a 18f4550 while the detected target is a 18f4553.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[USB communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13156</id>
		<title>PIC 18f4550</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13156"/>
		<updated>2009-04-27T01:50:01Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PIC 18f4553 is a chip very similar to the 18f4520, differing in two important respects:&lt;br /&gt;
*It has a built-in USB transceiver, so you can do USB communication with it.&lt;br /&gt;
*It has a 12-bit analog-digital converter (ADC) as opposed to a mere 10-bit one.&lt;br /&gt;
&lt;br /&gt;
== Programming the 18f4553 ==&lt;br /&gt;
If your version of the CCS compiler does not list the 4553 as a supported device, you can just program for the 4550, which is almost exactly the same except that it has only a 10-bit ADC. However you will need to update your ICD firmware so that it recognizes the PIC. Save this file to your &amp;quot;C:\Program Files\PICC&amp;quot; directory: [Image:icd-images-firmware-02-51.fw]. Then plug in your ICD and run &amp;quot;C:\Program Files\PICC\icd.exe&amp;quot;. Click &amp;quot;Update Firmware&amp;quot;, then select &amp;quot;Other&amp;quot; and browse to the file you save. Then hit &amp;quot;Ok&amp;quot; to update the firmware. &lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re programming for the 18f4550, when you hit Program in CCS you&amp;#039;ll need to confirm that it&amp;#039;s OK that the code wants a 18f4550 while the detected target is a 18f4553.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[USB Communication with PC]]&lt;br /&gt;
&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13155</id>
		<title>PIC 18f4550</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC_18f4550&amp;diff=13155"/>
		<updated>2009-04-27T01:49:44Z</updated>

		<summary type="html">&lt;p&gt;Gregory McGlynn: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PIC 18f4553 is a chip very similar to the 18f4520, differing in two important respects:&lt;br /&gt;
*It has a built-in USB transceiver, so you can do USB communication with it.&lt;br /&gt;
*It has a 12-bit analog-digital converter (ADC) as opposed to a mere 10-bit one.&lt;br /&gt;
&lt;br /&gt;
== Programming the 18f4553 ==&lt;br /&gt;
If your version of the CCS compiler does not list the 4553 as a supported device, you can just program for the 4550, which is almost exactly the same except that it has only a 10-bit ADC. However you will need to update your ICD firmware so that it recognizes the PIC. Save this file to your &amp;quot;C:\Program Files\PICC&amp;quot; directory: [Image:icd-images-firmware-02-51.fw]. Then plug in your ICD and run &amp;quot;C:\Program Files\PICC\icd.exe&amp;quot;. Click &amp;quot;Update Firmware&amp;quot;, then select &amp;quot;Other&amp;quot; and browse to the file you save. Then hit &amp;quot;Ok&amp;quot; to update the firmware. &lt;br /&gt;
&lt;br /&gt;
If you&amp;#039;re programming for the 18f4550, when you hit Program in CCS you&amp;#039;ll need to confirm that it&amp;#039;s OK that the code wants a 18f4550 while the detected target is a 18f4553.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[USB Communication with PIC]]&lt;br /&gt;
[[USB Bootloading]]&lt;/div&gt;</summary>
		<author><name>Gregory McGlynn</name></author>
	</entry>
</feed>