?? usb in a nutshell - chapter 7 - pdiusbd11 and pic16f87x example.htm
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0047)http://www.beyondlogic.org/usbnutshell/usb7.htm -->
<HTML><HEAD><TITLE>USB in a NutShell - Chapter 7 - PDIUSBD11 and PIC16F87x Example</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META
content="Shows an example Schematic and C Source Code of a PDIUSBD11 I2C USB Device connected to a Microchip PIC16F876 Microcontroller."
name=description>
<META
content="PDIUSBD11, PIC16F87x, PIC16F877, PIC16F876, USB, Tutorial, USB Tutorial, USB Primer, Universal Serial Bus, Enumeration, C Source Code, HiTech PICC"
name=keywords>
<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY leftMargin=0
background="USB in a NutShell - Chapter 7 - PDIUSBD11 and PIC16F87x Example.files/bgyellow.gif"
topMargin=0 FACE="ARIAL" BASEFONT marginwidth="0" marginheight="0">
<STYLE type=text/css>#TITLEBLOCK {
COLOR: #ffffff; TEXT-DECORATION: none
}
TD {
FONT-FAMILY: Arial
}
P {
FONT-FAMILY: Arial
}
FONT {
FONT-FAMILY: Arial
}
A {
FONT-FAMILY: Arial
}
LI {
FONT-FAMILY: Arial
}
B {
FONT-FAMILY: Arial
}
PRE {
COLOR: #100080
}
TT {
COLOR: #100080
}
</STYLE>
<BR>
<CENTER>
<TABLE width="95%" BOARDER="0">
<TBODY>
<TR>
<TD width="25%">
<CENTER><A href="http://www.beyondlogic.org/"><IMG alt="Beyond Logic"
src="USB in a NutShell - Chapter 7 - PDIUSBD11 and PIC16F87x Example.files/beyondsmall.gif"
border=0></A></CENTER></TD>
<TD width="50%">
<CENTER>
<SCRIPT type=text/javascript><!--google_ad_client = "pub-7725444460812017";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_type = "text_image";google_ad_channel ="";google_color_border = "0033FF";google_color_bg = "FFFFFF";google_color_link = "0000FF";google_color_url = "008000";google_color_text = "000000";//--></SCRIPT>
<SCRIPT
src="USB in a NutShell - Chapter 7 - PDIUSBD11 and PIC16F87x Example.files/show_ads.js"
type=text/javascript></SCRIPT>
<NOSCRIPT><FONT color=red>This page is optimised with JavaScript 1.2.
Currently your browser has JavaScript switched off.</NOSCRIPT>
</CENTER></FONT></TD>
<TD vAlign=center align=right><BR><FONT face=ARIAL>
<SCRIPT language=javascript
src="USB in a NutShell - Chapter 7 - PDIUSBD11 and PIC16F87x Example.files/beyondmenu_plain.js"></SCRIPT>
<NOSCRIPT></FONT></TD></TR></TBODY></TABLE></CENTER></NOSCRIPT>
<CENTER><BR><BR><FONT color=green size=6>USB in a NutShell</FONT><BR><BR><FONT
color=blue size=4><I>Making Sense of the USB Standard</I></FONT>
<TABLE width="95%">
<TBODY>
<TR>
<TD>
<UL><A name=Enumeration><FONT color=green
size=3><B>Enumeration</B></FONT></A>
<UL>
<P>Enumeration is the process of determining what device has just been
connected to the bus and what parameters it requires such as power
consumption, number and type of endpoint(s), class of product etc. The
host will then assign the device an address and enable a configuration
allowing the device to transfer data on the bus. A fairly generic
enumeration process is detailed in section 9.1.2 of the USB
specification. However when writing USB firmware for the first time,
it is handy to know exactly how the host responds during enumeration,
rather than the general enumeration process detailed in the
specification. </P>
<P>A common Windows enumeration involves the following steps, </P>
<OL>
<LI>The host or hub detects the connection of a new device via the
device's pull up resistors on the data pair. The host waits for at
least 100ms allowing for the plug to be inserted fully and for power
to stabilise on the device. <BR><BR>
<LI>Host issues a reset placing the device is the default state. The
device may now respond to the default address zero. <BR><BR>
<LI>The MS Windows host asks for the first 64 bytes of the Device
Descriptor. <BR><BR>
<LI>After receiving the first 8 bytes of the Device Descriptor, it
immediately issues another bus reset. <BR><BR>
<LI>The host now issues a Set Address command, placing the device in
the addressed state. <BR><BR>
<LI>The host asks for the entire 18 bytes of the Device Descriptor.
<BR><BR>
<LI>It then asks for 9 bytes of the Configuration Descriptor to
determine the overall size. <BR><BR>
<LI>The host asks for 255 bytes of the Configuration Descriptor.
<BR><BR>
<LI>Host asks for any String Descriptors if they were specified.
</LI></OL>
<P>At the end of Step 9, Windows will ask for a driver for your
device. It is then common to see it request all the descriptors again
before it issues a Set Configuration request. </P>
<P>The above enumeration process is common to Windows 2000, Windows XP
and Windows 98 SE. </P>
<P>Step 4 often confuses people writing firmware for the first time.
The Host asks for the first 64 bytes of the device descriptor, so when
the host resets your device after it receives the first 8 bytes, it is
only natural to think there is something wrong with your device
descriptor or how your firmware handles the request. However as many
will tell you, if you keep persisting by implementing the Set Address
Command it will pay off by asking for a full 18 bytes of device
descriptor next. </P>
<P>Normally when something is wrong with a descriptor or how it is
being sent, the host will attempt to read it three times with long
pauses in between requests. After the third attempt, the host gives up
name=PIC16F876Example><FONT color=green size=3><B>Firmware - PIC16F876
controlling the PDIUSBD11</B></FONT></A>
<UL>
<P>We start our examples with a Philip's PDIUSBD11 I2C Serial USB
Device connected to a MicroChip PIC16F876 (shown) or a Microchip
PIC16F877 (Larger 40 Pin Device). While Microchip has got two low
speed USB PIC16C745 and PIC16C765 devices out now, they are only OTP
without In-Circuit Debugging (ICD) support which doesn't help with the
development flow too well. They do have <A
href="http://www.beyondlogic.org/usb/usbhard.htm#Microchip">four new
full speed flash devices</A> with (ICD) support coming. In the mean
time the Philips PDIUSBD11 connected to the PIC16F876 which gives the
advantage of Flash and In-Circuit Debugging. </P>
<CENTER><A
href="http://www.beyondlogic.org/usbnutshell/pic16f876.gif"><IMG
src="USB in a NutShell - Chapter 7 - PDIUSBD11 and PIC16F87x Example.files/pic16f876thumb.gif"
border=0></A> <BR><A
href="http://www.beyondlogic.org/usbnutshell/pic16f876.gif">Click here
to enlarge</A></CENTER>
<P>A schematic of the required hardware is shown above. The example
enumerates and allows analog voltages to be read from the five
multiplexed ADC inputs on the PIC16F876 MCU. The code is compatible
with the PIC16F877 allowing a maximum of 8 Analog Channels. A LED
connected on port pin RB3 lights when the device is configured. A 3.3V
regulator is not pictured, but is required for the PDIUSBD11. If you
are running the example circuit from an external power supply, then
you can use a garden variety 78L033 3.3V voltage regulator, however if
you wish to run the device as a Bus Powered USB device then a low
dropout regulator needs to be sought. </P>
<P>Debugging can be done by connecting TXD (Pin 17) to a RS-232 Line
Driver and fed into a PC at 115,200bps. Printf statements have been
included which display the progress of enumeration. </P>
<P>The code has been written in C and compiled with the <A
href="http://www.htsoft.com/">Hi-Tech PICC Compiler</A>. They have a
<A href="http://www.htsoft.com/software/index.html">demo version (7.86
PL4)</A> of the PICC for download which works for 30 days. A
pre-compiled .HEX file has be included in the archive which has been
compiled for use with (or without) the ICD. </P><PRE>#include <pic.h>
#include <stdio.h>
#include <string.h>
#include "usbfull.h"
const USB_DEVICE_DESCRIPTOR DeviceDescriptor = {
sizeof(USB_DEVICE_DESCRIPTOR), /* bLength */
TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */
0x0110, /* bcdUSB USB Version 1.1 */
0, /* bDeviceClass */
0, /* bDeviceSubclass */
0, /* bDeviceProtocol */
8, /* bMaxPacketSize 8 Bytes */
0x04B4, /* idVendor (Cypress Semi) */
0x0002, /* idProduct (USB Thermometer Example) */
0x0000, /* bcdDevice */
1, /* iManufacturer String Index */
0, /* iProduct String Index */
0, /* iSerialNumber String Index */
1 /* bNumberConfigurations */
};
</PRE>
<P>The structures are all defined in the header file. We have based
this example on the Cypress USB Thermometer example so you can use our
<A href="http://www.beyondlogic.org/usb/cypress.htm">USB Driver for
the Cypress USB Starter Kit</A>. A new generic driver is being written
to support this and other examples which will be available soon. Only
one string is provided to display the manufacturer. This gives enough
information about how to implement string descriptors without filling
up the entire device with code. A description of the Device Descriptor
and its fields can be found <A
href="http://www.beyondlogic.org/usbnutshell/usb5.htm#DeviceDescriptors">here.</A>
</P><PRE>const USB_CONFIG_DATA ConfigurationDescriptor = {
{ /* configuration descriptor */
sizeof(USB_CONFIGURATION_DESCRIPTOR), /* bLength */
TYPE_CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
sizeof(USB_CONFIG_DATA), /* wTotalLength */
1, /* bNumInterfaces */
1, /* bConfigurationValue */
0, /* iConfiguration String Index */
0x80, /* bmAttributes Bus Powered, No Remote Wakeup */
0x32 /* bMaxPower, 100mA */
},
{ /* interface descriptor */
sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */
TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */
0, /* bInterface Number */
0, /* bAlternateSetting */
2, /* bNumEndpoints */
0xFF, /* bInterfaceClass (Vendor specific) */
0xFF, /* bInterfaceSubClass */
0xFF, /* bInterfaceProtocol */
0 /* iInterface String Index */
},
{ /* endpoint descriptor */
sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
0x01, /* bEndpoint Address EP1 OUT */
0x02, /* bmAttributes - Interrupt */
0x0008, /* wMaxPacketSize */
0x00 /* bInterval */
},
{ /* endpoint descriptor */
sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
0x81, /* bEndpoint Address EP1 IN */
0x02, /* bmAttributes - Interrupt */
0x0008, /* wMaxPacketSize */
0x00 /* bInterval */
}
};
</PRE>
<P>A description of the Configuration Descriptor and its fields can be
found <A
href="http://www.beyondlogic.org/usbnutshell/usb5.htm#ConfigurationDescriptors">here.</A>
We provide two endpoint descriptors on top of the default pipe. EP1
OUT is an 8 byte maximum Bulk OUT Endpoint and EP1 IN is an 8 byte max
Bulk IN Endpoint. Our example reads data from the Bulk OUT endpoint
and places it in an 80 byte circular buffer. Sending an IN packet to
EP1 reads 8 byte chunks from this circular buffer. </P><PRE>LANGID_DESCRIPTOR LANGID_Descriptor = { /* LANGID String Descriptor Zero */
sizeof(LANGID_DESCRIPTOR), /* bLenght */
TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
0x0409 /* LANGID US English */
};
const MANUFACTURER_DESCRIPTOR Manufacturer_Descriptor = { /* ManufacturerString 1 */
sizeof(MANUFACTURER_DESCRIPTOR), /* bLenght */
TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
"B\0e\0y\0o\0n\0d\0 \0L\0o\0g\0i\0c\0" /* ManufacturerString in UNICODE */
};
</PRE>
<P>A Zero Index <A
href="http://www.beyondlogic.org/usbnutshell/usb5.htm#StringDescriptors">String
Descriptor</A> is provided to support the LANGID requirements of USB
String Descriptors. This indicates all descriptors are in US English.
The Manufacturer Descriptor can be a little deceiving as the size of
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -