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 support@ccsinfo.com

DS18S20 8 bit lcd

 
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

DS18S20 8 bit lcd
PostPosted: Tue Jun 16, 2009 10:06 pm     Reply with quote

hi, i am trying to do temperature sensor using ds18s20 and display it on 8 bit lcd module.

the pic i am using is 16f877a and below is the source code that i modified from a 4 bit lcd temperature sensor source code.

Howver, it didn't work. the problem occur i think is due to the 8 bit lcd code that i have included. can anybody help me with the code?

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_D0
#define LCD_D1      PIN_D1
#define LCD_D2      PIN_D2
#define LCD_D3      PIN_D3
#define LCD_D4      PIN_D4
#define LCD_D5      PIN_D5
#define LCD_D6      PIN_D6
#define LCD_D7      PIN_D7

#define LCD_EN      PIN_C5
#define LCD_RS      PIN_C6

#define LINE_1      0x00
#define LINE_2      0x40
#define CLEAR_DISP  0x01
#define DEGREE_SYM  0xdf

#define TOTAL_CHARACTERS_OF_LCD 32


#use delay ( clock=4000000 ) // 4MHz crystal is used
#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 InitLCD ( void );
void GoToLine( int line );
void WriteChar(char character);
void WriteString(char LineOfCharacters[TOTAL_CHARACTERS_OF_LCD]);

////////////////////////////////
static char cShiftBit,cDataOut;
static long iTemperature,iDataIn;


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
       }
    }
////////////////////////////////////////////////////////////////////////////////////

#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 = 0x05 //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

void WriteString(char LineOfCharacters[TOTAL_CHARACTERS_OF_LCD])
{
printf(WriteChar,"%c", LineOfCharacters);
}






void main ( void )
    {
    Char LineOfCharacters;
    InitLCD();
    GoToLine(1);
    printf(WriteChar,"temperature is", LineOfCharacters);

    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;
        GoToLine(2);
        printf ( WriteChar, "%lu%cC %lu%cF", iTemperature, DEGREE_SYM, ( ( 9 * iTemperature ) / 5 ) + 32, DEGREE_SYM  );
    }
    }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

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

The schematic diagram doesn't match your code. It shows Port B is
used for a 4-bit interface to the LCD, and the R/W line on the LCD is
not used. (It's presumably connected to Ground).

Why spend so much time on an 8-bit LCD interface ? What's the reason ?
evaang2003



Joined: 10 Jun 2009
Posts: 14

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

PostPosted: Wed Jun 17, 2009 12:20 am     Reply with quote

This is because the lcd I use can only run in 8 bit.
That's why I'm very headache about it.

The schematic is for 4 bit lcd.
But the lcd driver I post is 8 bit.
Yet the program I write cannot work.
Any suggestion?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 17, 2009 2:07 pm     Reply with quote

Test only one thing at a time. First get the LCD working. Then work
on the ds18s20 code.

Who is the manufacturer and what is part number of your LCD ?
evaang2003



Joined: 10 Jun 2009
Posts: 14

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

PostPosted: Wed Jun 17, 2009 8:43 pm     Reply with quote

Well, the lcd I use is lmb162hba.
I have solved the lcd display text problem already.

Now the problem I encounter is to get the correct temperature in degrees Celsius.
However, based on the main source code I have posted, the lcd display
shows very weird readings. It gives me the symbol which corresponds to 255 dec.

Can you tell me how to do the correct temperature calculation for dallas 18s20?
evaang2003



Joined: 10 Jun 2009
Posts: 14

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

PostPosted: Thu Jun 18, 2009 2:36 am     Reply with quote

The code that have been modified is as follow:
Code:

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 / 1000;
        LCD_SetPosition ( LINE_2 + 5 );
        printf ( LCD_PutChar, "%lu%cC %lu%cF   ", iTemperature, DEGREE_SYM, ( ( 9 * iTemperature ) / 5 ) + 32, DEGREE_SYM  );
        }
    }

the lcd display 32767degree celcius.
why the output is 1111 1111 1111 1111?

how to test if my ds18s20 is functional or not?
evaang2003



Joined: 10 Jun 2009
Posts: 14

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

PostPosted: Thu Jun 18, 2009 2:45 am     Reply with quote

erm, please let me do the correction.
the
iTemperature = iDataIn / 1000
is actually
iTemperature = iDataIn / 2
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 10:46 am     Reply with quote

Where did you get the ds18s20 driver ?

Try using Han Solo's driver in the Code Library. Also use his test
program:
http://www.ccsinfo.com/forum/viewtopic.php?t=28425
evaang2003



Joined: 10 Jun 2009
Posts: 14

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

PostPosted: Thu Jun 18, 2009 9:22 pm     Reply with quote

I get the code from somewhere I think is www.vermontficks.org.
I can't recall it.

I try the code that you post.
The result give me 0.5 degree celcius.

I don't understand why.
Could it be my hardware problem?
I connect the Vq pin of dallas to pin B7 which I later define.
evaang2003



Joined: 10 Jun 2009
Posts: 14

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

PostPosted: Thu Jun 18, 2009 9:23 pm     Reply with quote

Another question, how do Dallas sense temperature?
From the black encapsulate head?
Ave_Rapina



Joined: 10 Apr 2008
Posts: 1

View user's profile Send private message

PostPosted: Tue Aug 18, 2009 1:07 pm     Reply with quote

Here is a tested code working fine:
Code:

//////////////////////////////////////////////////////////////////////////
////                               DS1820.C                           ////
////                Driver for one wire temperature sensor            ////
////                                                                  ////
////  ds1820_read()             Retuns an float - Standard Supply     ////
////                                                                  ////
////  ds1820_read_paras()       Set                                   ////
////                                                                  ////
//////////////////////////////////////////////////////////////////////////
////  Author:                                             ////
////                                                                  ////
////  Date: 18/07/2009                                                ////
////                                                                  ////
////  State: Complete and Tested                                      ////
////                                                                  ////
////  Notes: Need implement with parasite supply                      ////
////                                                                  ////
////  Sugest: Comments are Welcome!!!!                                ////
////                                                                  ////
////                                                                  ////
//////////////////////////////////////////////////////////////////////////

//#define PARASITE_VCC_PIN PIN_c1

#define ONE_WIRE_PIN PIN_c0
void onewire_reset()

{
output_low(ONE_WIRE_PIN);
delay_us( 500 ); //1-wire Reset time
output_float(ONE_WIRE_PIN);
delay_us( 500 ); //
output_float(ONE_WIRE_PIN);
}

void onewire_write(int data)
{
int count;
for (count=0; count<8; ++count)
{
output_low(ONE_WIRE_PIN);
delay_us( 2 );
output_bit(ONE_WIRE_PIN, shift_right(&data,1,0));
delay_us( 60 );
output_float(ONE_WIRE_PIN);
delay_us( 2 );
}
}

int onewire_read()
{
int count, data;
for (count=0; count<8; ++count)
{
output_low(ONE_WIRE_PIN);
delay_us( 2 );
output_float(ONE_WIRE_PIN);
delay_us( 8 );
shift_right(&data,1,input(ONE_WIRE_PIN));
delay_us( 120 );
}
return( data );
}

float ds1820_read()
{
int8 busy=0, temp1, temp2;
signed int16 temp3;
float result;
onewire_reset();
onewire_write(0xCC);
onewire_write(0x44);
while (busy == 0)
busy = onewire_read();
onewire_reset();
onewire_write(0xCC);
onewire_write(0xBE);
temp1 = onewire_read();
temp2 = onewire_read();
temp3 = make16(temp2, temp1);
result = (float) temp3 / 2.0;
delay_ms(200);
return(result);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 18, 2009 1:24 pm     Reply with quote

Your post is simply a copy of HanSolo's post in the Code Library, here:
http://www.ccsinfo.com/forum/viewtopic.php?t=28425
Wouldn't it have been better just to provide a link ?
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