Having made the choice to move on to a lower-level microcontroller, the next question is which one? PIC by Microchip, AVR by Atmel and SX chips are just a few of the most common choices. I decided to go with PIC since my research revealed a vast amount of information on the web and many books written about them. Next, I had to choose which language I would use. Initially, I decided on Assembly since I wanted my code to be as low-level as possible. I purchased a PIC book which taught how to program them using Assembly, but after a while decided that was too big of a step from the higher level language I was used to. Learning the ins and outs of the MCU and learning Assembly was too much. It was taking the fun out of the hobby. So I decided to choose the C programming language since I already knew it. This allowed me to focus on learning the ins and outs of the PIC micro and not be burdened with learning programming syntax. Microchip has free Integrated Programming Environment that you can download called MPLAB X which includes a C compiler XC8. The free version of the XC8 compiler is fine for most basic programs. The standard and Pro versions offer better code optimization to make best use of MCU program memory.
I purchased a couple books on how to program the PIC microcontroller using C. One of my favorites is Beginner's Guide to Embedded C Programming Volume 2 by Chuck Hellebuyck. I like the way the author explains in detail the purpose of every line of code. I have programmed all the examples in the book and have combined or adjusted many of them to further my knowledge.
One example I would like to share is the programming of a PIC16F690 which communicates with a PC via serial communication and also displays messages on an LCD. This is a combination of two of the books examples that I put into one and modified a bit. This is a rewarding project for me because I see much potential in it. Knowing how to make the microcontroller display the value of variables or messages on a LCD is an invaluable skill. It adds a bit of professionalism to any gadget you make at home. Also, having the microcontroller communicate with a PC using serial communication can be very useful. It can help with troubleshooting, data transfer from a sensor or you can even build hardware that controls an application or game on the PC.
I am only including the main.c file since I have modified this enough to consider it my own. For copyright reasons I will not include the files lcd.c or usart.c that main.c requires since these are the author's files and I do not have permission to re-print them here. However, you can download them from the books website http://www.elproducts.com/cbook2files.html You will have to modify these files slightly too since they were written using an older compiler. Basically include the xc.h header file instead of the htc.h.
I sketched up the circuit layout and included it below. Unlike the book's serial communication example I used a RS-232 voltage converter and a USB-to-Serial converter between the MCU and the PC. This is how one would most likely have their own gadget connected to the PC. However, if you just want to quickly test the program you can use the PICKIT2 programmer and it's USART program as the book does. To view the serial data from the micro us a terminal program such as HyperTerminal. Read the comments in the header portion of the code for a description of what it does.
To get the most out of this I recommend purchasing the book and completing each example yourself. If you are serious about programming PIC microcontrollers you won't be dissappointed. Since PIC mcu's are a fraction of the cost of an Arduino or Basic Stamp2, it makes sense to use them if you plan to build many projects or mass produce a gadget. If you know the C programming language or one of it's variants like Java, C++ or C# then it will be relatively simple to learn to program them since there are many resources on the web or books on the subject. One thing I would like to stress before I close is that it is very important to download and read the datasheet for which ever MCU you choose. Study the datasheet as you read the book and things will make sense a lot quicker versus reading the book alone.
/*
* Serial Port and LCD example. This code will interface to a standard LCD controller
* like the Hitachi HD44780 with the MCU. The MCU will also be connected to a PC via a
* serial port.
* Use a serial port to USB adapter cable and Hyperterminal terminal software
* (2400 bps, 8 databits, Parity: none, 1 Stop bit, Flow Control: none)
* Also use a Max232 voltage translator between the MCU and DB9 serial port connector
* MCU is a Pic16F690 using the XC8 compiler with MPLAB X IDE
* PORTC bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
* PORTA bit 0 is connected to the LCD RS input (register select)
* The LCD RW input (read/write) is connected to ground
* PORTA bit 1 is connected to the LCD EN bit (enable)
* When the program starts, first the MCU prints 123456789 to the terminal window
* Then it prompts the user to press a key and then the MCU echos the character back to
* the terminal window and displays it on the LCD.
*/
#include xc.h //for XC8 C compiler
#include stdio.h
#include "usart.h"
#include "lcd.h"
// CONFIG
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function
//on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select bit(MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit Program memory code protection disabled)
#pragma config CPD = OFF // Data Code Protection bit(Data memory code protection disabled)
#pragma config BOREN = OFF // Brown-out Reset Selection bits(BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit(disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit(disabled)
void pause( unsigned short usvalue ); //pause routine prototype
#define _XTAL_FREQ 4000000
#define LED PORTBbits.RB4 //the LED that will strobe when the user presses a key
//function to flash a LED rapidly for about 1/16th of a second
void strobeLED()
{
for(unsigned char c = 0; c < 4; c++ )
{
LED = ~LED;//toggle the state of the LED
pause (64);// very brief pause
}
}
void main(void)
{
ANSEL = 0; // Set all ports Digital, analog off
ANSELH = 0;
CM1CON0 = 0; // Comparator 1 off
CM2CON0 = 0; // Comparator 2 off
PORTA = 0; //Start all PORTA pins low
TRISA = 0; //All PORTA Outputs
TRISBbits.TRISB4 = 0;//LED pin is an output
TRISC = 0; //All PORTC Outputs
LED = 1; //start LED at HIGH (5 volts)
lcd_init(); //Initialize LCD Display
init_comms(); //set up the USART - settings defined in usart.h
lcd_clear(); //Clear LCD screen
lcd_goto(0); //select first line of LCD
lcd_puts("Pic. Serial Demo."); //Display message on the LCD
pause(125); //Delay for 1/8 second
//count to 9 in the terminal window 123456789 (ASCII 0x31 = 1, 0x32 = 2, ... , 0x39 = 9)
for(unsigned char i = 0x31; i <= 0x39; i++)
putch(i);
printf("\r\n");//go to the next line in the terminal window
unsigned char input; //must be outside serial Comm loop
//Serial Communication Loop
while(1)
{
printf("Press a key and I will echo it back:\r\n");
input = getch();//read a response from the user(waits for a key to be pressed)
strobeLED();//briefly strobe the LED when the user presses a key
printf("I detected [%c]\r\n",input);// echo it back
lcd_clear(); //Clear LCD screen
lcd_goto(0); //select first line
lcd_puts("You pressed "); //Display message to LCD
lcd_putch(input); //Display value of input on LCD
pause (125); //Delay for 1/4 second to read display
}
}