|
|
View previous topic :: View next topic |
Author |
Message |
evaang2003
Joined: 10 Jun 2009 Posts: 14
|
change 4 bit to 8 bit lcd code |
Posted: Sun Jun 14, 2009 7:38 pm |
|
|
Hi, I'm trying to change the following code to suit my 8 bit lcd.
Can anybody show me?
This is the code using ds1820 to display temperature on 4 bit lcd.
Code: |
/*********************************************************
ds1820_2a.c
Reads and displays temperature.
--------- --------
+5--20-|Vdd B0|-21-11-|D0 |
| B1|-22-12-|D1 |
Gnd---8-|Vss B2|-23-13-|D2 |
Gnd--19-|Vss B3|-24-14-|D3 |
6MHz--10-|Xtal B4|-25--6-|EN |
---9-|Xtal B5|-26--4-|RS |
| | --------
| 16F876 |-1----MCLR
| B6|-26---Clock
| B7|-27---Data
| |
DataIn---11|C0 |
---------
**********************************************************/
#include < 16F877a.H >
#include < jonsinc.h >
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#define DS1820_DATA_IN_PIN PIN_C0
#define DS1820_FET_CONTROL_PIN PIN_C1
#define DS1820_SKIP_ROM 0xCC
#define DS1820_READ_SCRATCHPAD 0xBE
#define DS1820_CONVERT_T 0x44
// LCD STUFF
#define LCD_D0 PIN_B0
#define LCD_D1 PIN_B1
#define LCD_D2 PIN_B2
#define LCD_D3 PIN_B3
#define LCD_EN PIN_B4
#define LCD_RS PIN_B5
#define LINE_1 0x00
#define LINE_2 0x40
#define CLEAR_DISP 0x01
#define DEGREE_SYM 0xdf
#use delay ( clock=4000000 )
#use standard_io ( A )
#use standard_io ( B )
#use standard_io ( C )
void ResetDS1820 ( void );
void WriteDS1820 ( void );
void ReadDS1820 ( void );
void WaitForConversion ( void );
void LCD_Init ( void );
void LCD_SetPosition ( unsigned int cX );
void LCD_PutChar ( unsigned int cX );
void LCD_PutCmd ( unsigned int cX );
void LCD_PulseEnable ( void );
void LCD_SetData ( unsigned int cX );
static char cShiftBit,cDataOut;
static long iTemperature,iDataIn;
void main ( void )
{
delay_ms ( 200 );
LCD_Init();
LCD_SetPosition ( LINE_1 + 0 );
printf ( LCD_PutChar, "Temperature is" );
while ( TRUE )
{
ResetDS1820();
cDataOut = DS1820_SKIP_ROM;
WriteDS1820();
cDataOut = DS1820_CONVERT_T;
WriteDS1820();
WaitForConversion();
ResetDS1820();
cDataOut = DS1820_SKIP_ROM;
WriteDS1820();
cDataOut = DS1820_READ_SCRATCHPAD;
WriteDS1820();
ReadDS1820();
iTemperature = iDataIn / 2;
LCD_SetPosition ( LINE_2 + 5 );
printf ( LCD_PutChar, "%lu%cC %lu%cF ", iTemperature, DEGREE_SYM, ( ( 9 * iTemperature ) / 5 ) + 32, DEGREE_SYM );
}
}
void ResetDS1820 ( void )
{
output_low ( DS1820_DATA_IN_PIN ); // low
delay_us ( 480 ); // reset pulse width
output_float ( DS1820_DATA_IN_PIN ); // high
delay_us ( 480 ); // presence pulse width
}
void WriteDS1820 ( void ) // ~70uS per bit
{
for ( cShiftBit = 1; cShiftBit <= 8; ++cShiftBit )
{
output_low ( DS1820_DATA_IN_PIN );
delay_us ( 5 );
output_bit ( DS1820_DATA_IN_PIN, shift_right ( &cDataOut, 1, 0 ) );
delay_us ( 60 );
output_float ( DS1820_DATA_IN_PIN );
delay_us ( 5 ); // recovery time between slots
}
//delay_us ( 200 ); // ???
}
void ReadDS1820 ( void ) // ~70uS per bit
{
iDataIn = 0;
for ( cShiftBit = 1; cShiftBit <= 16; ++cShiftBit )
{
output_low ( DS1820_DATA_IN_PIN );
delay_us ( 5 );
output_float ( DS1820_DATA_IN_PIN );
delay_us ( 5 );
shift_right ( &iDataIn, 2, input ( DS1820_DATA_IN_PIN ) ); // sample bit
delay_us ( 55 ); // includes recovery time between slots
}
ResetDS1820(); // terminate remainder of scratchpad register transmission
}
void WaitForConversion ( void ) // ~70uS per bit
{
while ( TRUE )
{
output_low ( DS1820_DATA_IN_PIN );
delay_us ( 5 );
output_float ( DS1820_DATA_IN_PIN );
delay_us ( 5 );
if ( input ( DS1820_DATA_IN_PIN ) == 1 ) // sample bit
{
break;
}
delay_us ( 55 ); // includes recovery time between slots
}
}
void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms ( 200 ); // wait enough time after Vdd rise
output_low ( LCD_RS );
LCD_SetData ( 0x03 ); // init with specific nibbles to start 4-bit mode
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); // set 4-bit interface
LCD_PulseEnable(); // send dual nibbles hereafter, MSN first
LCD_PutCmd ( 0x2C ); // function set (all lines, 5x7 characters)
LCD_PutCmd ( 0x0C ); // display ON, cursor off, no blink
LCD_PutCmd ( 0x01 ); // clear display
LCD_PutCmd ( 0x06 ); // entry mode set, increment
}
void LCD_SetPosition ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
void LCD_PutChar ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
output_high ( LCD_RS );
LCD_SetData ( swap ( cX ) ); // send high nibble
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); // send low nibble
LCD_PulseEnable();
output_low ( LCD_RS );
}
void LCD_PutCmd ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
LCD_SetData ( swap ( cX ) ); // send high nibble
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); // send low nibble
LCD_PulseEnable();
}
void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 10 );
output_low ( LCD_EN );
delay_ms ( 5 );
}
void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D0, cX & 0x01 );
output_bit ( LCD_D1, cX & 0x02 );
output_bit ( LCD_D2, cX & 0x04 );
output_bit ( LCD_D3, cX & 0x08 );
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
evaang2003
Joined: 10 Jun 2009 Posts: 14
|
|
Posted: Mon Jun 15, 2009 1:44 am |
|
|
Well, I use the 8 bit driver and change it into the following code.
However, it can't be compiled. Look at the bold one.
Why?
Quote: |
void main ( void )
{
char LINE1[]={ "temperature is" };
char LINE2[]={ " %lu%cC %lu%cF ", iTemperature, DEGREE_SYM, ( ( 9 * iTemperature ) / 5 ) + 32, DEGREE_SYM };
delay_ms ( 200 );
lcd_Init();
lcd_display_str(0, LINE1);
while ( TRUE )
{
ResetDS1820();
cDataOut = DS1820_SKIP_ROM;
WriteDS1820();
cDataOut = DS1820_CONVERT_T;
WriteDS1820();
WaitForConversion();
ResetDS1820();
cDataOut = DS1820_SKIP_ROM;
WriteDS1820();
cDataOut = DS1820_READ_SCRATCHPAD;
WriteDS1820();
ReadDS1820();
iTemperature = iDataIn / 2;
lcd_display_str(1, LINE2);
}
//////////////////////////////////////////////// lcd_write_cmd()
//
void lcd_write_cmd(int8 cmd)
{
delay_us(400);
output_low(LCD_RS);
output_low(LCD_RW);
output(LCD_DAT, cmd);
output_high(LCD_E);
delay_us(400);
output_low(LCD_E);
}//end lcd_write_cmd()
/////////////////////////////////////////////// lcd_write_dat()
//
void lcd_write_dat(int8 dat)
{
delay_us(400);
output_high(LCD_RS);
output_low(LCD_RW);
output(LCD_DAT, dat);
output_high(LCD_E);
delay_us(400);
output_low(LCD_E);
}//end lcd_write_dat()
//////////////////////////////////////////// lcd_init()
//
void lcd_init(void)
{
output_low(LCD_E); // Let LCD E line low
lcd_write_cmd(0x38); // LCD 16x2, 5x7, 8bits data
delay_ms(15);
lcd_write_cmd(0x01); // Clear LCD display
delay_ms(10);
lcd_write_cmd(0x0f); // Open display & current
delay_ms(10);
lcd_write_cmd(0x06); // Window fixed
delay_ms(10);
}//end lcd_init()
///////////////////////////////////////// lcd_display_char()
//
void lcd_display_char(int8 line, int8 pos, int8 ch)
{
int8 tmp;
line = (line==0) ? 0 : 1;
pos = (pos >NCHAR_PER_LINE) ? NCHAR_PER_LINE : pos;
tmp = 0x80 + 0x40*line + pos;
lcd_write_cmd(tmp);
lcd_write_dat(ch);
}//end lcd_display_char()
/////////////////////////////////////////// lcd_display_str()
//
void lcd_display_str(int8 line, char str[])
{
int8 i;
for(i=0; i<NCHAR_PER_LINE; i++)
{
lcd_display_char(line, i, ' ');
}
for(i=0; i<NCHAR_PER_LINE; i++)
{
if(str[i] == '\0') break;
lcd_display_char(line, i, str[i]);
}
}//end lcd_display_str() |
|
|
|
evaang2003
Joined: 10 Jun 2009 Posts: 14
|
|
Posted: Tue Jun 16, 2009 8:28 pm |
|
|
well, i have found hd44780 8 bit lcd driver.
however, the program i write do not display text.
can anybody tell me what's wrong?
the main() is the program i wrote while the rest of the fuction is 8 bit driver.
Code: |
#INCLUDE<16F877a.H>
#include<string.h>
#use delay(clock=40000000)
#include<stdio.h>
#define IR 0
#define DR 1
#define READ 1
#define WRITE 0
#define lcd_2X16
/* Defines the bits for Port C */
struct {
int unused:5; //The first 5 bits are not used by the LCD
int en:1; //EN is the 6th bit of Port C RC5
int rs:1; //RS is the 7th bit of Port C RC6
int rw:1; //RW is the 8th bit of Port C RC7
}LCDControl;
#byte LCDData = 0x08 //Defines the address of the variable LCDData
//as that of Port D
#byte LCDControl = 0x07 //Defines the address of the structure
//LCDControl as that of Port C
#byte LCDDataDir =0x88 //Defines the address of the variable
//LCDDataDir as that of TrisD
#byte LCDConDir = 0x87 //Defines the address of the variable
//LCDConDir as that of TrisC
#define LCD_DATA_IN LCDDataDir|=0xFF //to set the data lines as input
#define LCD_DATA_OUT LCDDataDir&=0x00 //to set the data lines as output
#define LCD_CON_OUT LCDConDir&=0x1F //to set the control lines as output
/************************The WriteByte function *******************/
/*
This function writes a byte to the LCD module with an 8-bit
interface
Input Parameters:
int rs This variable selects the register being written to.
DR selects the data register
IR selects the instruction register
int data_to_lcd This variable stores the data that will be written to
the selected register
*/
void WriteByte(short int rs, int data_to_lcd)
{
LCD_DATA_OUT; //LCD Data Bus is an output
LCDControl.rw = WRITE; //The operation is a write operation
LCDControl.rs = rs; //Selects the register (DR or IR)
delay_us(1); //Wait a minimum of 60ns
LCDControl.en = 1; //Raise EN
LCDData = data_to_lcd; //Set the Data Bus to the desired value
delay_us(1); //Wait a minimum of 195ns
LCDControl.en = 0; //Clear EN
delay_us(1); //Keep RS and RW at their current states for a
//minimum of 20ns
//Also, keep the current value at the Data Bus
//for a minimum of 10ns
}
/************************The ReadByte function *******************/
/*
This function reads a byte from the LCD module with an 8-bit
interface
Input Parameters:
int rs This variable selects the register being read from.
DR selects the data register
IR selects the instruction register
Output Value: The function returns the value of the byte read
*/
int ReadByte(short int rs)
{
int data_from_lcd; //This variable is used to store the byte
//read from the Data Bus
LCD_DATA_IN; //Port D is an input port
LCDControl.rw = READ; //The operation is a read operation
LCDControl.rs = rs; //Selects the register (DR or IR)
delay_us(1); //Wait a minimum of 60ns
LCDControl.en = 1; //Raise EN
delay_us(1); //Wait a minimum of 360ns
data_from_lcd = LCDData;//Read the value across the Data Bus
LCDControl.en = 0; //Clear EN
delay_us(1); //Keep RS and RW at their current states
//for a minimum of 20ns
return data_from_lcd;
}
//This function reads the IR register, returning 1 if the LCD module is busy or 0 if it is not
/************************The CheckBusyFlag function ******************/
/* This function reads a byte from the instruction register and
tests the 8th bit, which is the busy Flag
Output Value: The function returns
1 if the Busy Flag is set (LCD module busy)
0 if the Busy Flag is clear (LCD module is not
busy)
*/
short int CheckBusyFlag(void)
{
int data_from_lcd; //This variable is used to store the byte
//read from the LCD
data_from_lcd = ReadByte(IR); //Read the IR (rs=0)
return (bit_test(data_from_lcd,7)); //Test the BF
//Return 1 if set
//Return 0 if clear
}
/************************The InitLCD function *******************/
/* This function initialises the LCD module (Initialisation by
instruction).
Initialisation Parameters:
Interface 8-bit
Number of display lines 2-line or 4-line
Cursor shift direction Increment
Font size 5x8dots
Display On
Cursor Off
Cursor blink Cursor blink
*/
void InitLCD(void)
{
delay_ms(15); //Delay a minimum of 15ms
WriteByte(IR,0b00111000); //Define function set
//8-bit interface, 2-line or 4-line display, 5x8 font
delay_ms(5); //Delay a minimum of 4.1ms
WriteByte(IR,0b00111000); //Redefine function set
delay_us(100); //Delay a minimum of 100us
WriteByte(IR,0b00111000); //Redefine function set
while(CheckBusyFlag()); //Wait until BF = 0
WriteByte(IR,0b00001100); //Define display on/off control
//display on, cursor off, cursor blink off
while(CheckBusyFlag()); //Wait until BF = 0
WriteByte(IR,0b00000001); //Clear Display
while(CheckBusyFlag()); //Wait until BF = 0
WriteByte(IR,0b00000110); //Entry mode set
//cursor direction increment, do not shift display
}
// WRITING A CHARACTER TO LCD
/************************The WriteChar function *******************/
/* This function displays a character on the LCD.
Input Parameters:
char character This variable stores the character to be displayed on
the LCD.
*/
void WriteChar(char character)
{
while(CheckBusyFlag()); //Wait until the LCD module is not busy
WriteByte(DR,character);//Write character to DR
}
// SENDING A COMMAND TO LCD
/************************The PutCommand function *******************/
/* This function writes a byte to the instruction register.
Input Parameters:
int command This variable stores the byte to be written to the
instruction register.
*/
void PutCommand(int command)
{
while(CheckBusyFlag()); //Wait until the LCD module is not busy
WriteByte(IR,command); //Write command to IR
}
/************************The GoToLine function *******************/
/* This function sets the cursor to the first position of a
specified line of the LCD.
Input Parameters:
int line This variable selects the LCD line on which the
cursor is to be set.
*/
void GoToLine(int line)
{
int address; //This variable is used to determine the
//address at which the cursor is to be set
switch (line) //Set address to the first DDRAM address of the
//specified line
{
case 1:
address = 0x00;
break;
case 2:
address = 0x40;
break;
case 3:
address = 0x14;
break;
case 4:
address = 0x54;
break;
default: //An undefined line set the cursor home
address = 0x00;
break;
}
bit_set(address,7); //Bit 7 identifies the instruction as Set
//DDRAM address
PutCommand(address); //Set the DDRAM address
}
//WRITING A STRING OF CHARACTERS TO LCD
#define TOTAL_CHARACTERS_OF_LCD 32
void WriteString(char LineOfCharacters[TOTAL_CHARACTERS_OF_LCD])
{
printf(WriteChar,"%c", LineOfCharacters);
}
void main ()
{
char LineOfCharacters[4]={"abc"};
InitLCD();
GoToLine(2);
printf(WriteChar,"%c", LineOfCharacters);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 16, 2009 10:21 pm |
|
|
Quote: | #INCLUDE<16F877a.H>
#include<string.h>
#use delay(clock=40000000)
#include<stdio.h> |
The #fuses statement is missing, and the 16F877A can't run at 40 MHz. |
|
|
evaang2003
Joined: 10 Jun 2009 Posts: 14
|
|
Posted: Tue Jun 16, 2009 10:27 pm |
|
|
well, i have included the
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
and change the clock to 4 MHz.
However, it still can't run.
Why? |
|
|
|
|
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
|