CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

change 4 bit to 8 bit lcd code

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
evaang2003



Joined: 10 Jun 2009
Posts: 14

View user's profile Send private message Send e-mail

change 4 bit to 8 bit lcd code
PostPosted: Sun Jun 14, 2009 7:38 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 14, 2009 9:10 pm     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=38367
evaang2003



Joined: 10 Jun 2009
Posts: 14

View user's profile Send private message Send e-mail

PostPosted: Mon Jun 15, 2009 1:44 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Jun 16, 2009 8:28 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 16, 2009 10:21 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Jun 16, 2009 10:27 pm     Reply with quote

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?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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