PIC16F684 Interfacing with Hitachi 44780
Hi guys!
I'm a finalist university student on a Product Design and Technology course and I'm currently completing an assessment where we are required to design a circuit using a PIC16F684 to interface to a Hitachi 44780 LCD controller.
We've been given some standard code in order to output a sample message to the LCD, which we're intending to add to once we've programmed in the additional functionality of the circuit.
The code is as follows:
Code:
#include <pic.h>
/* cLCD.c - Write a String to a 4 Bit Hitachi 44780 LCD I/F
This Program Initializes Hitachi 44780 Based LCD in 4 Bit Mode
and then writes a simple string to it. The simulator was used
to time delay values.
RC3:RC0 - LCD I/O D7:D4 (Pins 14:11)
RC4 - LCD E Clocking Pin
RC5 - LCD R/S Pin
*/
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT \
& UNPROTECT & BORDIS & IESODIS & FCMDIS);
int i, j, k, n; // Use Global Variables for Debug
// 1234567890123456
const char TopMessage[] = " Hello World ";
const char BotMessage[] = " Hear me roar ";
#define E RC4 // Define the LCD Control Pins
#define RS RC5
const int Twentyms = 1250; // Declare a Constant for 20 ms Delay
const int Fivems = 300;
const int TwoHundredus = 10;
LCDWrite(int LCDData, int RSValue)
{
PORTC = (LCDData >> 4) & 0x0F; // Get High 4 Bits for Output
RS = RSValue;
E = 1; E = 0; // Toggle the High 4 Bits Out
PORTC = LCDData & 0x0F; // Get Low 4 Bits for Output
RS = RSValue;
E = 1; E = 0; // Toggle the Low 4 Bits Out
if ((0 == (LCDData & 0xFC)) && (0 == RSValue))
n = Fivems; // Set Delay Interval
else
n = TwoHundredus;
for (k = 0; k < n; k++); // Delay for Character
} // End LCDWrite
main()
{
PORTC = 0; // Start with Everything Low
CMCON0 = 7; // Turn off Comparators
ANSEL = 0; // Turn off ADC
TRISC = 0; // All of PORTC are Outputs
// Initialize LCD
j = Twentyms;
for (i = 0; i < j; i++); // Wait for LCD to Power Up
PORTC = 3; // Start Initialization Process
E = 1; E = 0; // Send Reset Command
j = Fivems;
for (i = 0; i < j; i++);
E = 1; E = 0; // Repeat Reset Command
j = TwoHundredus;
for (i = 0; i < j; i++);
E = 1; E = 0; // Repeat Reset Command Third Time
j = TwoHundredus;
for (i = 0; i < j; i++);
PORTC = 2; // Initialize LCD 4 Bit Mode
E = 1; E = 0;
j = TwoHundredus;
for (i = 0; i < j; i++);
LCDWrite(0b00101000, 0); // LCD is 4 Bit I/F, 2 Line
LCDWrite(0b00000001, 0); // Clear LCD
LCDWrite(0b00000110, 0); // Move Cursor After Each Character
LCDWrite(0b00001110, 0); // Turn On LCD and Enable Cursor
for (i = 0; TopMessage[i] != 0; i++)
LCDWrite(TopMessage[i], 1);
LCDWrite(0b11000000, 0); // Move Cursor to the Second Line
for (i = 0; BotMessage[i] != 0; i++)
LCDWrite(BotMessage[i], 1);
while(1 == 1); // Finished
} // End cLCD
We are manufacturing the circuits on a PCB and, to get all of the necessary connection on a single side of copper, we reversed the data bus connections to the Hitachi. Normally, the output of PORTC is defined such that pin RC3 goes to DB7, RC2 goes to DB6, RC1 goes to DB5 and RC0 goes to DB4. However, in our reconfigured circuit DB4 is connected to RC3, DB5 is connected to RC2, DB6 is connected to RC1 and DB7 is connected to RC0. i.e. the data connections are reversed (sorry if this is lengthy, wanted to be absolutely clear about what we've done).
We made these modifications under the assumption that it would be a simple matter of changing the code to account for this change of connections, since the output of PORTC on the PIC is simply governed by its programming.
We've tried a number of code modifications on our breadboarded circuit, but so far no success.
Does anybody have any thoughts as to how I would reverse the order of outputs from PORTC pins 0 through 3?
Sorry if any of this is unclear, if you need further information I'd be happy to provide it.
At this stage, if we're unable to modify the code we're going to have to cut through some of the tracks on the PCB and solder some bits in using wires. Unfortunately, we'll get marked down for this.
Thanks for any help anybody may be able to give.
JT