| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| evaang2003 
 
 
 Joined: 10 Jun 2009
 Posts: 14
 
 
 
			      
 
 | 
			
				| DS18S20 8 bit lcd |  
				|  Posted: Tue Jun 16, 2009 10:06 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Jun 16, 2009 10:28 pm |   |  
				| 
 |  
				| 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
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Jun 17, 2009 12:20 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Jun 17, 2009 2:07 pm |   |  
				| 
 |  
				| 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
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Jun 17, 2009 8:43 pm |   |  
				| 
 |  
				| 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
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Thu Jun 18, 2009 2:36 am |   |  
				| 
 |  
				| 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
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Thu Jun 18, 2009 2:45 am |   |  
				| 
 |  
				| erm, please let me do the correction. the
 iTemperature = iDataIn / 1000
 is actually
 iTemperature = iDataIn / 2
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 |  |  
		|  |  
		| evaang2003 
 
 
 Joined: 10 Jun 2009
 Posts: 14
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Thu Jun 18, 2009 9:22 pm |   |  
				| 
 |  
				| 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
 
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Thu Jun 18, 2009 9:23 pm |   |  
				| 
 |  
				| Another question, how do Dallas sense temperature? From the black encapsulate head?
 |  |  
		|  |  
		| Ave_Rapina 
 
 
 Joined: 10 Apr 2008
 Posts: 1
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Aug 18, 2009 1:07 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |