understanding about MPLAB IDE, PIC digital I/O, PICanalog input and PIC-to- PC communication using UART protocol. All you need from installing the required software until demo of some real life application will be included. Every single step will be explained in details and visualization is included for your ease. By following this step-by-step guide, you will find that PIC is very powerful yet simple to use tool to solve your problem.
Hardware Requirements
1. PC or Laptop with USB Port 2. SK40C 40 Pins PIC Start-Up Kit 3. PIC16F877A 4. USB ICSP PIC Programmer 5. USB to UART UC00A Converter 6. 2510-04 connector 7. Mini USB Cable 8. Breadboard 9. 12V Adapter 10. Male to Male Jumper Wires 11. Resistor 1k 5pcs 12. LEDs 5pcs 13. Potentiometer 1k 1pc 14. DC Motor 1pc 15. Motor Driver 1pc
Software Requirements
1. MPLAB IDE V8.89 2. HITECH C Compiler 3. PICkit 2 v2.61 4. Hyperterminal BASIC GUIDE TO MPLAB IDE
In this tutorial, we are going to use MPLAB V8.89 with HI-TECH C compiler to compile and upload programs to PIC16F877A.
Install MPLAB IDE
To install MPLAB IDE on your system, navigate to MPLAB installer folder and execute the setup.exe file.
Install HI-TECH C Compiler
To install HI TECH C Compiler on your system, navigate to HI TECH C Compiler installer folder and execute the picc_9_83_win.exe file for PIC 10, 12 and 16.
Repeat the same steps on PICC_18_9_80_win.exe file for PIC 18.
Install PICkit 2 v2.61
To install PICkit 2 v2.61 on your system, navigate to PICkit installer folder and execute the setup.exe file.
Create/Open a Project
Double click MPLAB IDE icon on your desktop to start the program.
Go to Project on the toolbar Project Wizard When a windows appear, click Next.
Choose PIC16F877A as the type of device that you want to use and click Next.
Choose HI-TECH Universal Toolsuite in Active Toolsuite. HI-TECH ANSI C Compiler will show up in the Toolsuite Content.
Choose a destination where the project you create can be saved and type the project name. After that, click NEXT>.
Add the existing file(source file, header file) to the project by selecting the directory folder where the files are located and add to the project created. For source file, it will be *.c file while header file will be *.h file.
Click Finish. Or if you have an existing project, you can open the project from Project Open File directory Select the File (*.mcp ) click Open
Edit, Compile And Load
To view the project that you have created or opened, click Project View project. Your project bar should appear. To edit your source code, double click on the *.c file under Source Files
After you have edited your code, you are ready to compile and load it to your device. Right click on the project title choose Build.
In order to load the file to the device, connect the PIC ICSP programmer (UIC00A/UIC00B) to the computer and the device. You can choose to load from MPLAB IDE or using PICkit 2 Programmer software.
Load From MPLAB
Go to Programmer Select Programmer Choose Pickit 2
Go to Programmer> Setting. Tick the box as below.
Right click on the project title choose Build. Thats it.
Load From Pickit 2 Programmer Software
Open the PICkit 2 software. Go to Tools Check Communication Go to File Import Hex
Go to the project folder that you created Choose the *.hex file
Click Write
Thats it. You can repeat to edit, compile and load until you have achieve the result you want.
BASIC GUIDE TO SK40C
Board Overview
A DC power adapter socket for user to plug in DC adapter. The input voltage should be in the range of 7 15V. B USB connector for communication between SK40C and a host controller. This function is only valid for certain models of PIC microcontroller. Please refer to SK40C User Manual. The power LED will light ON when USB cable is connected. C Toggle switch to ON/OFF the power supply from DC adapter. D Power indicator LED. It will light ON as long as the input power is connected correctly. E 25 box header for UIC00A & UIC00B, USB ISCP Programmer. F 2 LEDs (connected to RB6 and RB7) as active High output for PIC MCU. These LEDs are controllable from PIC MCU. G Consist of several line of header pin and turn pin. Header pin provide connector for user to solder SK40C to prototype board and use the I/O of PIC MCU. It is fully compatible with SK40B. Turn pin offers a simple way to check voltage with a multimeter probe. 40 pins of PIC MCU except OSC (connected to crystal) are extended out to these pins. There is an extra pin on top of MCLR which is labeled as Vin, is connected to the input power. H 2x Push Button connected to RB0 and RB1 of PIC MCU. This is extra input button for user. It can be programmed as input switch.
I Reserved for UART communication. Tx and Rx pin of SK40C are connected to RC6 and RC7 respectively. Ensure PIC user have the correct UART pin (RC6 and RC7). J Reset button for PIC MCU. K 5K trimmer for LCD contrast. L JP8 for LCD backlight. LCD Display will have backlight if this pin is shorted. M JP9 is for USB. Connect this pin to use USB port. N 40 pin IC socket for user to plug in any 40 pin PIC MCU(8Bit). It can be either 16F or 18F PIC. Of course the IC package should be PDIP. Please ensure the first pin is at the top side. O Turn pins is provided for crystal. 20MHz is the default crystal provided in SK40C. The 20MHz crystal can be replace with other value. Just remove and plug a new crystal on the turn pin. No soldering required. P Reserved for 2 x 16 LCD. User may solder the LCD here if it is needed.
2 X 16 Parallel LCD Connection Pin (Label P)
Turn Pin For Crystal (Label O)
Push Button Pin (Label I)
UART PIN (Label H)
Hardware Setup
To start, plug the PIC16F887 into the socket that have been provided. Make sure the PIC MCU is correctly placed in the SK40C board. The PIN 1 is just next to the little half moon shape or circle.
Next, connect the A-type USB to the PC. After that, plug in the USB (mini) to UIC00B. The power supply indication, green LED will light ON.
Finally, connect one side of the programming cable to the box header of UIC00B and the other side to the box header of SK40C (Target device) to upload the code. Make sure that external power (DC adapter or battery) for SK40C is provided when uploading.
I/O Port
The input and ouput (I/O) of the PIC can be accessed through few methods such as using jumper wire, plugging on to a breadboard or soldering it on a donut board or strip board.
PROJECTS
Digital Output
Light Emitting Diode (LED)
Project 1 : Simple LED Blinking In this project, we are going to do a simple LEDs blinking using the LEDs on SK40C. Here, we are using both of the LEDs and blink it like a police car. Besides on learning electronic parts, you will also learn about some coding in C using HI-TECH C in MPLAB.
Component Needed
LEDs on SK40C
Connection For this project, the LEDs was already connected to the pins RB6 (PORTB.6) and RB7 (PORTB.7). So, you only have to configure the I/O pins as an output in programming part. To program the PIC16F887, connect the UIC00B to the ICSP Programmer. Make sure the power connection is correct and ON for SK40C. Open MPLAB and include the Project_1.c and click to compile and build .HEX file. After Build Successful, the PICKit 2 should automatically run and program the .HEX file into PIC16F887. Finally, the LED1 and LED2 will be blink like the police car.
Code Overview
__CONFIG ( 0x3F32 ); The configuration 0x3F32 used to configure the PIC. 0x refers to Hexadecimal whereas 3F32 means: Set the oscillator as high speed Off the watchdog timer On power timer Off brown out detect Disable low voltage program Off data EE read protect Off flash program write
system.h
#define _XTAL_FREQ 20000000 Besides that, same step by #define the crystal frequency (_XTAL_FREQ) according to your external crystal frequency using. In here, the default external crystal frequency using are 20000000 (20MHz). #define SW1 RB0 Here, we have already define the switch on SK40C board as RB0. User are no need to define again in the main coding. #define LED1 RB6 #define LED2 RB7 Using the code #define, we can replace the RB6 and as LED1 and RB7 as LED2. By doing this, we can easily remember I/O port we are using. #define LCD_E RB5 #define LCD_RS RB4 #define LCD DATA PORTD Besides that, user are not required again to define the LCD pin for SK40C. User only required to include the system.h file. Further detail on LCD please refer to Project_3. #define TX RC6 #define RX RC7 User are not required again to define the serial comunication (UART) pin for SK40C. User only required to include the system.h file. Further detail on UART please refer to Project_6. void delay_ms(unsigned int ui_value); Function prototype is the declaration of a function that omits the function body but does specify the functions name, argument types and return type. Main Program
void main (void) Figure above shows the main program. 1st we have to type void main(void) at the 1st line to tell the micro-controller that this is the starting point of the program. Here, void main, tell the compiler the name of the function which is main and it does not return any data (void). PORTA = 0; Clear PORT A. TRISA = 0b00000000; is the Tri-STATE Register that declare the I/O ports as an INPUT or OUTPUT by (1=INPUT) and (0=OUTPUT). E.g. TRISB = 0b00001111 is to set the PORTB<7:4> to OUTPUT and PORT<3:0> as INPUT. LED1 = 0; Then, we turn off the LED1 by giving it a 0 at initial state as shown above. So as the LED2 too. To make it on, just change the 0 to 1.
while(1) To make the program loop forever, we use while (1) function. while construction consists of a block of code and a condition. The condition is evaluated, and if the condition is true, the code within the block is executed. Here, we put (1) to indicated that the condition is true. delay_ms(100); is a function call is an expression containing a simple type name and a parenthesized argument list. The argument list can contain any number of expression separated by commas. It can also be empty. In here, we put the arguments list as 100 which is 100ms.
Comment line // In the code, we can found the // on the right hand side of the code. The // is simply a comment in the code and is ignore by the compiler. Any code that behind the // is ignore by compiler and is just simply there for you, or everyone to reads the code. Comments are essential in the code to help you to better understanding on what going on and how the code works. Comments can be put after the command as in the next line of the program. On the other hand, you can also put comments into the block statement by using /* and */. E.g.:
/* All the code within the slash and asterisks will be ignore by compiler */
void delay_ms(unsigned int ui_value) is an function that will be call and perform in the main function. void delay_ms, here we are telling the compiler that out function's name is delay_ms and it does not return any data (void). (unsigned int ui_value) is the parameter use to insert value depending to our requirement. int mean integer which the minimum allow range are between -32767 to +32767 (2 Bytes). unsigned int mean that the data we can insert is between 0 to 65535. while (ui_value-- > 0) in this condition, if the ui_value is subtract by one at the time and check if the ui_value is still greater than 0. The code within the while loop will be running for many times until the ui_value is less than 0. _delay_ms(1); This is the macro from HI-TECH compiler which will generate 1ms delay base on value of _XTAL_FREQ. Project 2 : LED Running In project 2, you are about to experience how to program an LED running. Here, we are going to use total of 5 LEDs and will connected with a current limiting resistor before plug into the I/O port. Component Needed
5 x 1k Resistor Breadboard Jumper Wires 5 x LEDs
Connection Connect the cathode (-ve) of all LEDs to 1k Resistors and end of resistors are connected to the PORTA.0 until PORTA.4. On the other hand, the anode (+ve) of all LEDs are connected to the VDD (Power Supply). The 1k Resistors' function are to limit the current going through them to a safe value. So that it can protect the LEDs from damage.
Additional Information Light Emitting Diode (LED) There are few method to determine the anode and cathode side of the LED such as : 1. The flat spot on the lens/case of the LED is cathode. 2. The short lead (or leg) is cathode. 3. The flag symbol inside the lens is cathode.
Resistor Colour Code
Breadboard Overview
Figure above shows that the connection of half of the breadboard. The RED and BLACK colour line are usually been connect to power supply (VDD) and ground (GND). They are connected all the way from the beginning to the end but they did not connect to each other. Besides that, the orange colour line are the part that we usually use to place the electronic component. They are connected in a straight line. There is a gap in the middle of the breadboard which are not connected to anything. This allow you to put integrated circuit across the gap and have each pin of the chip go to the different set of holes and therefore a different rail.
Code Overview
#define ex_LEDs PORTA Using the code #define, we can replace PORTA by ex_LEDs so that we can easily remember the I/O port we are using. ex_LEDs = 0b00011111; LEDs anode are connected to VDD at while their cathode are connected to the PORTA.0 until PORTA.4. So it means that to ON the LEDs, we need to give it a LOW bit (0). To OFF the LEDs, just simply give a HIGH bit (1) to LED1. Our main program are start with a while loop so that it can stay running non-stop.
Liquid Crystal Display (LCD) - Project 3 : SK40C FKM UMP With Parallel LCD For project 3, we will show you how to interface the SK40C board will parallel 162 LCD display. The connection are simple and the coding are easy to learn. We are going to display the SK40C FKM UMP on the LCD display by just adding a library that has been done for you. Component Needed
16 x 2 LCD Display
Connection
SK40C offers user an extra connecter to directly plug in the LCD display. User may saves a lot of time from soldering the LCD display. The data pin of the LCD are connected to the PORTD while the RS of LCD are connected to RB4 and E of LCD are connected to RB5. Please refer to SK40C user manual for further information.
Additional Information Liquid Crystal Display
Before start program the LCD, we need to know the function of each pin on the LCD display to avoid wrong connection. RS LOW (0), data bytes transfer are treated as command. HIGH (1), character can be transfer to and from module. R/W LOW(0), write command or character data to the module. HIGH(1), read character data or status information from its registers. E HIGH(1) to LOW(0), writing to display. LOW(0) to HIGH(1), reading from display. D0 to D7 Eight data bus line. There are numbers of cool experiment inside the LCD datasheet which teach us how to entering the text, addressing, shifting the display, character entry mode, user-defined graphic and 4-bits data transfer. LCD Backlight Control
To make your LCD looks cool, we can ON the backlight of the LCD by just put a mini jumper or solder to short LCD B/L. LCD Contrast Control
There is a potential meter which is purposely added to enable user to adjust the different contrast of LCD. Turn left or right to adjust the contrast level. Code Overview
Figure above shows that we have included an lcd.h and system.h file inside our main program. The reason we doing this is to separate our code in different file and for to easily relocate back by user if there is any error. To refer back to the LCD program, all we need is double-click the lcd.c and it will show up. Whats inside lcd.c & lcd.h ? Inside lcd.c, all the code that needed to control the LCD have been defined such as the coding in figure below:
lcd.h is one of header files. These files allow programmers to separate certain elements of a programs source code into reusable files. Header files commonly contain forward declarations of classes, subroutines, variables, and other identifiers. Programmers who wish to declare standardized identifiers in more than one source file can place such identifiers in a single header file, which other code can then include whenever the header contents are required. system.h
In system.h, a name to a port has been given using #define. Besides from defining the crystal frequency, here, the PORT that required to use by LCD which is RB4, RB5 & PORTD have been defined too.
lcd_initialize(); Before we start to send any data to LCD, the LCD should be initialized 1st. The initialization process are such as, clear LCD display, cursor home, cursor on/off, display/cursor shift and function set. lcd_home(); To make sure that the cursor is back to home. We need to send a command for it which is in binary 00000010. lcd_putstr(SK40C FKM UMP) Send a string to LCD data bus to display it on the screen. The symbol means what the word or text inside are in ASCII format. The compiler will automatically convert it to binary and send to the required port. Finally the texts SK40C FKM UMP will be displayed on the screen.
Digital Input - Project 4 : Push Button For this project, we will discover how to manage a digital input signal. Digital signal is either HIGH (1) and LOW (0) only. But for different integrated circuit such as PIC MCU, we need to define at the beginning of the code that the port using are either input or output and also declaration for digital or analog signal send and received.
Component Needed LEDs on SK40C Push Button on SK40C
Connection
There is no need to connect extra push button to SK40C board because inside SK40C, there is already have 2 push button on board which is purposely prepared for user to use it. These push button are already connected to RB0 and RB1. So all we need to do is just declare these 2 ports as INPUT. As for the OUTPUT, we use the on board LEDs to show us that we have push the push button. The LEDs are connect to RB6 and RB7. To use the LEDs, we need to declare it as an OUTPUT.
Additional Information Besides on using the push button on SK40C, we can use others component to replace it such as limit switch, keypad and etc. Referring to the figure below, input signal read at HIGH are between 3.5V to 5V and while LOW are read between 1.5V to 0V. For output of the external device are giving the digital value of HIGH at between 4.95V to 5V and LOW at between 0.05V to 0V. As long as the logic input and output voltage are within this level, the PIC MCU can read it without any conversion.
On the other hand, by adding an additional switch to the PIC16F887, the switch have to be pull-up because some port do not have this pull-up function. Besides the pull-up resistor, there is also pull-down resistor as shown in the picture below.
In this project, we do not employ any additional push button.
Code Overview
PORTA = 0; We clear PORTA so that it wont affect Tri-State Register (TRIS). TRISB = 0b00000011; Push buttons is connected to RB0 to RB2. To make in as an input, we have set HIGH(1) to TRISB.0 and TRISB.1. The rest are declared as output port. ADCON1 = 0b00000110; ADCON1 is an ADC register for PORTA. To make it DIGITAL I/O, we need to set ADCON1 as shown above.
while (SW1 == 0) check whether the switch 1 is LOW(0). If it does then do the following code which is blink the LED1 and loop forever. The symbol == is usually use to represent the signal in digital. While = is usually use to represent the signal in analog.
Analog Input - Project 5 : Potentiometer In this part, we are going to discuss about how to write the Analog to Digital Converter code which has become the most popular question among the students. We are going to use PIC16F887A which provides 10-bits binary result and a potentiometer to adjust the voltage different and display it in the LCD display.
Component Needed
16 x 2 LCD Display Potentiometer (5k) Breadboard Jumper Wires Connection The connection for the potentiometer is very easy. Just connect one end to VDD and another end to GND while the middle pin is connected to RA0. By referring to the PIC16F887A, there are total 8 analog pins that we can choose. Here we use RA0 as our ADC input pin.
Additional Information
ADC enable the microcontroller to recognize, not only whether a pin is driven to logic zero or one (0 or +5V), but to precisely measure its voltage and convert it into a numerical value, i.e. digital format. So, here are the steps to configure the ADC and carry out the conversion: 1. Decide which pins need to be analogue, which pins need to be digital and which (if any) need to be configured as reference pins. 2. Select the appropriate settings for PCFG[3:0] in ADCON1. 3. Select ADC module conversion clock by setting ADCS[2:0] in ADCON1 and ADCON0. 4. Select justification method left- justification or right-justification by setting/clearing ADFM in ADCON1. 5. Turn on ADC module by setting ADON to 1 in ADCON0. 6. Select which channel is to be sampled/measured and converted by setting CHS[2:0] in ADCON0. 7. Wait the required acquisition time. 8. Start conversion by setting GO/DONE to 1 in ADCON0. 9. Check if conversion is over by checking if GO/DONE has been cleared to 0. 10. If conversion is over, read the results from ADRESH:ADRESL. Code Overview ADC Configuration
ADSC2 = 0; ADCS1 = 1; ADCS0 = 0;
ADCS is the A/D Conversion Clock select bits. In here we have selected the conversion clock as Fosc/32. Which the Fosc using are 20MHz to produce a period of 1.6us for an accurate ADC conversion.
PCFG3 = 1; PCFG2 = 1; PCFG1 = 1; PCFG0 = 0; are port configuration in ADCON1 register to set RA0 as analog while RA1 until RA7 as digital. ADFM = 1; ADFM is the conversion result format select bit. Here, we give a value 1 to configure it as an Right Justified. If value 0 is given, the format are in Left justified. ADON = 0; ADON is the ADC enable bit. If the ADON is 0, the ADC is OFF. While if the ADON is 1, the ADC is ON. ADC Read
unsigned int pot = 0; Initialize and make the pot as a 0 value at the every time the code jump into this subroutine. __delay_ms(1); The purpose of the 1ms delay in here is to wait the holding capacitor in ADC module to fully charge. GO_DONE = 1; After the A/D Conversion started, set this register and wait it to become LOW(0) which mean that its has done the conversion. pot = (unsigned int) ADRESH << 8; After conversion is done, the value of ADRESH is transferred to pot and shifted LEFT by 8 bits. E.g.: ADRESH = 0000 0011 (unsigned int 1 byte) pot = ADRESH = 0000 0011 (unsigned int 1 bytes) ADRESH = 0000 0011 0000 0000 (<< 8 ) pot = pot + ADRESL; Finally, the value in pot will be added with ADRESL.
E.g: pot = 0000 0011 0000 0000 ADRESL = 1111 1111 Final pot result = 0000 0011 1111 1111
LCD & ADC Initialize
Before the main code start running, we need to initialize LCD and ADC.
Main Program : Potentiometer
CHS2 = 0; CHS1 = 0; CHS0 = 0;
Analog channel select bit which is use to select the analog port we are using. In this case we are using the RA0. By referring to the datasheet, RA0 is on the CHS<2:0> = 000;. for(i=0 ; i<10 ; i++) { adc_value = adc_value + ui_adc_read(); }
In this case, the values of ADC have been taken and add together for 10 times. adc_value = adc_value/10; After the adc_value is been added by 10 times. It is divided by 10 to get the average value. The purpose is to get a more accurate value. lcd_bcd(4,adc_value); Convert the ADC output value in BCD and display it in LCD. Here, we have limit it to display maximum 4 digit only. volt_value = (adc_value*50)/102.4; To display the voltage of the analog. We need to convert the digital value in the output of the ADC by applying the formula. E.g. : If adc_value is 1022 (decimal) 1022*50 = 51100. 51100/102.4 = 499 (volt_value)
UART
Project 6 : UART To Computer
Universal Asynchronous Receiver Transmitter (USART) has becoming a popular item on sending and receiving data in the fast way. For PIC16F877A, USART can be configured to transmit and receive data either in synchronous or asynchronous. Here, we are going to experience on how to use UC00A to communicate with our computer/PC and SK40C using synchronous method (UART).
Component Needed
16 x 2 LCD Display USB to UART Converter Hyperterminal Installer Jumper Wires
Connection
To interface between UC00A and SK40C required only 4 wires connection which is power supply (VDD), ground(GND), transmit(TX) and receive (RX). For serial communication, the transmit and receive for UC00A and SK40C have to be connected in duplex. Please refer figure below and UC00A datasheet. Additonal Information
Wires in PIN1 and PIN2 are switch for the second connecter.
Hyperterminal Installation Open hypertrm.exe. Next, LOCATION INFORMATION will pop up like figure below. Then, click CANCEL until you see the CONNECTION DESCRIPTION.
Enter a project name then click OK.
Choose the suitable COM port by referring to the DEVICE MANAGER.
Setting up the COM PROPERTIES as shown in figure below:
Go to FILE > PROPERTIES > SETTING > ASCII SETUP and tick like figure below. After that, the HyperTerminal is ready to go.
Code Overview
uart_putstr(Ready To Receive & Transmit!!) Send a string of ASCII through UC00A and display on HyperTerminal to tell the computer that SK40C is ready.
for(i=0 ; i<32 ; i++) { if (i == 15) lcd_2ndline(); else if (i == 31) lcd_home(); } This loop count and make sure that the word are displayed on LCD. This is to make sure that every word displayed can be seen which is for 1 st line LCD address are from 000 until 0x0F and for 2 nd line LCD address are from 040 until 0x4F. If i counted 15, it automatically shift the cursor to 040 and when i counted 31, it back to 000. uc_uart_receive(); Receive the data from computer. data = RCREG; Store the bytes of data receive in data. lcd_putchar(data); end the data received to LCD which sending the 1 to telling the LCD that the data is a character. The data received from the computer are in ASCII, so there was no need any conversion.
Project 7 :DC Motor GUI Control Panel
Introduction
DC Motor GUI Control Panel able to use for control DC motor via SK40C and UC00A USB to UART converter. This GUI Control panel able to activate and deactivate dc motor.
Installation Software:
1. Double click setup and waiting the Control Panel will pop out as following figure:
Connection
Connect the circuit as shown in the figure above. D1 until D4 is IN4001.
Code Overview
define functions to turn on and turn off DC motor. The functions is very simple. To turn ON DC motor, set RB5 = 1, RB6 = 1 and RB7 = 0. Additionally, you can simply change the direction of motor rotation by swap RB6 and RB7. To turn off DC motor, simply set RB5 = 0.