AlanMacek.com AlanMacek.com | Print | Contact Me
Alan's Corner of the Internet

USB and PIC Microprocessors 16C745 and 18F2455

From AlanMacek.com


Introduction

This page describes a project a colleague and I completed between September, 2000 and March, 2001 as part of the Engineering Physics degree program at the University of British Columbia.   In summary this project involved building a USB device using the PIC 16C745 microprocessor from Microchip.  The USB device consisted of a microphone, the microprocessor and other hardware and the device sent audio data to the host computer.

This page contains notes, links and code extracts from this project relating to USB, USB Human Interface Devices, the 16C745 microprocessor, and specifics of this project.  Hopefully this information will be helpful to your project.

Table of Contents


Result

We achieved our goal and built a working device.  This involved building the device hardware (microprocessor, microphone, and supporting electronics) and software (microprocessor code and host computer code).  Unfortunately, the relatively low sampling rate by the microprocessor in the analog-to-digital conversion process mangled the audio signal to make it indecipherable at the host computer, but loud/soft transitions were easily detected.

To top.

USB

USB (Universal Serial Bus) is a protocol that allows two way communication between peripheral devices and a host computer.  It is hot pluggable, allowing the device to be connected and/or removed while the computer is running.  There are lots of other features of USB.

The specifications for USB are available at www.usb.org.  Be warned that while this information is very thorough, it is not very practical for developing a device or software.  Technical documents are available at www.usb.org/developers/docs.html.

Here is a quick overview of what is involved in USB.

To top.

USB and Human Interface Devices (HID)

Human Interface Devices (HID) are a class of USB devices that give structure to the data that will transfered between the device and the host computer. During the enumeration process, the device describes the information that it can receive and send.  This allows a host computer to handle the data being received from the USB device without requiring a specially designed device driver.

The HID class is supposed to include devices such as a mouse, joystick, keyboard, etc. Because the host computer knows what the data means a device driver is not necessary for HID devices, the operating system can supply a generic HID driver. For instance, if you plug in a USB Mouse, it will immediately work because the OS knows how to interpret information received from a mouse.

Information on the HID class can be found at www.usb.org/developers/hidpage. You can see examples of HID descriptors starting on page 89 of the HID 1.1 spec from usb.org.

A very useful tool for designing HID class devices is the HID Descriptor Tool also available from usb.org. This tool allows you to put together the HID description and run it through the HID parser.

Some other useful tools are available from Intel University Press[1]. They include 'USB Single Step', 'USBView', 'HIDView' and the HID Descriptor Tool described above.

If you are using Visual C++, then the 'hview' sample program that comes with the Windows DDK is good for examining the HID descriptor and values. Unfortunately the program is more complicated than it needs to be and is not a good example of using the USB functions.

To top.

PIC 16C745

I used the PIC 16C745 from Microchip as the USB interface microcontroller. This chip belongs to a two chip family (along with the 16C765) called the 16c7xx.

The 16C745 is a 28 pin microprocessor operating at 24 Mhz. It has 8K of program memory, 256 bytes of RAM and 5 x 8bit analog inputs (the 16C765 has 40 pins and 8 analog inputs). The specifications are available from Microchip. The reference manual for the mid-range microprocessors is also useful.

Download the development environment from Microchip called MPLAB (freely available from Microchip's web site). Another necessary component is the USB firmware. The support files that I used seem to no longer exist on the Microchip web site being replaced by a more sophisticated USB example. The firmware includes the following pieces:

Warning: It has been a long time since I've worked on this project so I do not know if these files are complete or if they can be compiled directly.

Try to understand how the usb_main.asm file works. A couple of gotchas that you should watch out for are:

I used the PIC-Start programmer available from Microchip to program the 16C745.  Because this chip is not available in a flash version, a UV light is also required in order to erase the program before it can be reprogrammed.  If you are looking for a suitable third party programmer, look for those that have an external power supply of at least 12V.  Programmers that are powered from the USB or Serial port are NOT powerful enough for the non-flash microprocessors such as the 16C745.  I have used a programmer from http://www.kitsrus.com/ with success and they have programmers suitable for the 16C745.

To top.

Host Computer Code

Once a have is connect, you want to send and receive data from your applications. This document describes how you can do with using C in Visual C++. It is also possible to do this in Visual Basic (see below)

The following examples assume you are using Windows 2000. It should also work on Windows 98 but I'm not sure what the differences might be. Windows 95 did not fully support USB.  Linux also supports USB HID.

More information on these Windows API calls are available on the Microsoft web site. I used to have links directly to the appropriate page on the Microsoft MSDN website but Microsoft, in their wisdom, rearrange their website every 6 months or so, breaking all the links.  Compiling code to use these function calls requires that you install the Windows DDK (Device Development Kit) which used to be freely available from the Microsoft website (see below obtaining copies of the required dlls and header files.)

See the example code below for details on using these methods.

To top.

Visual Basic Code

Even though Visual Basic does not allow direct access to the API calls, you can convert the API calls into visual basic functions. A good source of examples is at the web site for the book USB by Example[1]. The files HIDinterface.bas and OSinterface.bas available from the book's web site demonstrate using the API calls in Visual Basic.

To top.

- -

Example Host Code

I have put together some library code which uses the above api's to connect to available HID USB devices.  The code returns a file handle to the USB device which allows a program to read and write data with the device just like with a regular file handle.  Note that this code is not a fully working program - it requires, at the minimum, a main function.

These file are known to compile under Visual C++ 5.0 on Windows 2000 with the Windows DDK installed. Make sure that the path to the file 'setupapi.h' is in your header file path (Project->Settings). You will also need to add 'setupapi.lib' and 'hid.lib' to list of libraries and ensure the path to these files is added to the library path for your project.

The code samples are:

You can either download the complete Windows DDK (which used to be available free from the Microsoft Website at http://www.microsoft.com/ddk/W2kDDK.htm or download just the few files actually needed for the sample code. These are from the Microsoft DDK which used to be freely available.
One person who found my code useful optimized my example code which removes some of the dependencies on the Windows DDK.  See Ross Bencina's P5 Glove Project for details.

A visitor to my site, Jim Koornneef, has provided a C++ class wrapper for my code that you can download from usb.h and usb.cpp.  This class encapsulates the functionality in my code but also provides read/write methods and automatic connect/disconnect functionality.

To top.

Project Hardware

This section describes the hardware specific to my project.  Please note that the focus of this page is on the USB aspects of the project.  My understanding is that the analog circuity for the microphone is not well designed.

The analog signal from the microphone was amplified using an op-amp and then digitized using the 16C745's analog-to-digital feature.  If you are reproducing this project, I would recommend putting in a filter to remove the frequencies higher than the microprocessor's sampling rate.  The digital data was buffered in the microprocessor and then set to the host computer over the USB connection.  Since 'interrupt' method of transfer only allows 8 bytes of data transfered every 10ms, this limited the amount of data that could be transfered.

The following circuit connects the PIC to the usb cable. It is designed to be powered off the USB cable. The 6 MHz clock controls the internal oscillator.

The 'reset' switch, causes a reset condition which should cause most of the special registers to clear and the program to start again.

The value of R1 is not critical since it is only used as a pull-up for the MCLR (master clear) pin. The R2 resister is required by the USB specification and should be 1.5 kOhms. The capacitor C3, is not critical and simply stabilizes the Vusb pin voltage. The values of the capacitors, C1 and C2 can be in a range specified in the 16C745 specification (15pf - 69 pf) and may depend on the crystal that you use.

Check that USB power and ground connections are correct before connecting the chip. It is easy to get turn around between the cable pinout and the socket pin out.

Circuit Diagram showing USB connections

The following circuit is used to power the electret microphone and then amplify the signal. The output signal is connected to one of the analog pins of the 16C745, we used pin 2, corresponding to AN0 (analog pin 0).
Microphone Powering Circuit

The components are

The left side of the circuit is copied from http://www.hut.fi/Misc/Electronics/circuits/microphone_powering.html and the right side amplifies the signal 500 times (1 + R4/R3) using the op amp.

Update: a visitor to the site made the following suggestion to improve the circuit to allow the Op Amp to amplify the negative portion of the signal. 'Romano' said, "You should (if you want, of course), put a resistor between (+) of op-amp and Vcc, call it R2a, 6.8kohm will be good. R2 should be 6.8k again, so without mic signal you will have Vcc/2 at (+). Finally disconnect R3 from GND and put a capacitor (1uf or more) between R3 and GND. Without signal you will get Vcc/2 at the input of A/D."

Further update (06/09/27): Tito wrote me to suggest improvements to the amplifer. He made the following suggestion, "I noticed that your audio amplifier is not well polarized. I think it has big distortions because it only amplifies the positive part of the signal. I recommend using a negative amplifier configuration for the OPAMP. You just need to add a voltage divisor and a filter to polarize the OPAMP inputs."

To top.

Links

To top.


Main Page:
AlanMacek.com
Popular Pages:
USB
CPR in BC
USB & PICs:
16C745 & 16C765
18F series


Table Of Contents: