/****************************************************************************
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 < 16F876.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=6000000 )
#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 );
}