|
|
View previous topic :: View next topic |
Author |
Message |
Rhinosaur Guest
|
Problem with LCD program |
Posted: Thu Feb 26, 2009 7:19 am |
|
|
Hello all,
I've got a strange issue when trying to send a message to the second line of a Powertip PC1602-F LCD. I'm using a PIC16F648A chip, and based my program on the CCS C LCD.c example. This is using an 8-bit interface.
Basically the program initialises fine, and shows a message on the top line. A button press will send another message character by character with a 500ms delay between each.
After another button press the same message is supposed to move to the second line instantly, but it doesn't. I have the cursor on, so I can see the cursor move to the second line but the message doesn't get shown. Any subsequent button presses do nothing (when they should continue to swap the line the message is on).
Am I making an obvious mistake here? I merged the send byte and send nibble functions in the example file (as I'm not using a 4-bit interface).
Here's my code, any help would be greatly appreciated.
Code: | #include <16F648A.h>
#use delay(clock=4000000)
#fuses NOWDT, INTRC_IO, NOPUT, NOPROTECT, NOLVP, NOMCLR
struct lcd_pin_map {
boolean rs;
boolean rw;
boolean enable;
boolean switchInput;
int unused : 4;
int data : 8;
} lcd, lcdDirection;
#byte lcd = 0x05
#byte lcdDirection = 0x85
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x38, 0x0e, 0x01, 0x06};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
char const message[2][17] = {"Initial message.","Alternating msg!"};
int msgLine;
struct lcd_pin_map const LCD_WRITE = {0,0,0,1,0,0}; // For write mode data pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,1,0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE dataBits;
lcdDirection = LCD_READ;
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
dataBits = lcd.data;
lcd.enable = 0;
lcdDirection = LCD_WRITE;
return(dataBits);
}
void lcd_send_byte( BYTE address, BYTE n ) { // Send character to display
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_init() { // Initialisation procedure, see notes
BYTE i; // for more detail on how this works
lcdDirection = LCD_WRITE;
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=2;++i) {
lcd_send_byte(0,0x30);
delay_ms(5);
}
lcd_send_byte(0,0x30);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // Wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
void send_message(int msg, int line, int delay) {
int i;
lcd_putc('\f'); // Clear the display
if(line!=0) // Go to next line if required
lcd_putc('\n');
for(i=0; i<16; i++){ // Send message to display
lcd_putc(message[msg][i]);
delay_ms(delay);
}
}
void main()
{
lcd_init(); // Initialise the LCD
msgLine = 0; // First message on first line
send_message(0,msgLine,0); // Send initial message to display
while(lcd.switchInput==0) {} // Wait here until there's an input
send_message(1,msgLine,500); // Send the next message letter by letter
while(lcd.switchInput==1) {} // Wait here until switch is released
while(true) {
while(lcd.switchInput==0) {}
msgLine = (++msgLine)%2; // Alternate the message line
send_message(1,msgLine,0); // Send the message without a delay
while(lcd.switchInput==1) {}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 26, 2009 1:53 pm |
|
|
Quote: |
struct lcd_pin_map const LCD_READ = {0,0,0,1,0,15};
|
Your LCD_READ pin map is not correct. Here is the .LST file:
Quote: |
... lcdDirection = LCD_READ;
0048: MOVLW 0F // Sets TRISB = 0x0F (Should be 0xFF).
0049: BSF STATUS.RP0
004A: MOVWF TRISB
004B: MOVLW 08
004C: MOVWF TRISA |
You've tried to modify the 4-bit driver into an 8-bit driver, but you have
left the Read TRIS mask at 15 (0xF). For an 8-bit wide data port, it
should be 0xFF. (I don't believe in using decimal values to represent
bitmasks). |
|
|
Rhinosaur Guest
|
|
Posted: Fri Feb 27, 2009 3:16 am |
|
|
Hello,
Thank you for the reply, I didn't notice that. Do you think that's what my problem is? Although I'm only using this program to write to the LCD, I decided I may as well leave the read functions in the program anyway. I'll give it a shot when I get chance.
Any other opinions on my problem?
Many thanks in advance. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|