LCD and real clock timer

Thread Starter

apiz88

Joined Sep 14, 2008
1
i have a problem with my programming.the output did not appear at the LCD but consist of rubbish character.what should i do???


// Industrial project -- "seat reserving" ticketing machine
#include <p18f452.h>
#include <delays.h>
#include <string.h>
#include <math.h>
#pragma config OSC = XT // use crystal oscillator
#define LCD_RS PORTAbits.RA3 // Assigning RA3 for Register Select on LCD
#define LCD_EN PORTAbits.RA1 // Assigning RA1 for Enable on LCD controller
#define LCD_WR PORTAbits.RA2 // Assigning RA2 for Write on LCD controller
#define set_dd_line1_pos1 0x80 // The address of line 1, pos1 on the module -- was 8F
#define set_dd_line2_pos1 0xC0 // The address of line 2, pos1 on the module -- was CF
// Function prototypes
void lcd_strobe(void);
void lcd_write(unsigned char c);
void lcd_clear(void);
void lcd_putch(char c);
void lcd_goto(unsigned char LCD_POS);
void lcd_init(void);
void T2ISR(void);
char int_2_char (unsigned char int1);
// ========================================================================================
// Function to strobe the LCD
void lcd_strobe(void) // This function provides the high to low transition needed
// to initiate the actual transfer of commands or data to the module
{
LCD_EN = 1;
Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "1"
LCD_EN = 0;
Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "0"
}
// Function to write a command byte to the LCD in 4 bit mode
void lcd_write(unsigned char c)
{
unsigned char temp1;
LCD_RS = 0; // Select LCD for command mode
Delay10TCYx(4); // 40us delay for LCD to settle down at commmand mode
temp1 = c;
temp1 = temp1 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
PORTD = temp1 & 0x0F; // Output to PORTD which is connected to LCD
Delay1KTCYx(1); // Delay at least 1 ms before strobing
lcd_strobe();
Delay1KTCYx(1); // Delay at least 1 ms after strobing

temp1 = c ; // Re-initialise temp2
PORTD = temp1 & 0x0F; // Mask out upper 4 bits
Delay1KTCYx(1); // Delay at least 1 ms before strobing
lcd_strobe();
Delay1KTCYx(1); // Delay at least 1 ms before strobing
}
// Function to initialise the LCD
void lcd_init(void)
{
LCD_RS = 0; // Select LCD for command mode
LCD_WR = 0; // Select LCD for write mode for only writing of commands
// and data (ie does not read eg the status of the LCD)
Delay10KTCYx(100); // Delay a total of 1 s for LCD module to

// ... after power is applied, a command sequence of 3 bytes of 30h is sent to the module to ensure that the module is in
// 8-bit mode and properly initialised. Following this, the LCD module can be switched to 4-bit mode. */
PORTD = 0x03; // Note that PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
// Thus, PORTD = 0x03 is 0x30 at DB7-0
lcd_strobe();
Delay1KTCYx(250); // 250 ms power on delay
PORTD = 0x03;
lcd_strobe();
Delay1KTCYx(250); // 250 ms power on delay
PORTD = 0x03;
lcd_strobe();
Delay1KTCYx(250); // 250 ms power on delay
PORTD = 0x02; // Set to 4-bit mode
lcd_strobe();
Delay10KTCYx(50); // 500 ms power on delay
lcd_write(0x28); // Send a command to set 4 bit mode, 2 line(5x7 font)
Delay1KTCYx(20); // 20 ms power on delay
lcd_write(0x01); // Send a command to clear display
Delay1KTCYx(40); // 40 ms power on delay
lcd_write(0x0F); // Send command to on display and cursor
Delay1KTCYx(20); // 20 ms power on delay
lcd_write(0x06); // Send command to put LCD in char entry mode
Delay1KTCYx(20); // 20 ms power on delay
}
// Clear and home the LCD ie put the cursor at line1, pos1
void lcd_clear(void) // Function to clear LCD display
{
LCD_RS = 0; // Select LCD for command mode
Delay10TCYx(4); // 40us delay for LCD to settle down
lcd_write(0x01); // LCD command 0f 0x01 clears the display
Delay1KTCYx(2); // Delay at least 2 ms after writing the CLEAR LCD command
}
// Function to put cursor at a specified position
void lcd_goto(unsigned char LCD_POS)
{
LCD_RS = 0; // Select LCD for command mode
Delay10TCYx(4); // 40us delay for LCD to settle down at command mode
lcd_write(LCD_POS); // Send the cursor position
}
// Function to write a character to the LCD in 4 bit mode
void lcd_putch(char c)
{
char temp2;
LCD_RS = 1; // Select LCD for data mode
Delay10TCYx(4); // 40us delay for LCD to settle down at data mode
temp2 = c;
temp2 = temp2 >> 4;
PORTD = temp2 & 0x0F;
Delay1KTCYx(1);
lcd_strobe();
Delay1KTCYx(1);
temp2 = c ;
PORTD = temp2 & 0x0F;
Delay1KTCYx(1);
lcd_strobe();
Delay1KTCYx(1);
}
// ==============================================================================================
char outchar; //-- character to send to the LCD
unsigned char hour, minute, second, hour10, hour1, minute10, minute1, second10, second1;
unsigned int tick_count;
void main(void)
{
// RTC code
hour = 12;
minute = 34;
second = 56;
tick_count = 0;
T2CON = 0x04; // posS=1, preS=1, Timer 2 ON.
PR2 = 199; // Period = 200 x 1us = 0.2 ms with 4-MHz crystal
RCONbits.IPEN = 1; // Enable Priority Features
IPR1bits.TMR2IP = 1; // Timer 2 is High Priority
PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag.
PIE1bits.TMR2IE = 1; // Enable Timer 2 Interrupt.
INTCONbits.GIEH = 1; // Enable Global Interrupt, High.
// LCD code
ADCON1 = 0x07; // configure PORTA to be digital I/O
TRISA = 0x00; // set Port A as output
TRISAbits.TRISA4 = 1; // set RA4 as input pin -- button to Up Hour
TRISBbits.TRISB0 = 1; // set RB0 as input pin -- button to Up Minute
TRISD = 0x00; // set Port D as output
LCD_EN = 0;
LCD_RS = 0;
LCD_WR = 0;
PORTD = 0x00;
Delay1KTCYx(1); // 1 ms power on delay
lcd_init();
LCD_RS = 1; // Select LCD for data mode
Delay1KTCYx(1); // 1 ms power on delay
lcd_clear();
// wait forever
while(1)
{
}
}
// RTC code
#pragma code
#pragma interrupt T2ISR // Timer2 -- interrupt service routine
void T2ISR(void)
{
PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag.
tick_count++;
if (tick_count >= 5000)
{ // one second's up, (1) check RA4 to update hour (2) check RB0 to update minute (3) update second (4) update display
tick_count = 0;
// (1)
if (!PORTAbits.RA4) // "RA4 pressed", PIC read 0, increment hour
{
hour = hour + 1; // increment hour
if ( hour > 23 )
hour = 0; // roll over hour
}
// (2)
else if (!PORTBbits.RB0) // "RB0 pressed", PIC read 0, increment minute
{
minute = minute + 1; // increment minute
if ( minute > 59 )
{
minute = 0; // roll over minute
hour = hour + 1; // increment hour
if ( hour > 23 )
hour = 0; // roll over hour
}
}
// (3)
else // increment second
{
second = second + 1; // increment second
if ( second > 59 )
{
second = 0; // roll over second
minute = minute + 1; // increment minute
if ( minute > 59 )
{
minute = 0; // roll over minute
hour = hour + 1; // increment hour
if ( hour > 23 )
hour = 0; // roll over hour
}
}
}
hour10 = hour / 10;
hour1 = hour - hour10 * 10;
minute10 = minute / 10;
minute1 = minute - minute10 * 10;
second10 = second / 10;
second1 = second - second10 * 10;
// send "time = hh:mm:ss" to LCD display
lcd_goto(set_dd_line1_pos1);
lcd_putch('t');
lcd_putch('i');
lcd_putch('m');
lcd_putch('e');
lcd_putch(' ');
lcd_putch('=');
lcd_putch(' ');
outchar = int_2_char (hour10);
lcd_putch(outchar);
outchar = int_2_char (hour1);
lcd_putch(outchar);
lcd_putch(':');
outchar = int_2_char (minute10);
lcd_putch(outchar);
outchar = int_2_char (minute1);
lcd_putch(outchar);
lcd_putch(':');
outchar = int_2_char (second10);
lcd_putch(outchar);
outchar = int_2_char (second1);
lcd_putch(outchar);
// send "enter #seats: _" to LCD display
lcd_goto(set_dd_line2_pos1);
lcd_putch('e');
lcd_putch('n');
lcd_putch('t');
lcd_putch('e');
lcd_putch('r');
lcd_putch(' ');
lcd_putch('#');
lcd_putch('s');
lcd_putch('e');
lcd_putch('a');
lcd_putch('t');
lcd_putch('s');
lcd_putch(':');
lcd_putch(' ');
// cursor waiting at set_dd_line2_pos1 + 14. If keypad pressed, show no of seats required....
// lcd_putch('9'); -- example
}
return;
}
// =====================================================================
// function to convert unsigned char to char (for display)
char int_2_char (unsigned char int1)
{
char char1;
switch (int1)
{
case 0 : char1 = '0' ; break;
case 1 : char1 = '1' ; break;
case 2 : char1 = '2' ; break;
case 3 : char1 = '3' ; break;
case 4 : char1 = '4' ; break;
case 5 : char1 = '5' ; break;
case 6 : char1 = '6' ; break;
case 7 : char1 = '7' ; break;
case 8 : char1 = '8' ; break;
case 9 : char1 = '9' ; break;
default : char1 = '?' ;
}
return(char1);
}
#pragma code IVH = 0x08 // Interrupt HIGH vector location.
void IVH(void){ _asm goto T2ISR _endasm }
#pragma code IVL = 0x18 // Interrupt LOW vector location.
void IVL(void){ _asm goto T2ISR _endasm }
 

SgtWookie

Joined Jul 17, 2007
22,230
I have not changed your program; merely re-indented it. If you do not use the CODE tags, the original indenting of your source code is lost.

Rich (BB code):
// Industrial project -- "seat reserving" ticketing machine
#include <p18f452.h>
#include <delays.h>
#include <string.h>
#include <math.h>
#pragma config OSC = XT // use crystal oscillator
#define LCD_RS PORTAbits.RA3 // Assigning RA3 for Register Select on LCD
#define LCD_EN PORTAbits.RA1 // Assigning RA1 for Enable on LCD controller
#define LCD_WR PORTAbits.RA2 // Assigning RA2 for Write on LCD controller
#define set_dd_line1_pos1 0x80 // The address of line 1, pos1 on the module -- was 8F
#define set_dd_line2_pos1 0xC0 // The address of line 2, pos1 on the module -- was CF
// Function prototypes
void lcd_strobe(void);
void lcd_write(unsigned char c);
void lcd_clear(void);
void lcd_putch(char c);
void lcd_goto(unsigned char LCD_POS);
void lcd_init(void);
void T2ISR(void);
char int_2_char (unsigned char int1);
// ================================================== ======================================
// Function to strobe the LCD
void lcd_strobe(void) // This function provides the high to low transition needed
// to initiate the actual transfer of commands or data to the module
{
	LCD_EN = 1; 
	Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "1"
	LCD_EN = 0;
	Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "0"
}
// Function to write a command byte to the LCD in 4 bit mode
void lcd_write(unsigned char c)
{
	unsigned char temp1;
	LCD_RS = 0; // Select LCD for command mode
	Delay10TCYx(4); // 40us delay for LCD to settle down at commmand mode
	temp1 = c; 
	temp1 = temp1 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
	PORTD = temp1 & 0x0F; // Output to PORTD which is connected to LCD 
	Delay1KTCYx(1); // Delay at least 1 ms before strobing
	lcd_strobe();
	Delay1KTCYx(1); // Delay at least 1 ms after strobing

	temp1 = c ; // Re-initialise temp2
	PORTD = temp1 & 0x0F; // Mask out upper 4 bits
	Delay1KTCYx(1); // Delay at least 1 ms before strobing
	lcd_strobe();
	Delay1KTCYx(1); // Delay at least 1 ms before strobing 
}
// Function to initialise the LCD
void lcd_init(void)
{
	LCD_RS = 0; // Select LCD for command mode
	LCD_WR = 0; // Select LCD for write mode for only writing of commands
	// and data (ie does not read eg the status of the LCD)
	Delay10KTCYx(100); // Delay a total of 1 s for LCD module to

	// ... after power is applied, a command sequence of 3 bytes of 30h is sent to the module to ensure that the module is in
	// 8-bit mode and properly initialised. Following this, the LCD module can be switched to 4-bit mode. */
	PORTD = 0x03; // Note that PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
	// Thus, PORTD = 0x03 is 0x30 at DB7-0
	lcd_strobe();
	Delay1KTCYx(250); // 250 ms power on delay
	PORTD = 0x03; 
	lcd_strobe();
	Delay1KTCYx(250); // 250 ms power on delay
	PORTD = 0x03; 
	lcd_strobe();
	Delay1KTCYx(250); // 250 ms power on delay
	PORTD = 0x02; // Set to 4-bit mode
	lcd_strobe();
	Delay10KTCYx(50); // 500 ms power on delay
	lcd_write(0x28); // Send a command to set 4 bit mode, 2 line(5x7 font) 
	Delay1KTCYx(20); // 20 ms power on delay 
	lcd_write(0x01); // Send a command to clear display
	Delay1KTCYx(40); // 40 ms power on delay
	lcd_write(0x0F); // Send command to on display and cursor
	Delay1KTCYx(20); // 20 ms power on delay
	lcd_write(0x06); // Send command to put LCD in char entry mode
	Delay1KTCYx(20); // 20 ms power on delay
}
// Clear and home the LCD ie put the cursor at line1, pos1
void lcd_clear(void) // Function to clear LCD display
{
	LCD_RS = 0; // Select LCD for command mode
	Delay10TCYx(4); // 40us delay for LCD to settle down
	lcd_write(0x01); // LCD command 0f 0x01 clears the display
	Delay1KTCYx(2); // Delay at least 2 ms after writing the CLEAR LCD command
}
// Function to put cursor at a specified position
void lcd_goto(unsigned char LCD_POS)
{
	LCD_RS = 0; // Select LCD for command mode
	Delay10TCYx(4); // 40us delay for LCD to settle down at command mode 
	lcd_write(LCD_POS); // Send the cursor position
}
// Function to write a character to the LCD in 4 bit mode
void lcd_putch(char c)
{
	char temp2;
	LCD_RS = 1; // Select LCD for data mode
	Delay10TCYx(4); // 40us delay for LCD to settle down at data mode
	temp2 = c; 
	temp2 = temp2 >> 4;
	PORTD = temp2 & 0x0F; 
	Delay1KTCYx(1); 
	lcd_strobe();
	Delay1KTCYx(1); 
	temp2 = c ; 
	PORTD = temp2 & 0x0F; 
	Delay1KTCYx(1); 
	lcd_strobe();
	Delay1KTCYx(1);
}
// ================================================== ============================================
char outchar; //-- character to send to the LCD
unsigned char hour, minute, second, hour10, hour1, minute10, minute1, second10, second1;
unsigned int tick_count;
void main(void)
{ 
	// RTC code
	hour = 12;
	minute = 34;
	second = 56;
	tick_count = 0;
	T2CON = 0x04; // posS=1, preS=1, Timer 2 ON. 
	PR2 = 199; // Period = 200 x 1us = 0.2 ms with 4-MHz crystal 
	RCONbits.IPEN = 1; // Enable Priority Features 
	IPR1bits.TMR2IP = 1; // Timer 2 is High Priority 
	PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag. 
	PIE1bits.TMR2IE = 1; // Enable Timer 2 Interrupt. 
	INTCONbits.GIEH = 1; // Enable Global Interrupt, High. 
	// LCD code
	ADCON1 = 0x07; // configure PORTA to be digital I/O
	TRISA = 0x00; // set Port A as output
	TRISAbits.TRISA4 = 1; // set RA4 as input pin -- button to Up Hour
	TRISBbits.TRISB0 = 1; // set RB0 as input pin -- button to Up Minute
	TRISD = 0x00; // set Port D as output
	LCD_EN = 0;
	LCD_RS = 0; 
	LCD_WR = 0;
	PORTD = 0x00; 
	Delay1KTCYx(1); // 1 ms power on delay
	lcd_init();
	LCD_RS = 1; // Select LCD for data mode
	Delay1KTCYx(1); // 1 ms power on delay
	lcd_clear();
	// wait forever
	while(1)
	{
	}
}
// RTC code
#pragma code
#pragma interrupt T2ISR // Timer2 -- interrupt service routine
void T2ISR(void)
{
	PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag. 
	tick_count++;
	if (tick_count >= 5000)
	{ // one second's up, (1) check RA4 to update hour (2) check RB0 to update minute (3) update second (4) update display
		tick_count = 0;
		// (1)
		if (!PORTAbits.RA4) // "RA4 pressed", PIC read 0, increment hour
		{
			hour = hour + 1; // increment hour
			if ( hour > 23 )
			hour = 0; // roll over hour
		}
		// (2)
		else if (!PORTBbits.RB0) // "RB0 pressed", PIC read 0, increment minute
		{
			minute = minute + 1; // increment minute
			if ( minute > 59 )
			{
				minute = 0; // roll over minute
				hour = hour + 1; // increment hour
				if ( hour > 23 )
				hour = 0; // roll over hour
			}
		}
		// (3)
		else // increment second
		{
			second = second + 1; // increment second
			if ( second > 59 )
			{
				second = 0; // roll over second
				minute = minute + 1; // increment minute
				if ( minute > 59 )
				{
					minute = 0; // roll over minute
					hour = hour + 1; // increment hour
					if ( hour > 23 )
					hour = 0; // roll over hour
				}
			}
		}
		hour10 = hour / 10;
		hour1 = hour - hour10 * 10;
		minute10 = minute / 10;
		minute1 = minute - minute10 * 10;
		second10 = second / 10;
		second1 = second - second10 * 10;
		// send "time = hh:mm:ss" to LCD display
		lcd_goto(set_dd_line1_pos1);
		lcd_putch('t');
		lcd_putch('i');
		lcd_putch('m');
		lcd_putch('e');
		lcd_putch(' ');
		lcd_putch('=');
		lcd_putch(' ');
		outchar = int_2_char (hour10);
		lcd_putch(outchar);
		outchar = int_2_char (hour1);
		lcd_putch(outchar);
		lcd_putch(':');
		outchar = int_2_char (minute10);
		lcd_putch(outchar);
		outchar = int_2_char (minute1);
		lcd_putch(outchar);
		lcd_putch(':');
		outchar = int_2_char (second10);
		lcd_putch(outchar);
		outchar = int_2_char (second1);
		lcd_putch(outchar);
		// send "enter #seats: _" to LCD display
		lcd_goto(set_dd_line2_pos1);
		lcd_putch('e');
		lcd_putch('n');
		lcd_putch('t');
		lcd_putch('e');
		lcd_putch('r');
		lcd_putch(' ');
		lcd_putch('#');
		lcd_putch('s');
		lcd_putch('e');
		lcd_putch('a');
		lcd_putch('t');
		lcd_putch('s');
		lcd_putch(':');
		lcd_putch(' ');
		// cursor waiting at set_dd_line2_pos1 + 14. If keypad pressed, show no of seats required....
		// lcd_putch('9'); -- example
	}
	return;
}
// ================================================== ===================
// function to convert unsigned char to char (for display)
char int_2_char (unsigned char int1)
{
	char char1;
	switch (int1)
	{
	case 0 : char1 = '0' ; break;
	case 1 : char1 = '1' ; break;
	case 2 : char1 = '2' ; break;
	case 3 : char1 = '3' ; break;
	case 4 : char1 = '4' ; break;
	case 5 : char1 = '5' ; break;
	case 6 : char1 = '6' ; break;
	case 7 : char1 = '7' ; break;
	case 8 : char1 = '8' ; break;
	case 9 : char1 = '9' ; break;
		default : char1 = '?' ;
	}
	return(char1);
}
#pragma code IVH = 0x08 // Interrupt HIGH vector location. 
void IVH(void){ _asm goto T2ISR _endasm }
#pragma code IVL = 0x18 // Interrupt LOW vector location. 
void IVL(void){ _asm goto T2ISR _endasm }
 

Lucysmith

Joined Oct 3, 2008
4
well let me check it in details, well you did not mention what types of character you got as output as if it is non-stop, it means you have problem in some of your loop otherwise let me know your exact problem
 
Top