The PIC microcontroller can be made more useful by adding peripherals to it that perform different functions. This is necessary if you are using a controller such as the PIC16C505 or the PIC12C509 that have limited capabilities. While it is possible to buy microcontrollers with such peripherals as serial ports, A/D convertors, etc., built in, it is often more economical to simply add the peripherals that are needed. This document describes (very briefly) how to connect some of these devices to the PIC.The peripherals discussed here are:
A good resource for help with the PIC programmed with the CCS C-compiler is given at www.ccsinfo.com/wwwboard.
Interfacing to the National Semiconductor ADC0831
The ADC0831 is a simple single channel, 8 bit A/D convertor that is easily connected to the PIC microcontroller, made by National Semiconductor. There is a slightly more complex convertor in the same family, the ADC0832, that allows for two channels. I will only consider the ADC0831.
The pinout for the ADC0831 is show below (from data sheet).
We will use this device with VCC=VREF=+5V. This sets up the device for conversion of inputs from 0 to 5 volts. The input is between Vin(+) and Vin(-), but Vin(-) is grounded for a single ended input. In this way a 0 Volt input corresponds to an A/D value of 0, a 5 volt input corresponds to a value of 255, 2.5 volts corresponds to 128, etc... The pin CS is chip select, which is also used to signal the beginning of a conversion. The pin D0 is the data line for reading data out of the chip. The data is read serially (one bit at a time) with the CLK input used to synchronize the data flow. The scheme is discussed in full in the ADC0831 data sheet.
The program below does A/D conversions ten times per second, and displays the value on one of four LED's connected to pinB0, B1, B2, and B4 (i.e., LED on pin_B0 is lit if Vin > 1 Volts, also light pin_B1 LED is lit if Vin > 2, etc... ) You should be able to use the function AD_Read without modification. Don't forget the "#define" statements and the declaration of the variable "adVal". (link to code file)
#INCLUDE <16C505.h> #FUSES INTRC, RB4, NOWDT, NOPROTECT, NOMCLR #INCLUDE <16C505.h> #define AD_CS pin_C0 #define AD_CK pin_C1 #define AD_DO pin_C2 int adVal; //This variable holds result from A/D conversion. /* This function initiates a conversion from the ADC0831 A/D convertor, then reads the value from the A/D convertor and puts the result into the variable adVal. */ void AD_Read() { int i; output_low(AD_CS); //Select chip (initiate conversion. for (i=0; i<2; i++) { output_high(AD_CK); //cycle clock twice (while converstion starts. delay_us(10); output_low(AD_CK); delay_us(10); } for (i=0;i<8;i++) { //Read in value from A/D convertor output_high(AD_CK); delay_us(10); shift_left(&adVal, 1, input(AD_DO)); output_low(AD_CK); delay_us(10); } output_high(AD_CK); //cycle clock once. delay_us(10); output_low(AD_CK); delay_us(10); output_high(AD_CS); //Deselect chip. } /* Main routine - Read A/D convertor 10 times per second void main() { output_low(AD_CK); //Initialize A/D output_high(AD_CS); setup_counters(RTCC_INTERNAL,RTCC_DIV_256); while(1) { output_low(pin_b0); //Turn off all LEDS output_low(pin_b1); output_low(pin_b2); output_low(pin_b4); AD_Read(); //Read A/D convertor if (adVal>51) output_high(pin_b0); //LED1 for Vin>1 volt if (adVal>102) output_high(pin_b1); //LED2 for Vin>2 volt if (adVal>153) output_high(pin_b2); //LED3 for Vin>3 volt if (adVal>204) output_high(pin_b4); //LED4 for Vin>4 volt delay_ms(100); //Wait 0.1 seconds. } }Interfacing to the Serial LCD interface from Wirz Electronics
An easy way to generate text output from a PIC is to use a serial LCD driver. This only takes one I/O pin from the PIC. In this section I will describe how to use a serial LCD driver from Wirz Electronics. The data sheet is here.
Below is a program that writes a line to the serial LCD. There are several things in this code that you may not have seen before. The first is the two lines:
#USE FIXED_IO (b_outputs=pin_b5)#USE RS232 (Baud=2400, Xmit=pin_b5, PARITY=N, BITS=8)which tells the compiler that we will use pin_b5 for the serial connection from the PIC to the LCD, and sets the baud rate, etc... The next new thing are the two lines
#BYTE oscal=0x05and
oscal=0x40;these two lines calibrate the internal oscillator on the PIC. It must be correct to within a few percent for the serial I/O to work. Refer to the PIC16C505 datasheet for information on how this works. The number 0x40 is a hexadecimal calibration constant that will vary from chip to chip. This number should be written on the bottom of the chips in the lab. If you are using a chip that has never been programmed before, you will need to read this number from the calibration memory (MPLab will do this). The number gets erased from the calibration memory whenever you erase the chip. When in doubt, use the number 0x40 - most of the chips are close to this value.
You need to set pin_b5 high (output_high(pin_b5);) within a few milliseconds of power up for the LCD to read data properly. The serial I/O can either be positive logic or negative logic, depending on the voltage sensed by the LCD controller when it powers up. Setting the pin high ensures positive logic.
You should also know that the LCD is erased whenever you send a cr/lf ("\n").
Sample Program
#INCLUDE <16C505.h>#FUSES INTRC, RB4, NOWDT, NOPROTECT, NOMCLR#USE DELAY (CLOCK=4000000)#USE FIXED_IO (b_outputs=pin_b5)#USE RS232 (Baud=2400, Xmit=pin_b5, PARITY=N, BITS=8)#BYTE oscal=0x05void main() {oscal=0x40;output_high(pin_b5);setup_counters(RTCC_INTERNAL,RTCC_DIV_256);printf("\nHello."); //Write "Hello" to LCD.while(1) {} //End of program}There are several options you can set on the Serial LCD controller (refer to datasheet). For the device to work properly with the character displays in the lab and the code given below, you should set the DIP switch on the controller for 1 Row Split, 8 characters per row (16 characters total on the display), baud rate=2400.
from datasheet
Example Settings
1 Row Split
8 Characters per Row
2400 Baud
← Comments or Questions?