/* THIS THERMOMETER USE THE MCD2 DEMO BOARD TO DISPLAY THE temprature degree. USING 16F877 READ MAXIM DS18b20 AND DISPLAY ON LCD1602 */ /* ver1.1 May 2006 by Freeman(ΧΤΣΙΘΛ) On the demo board, original DQ pin of DS18B20 is connected to PORTA.2 through a switch, have some conflict with LCD which also use PORTA.2 so I just keep the switch OFF, and fly a wire from pin DQ to PORTA.0 directly. the program of ver 1.0 only display a integer degree, ver 1.1 can display float point. with 1 decimal fraction. the difference as follow : int dsread() ---> float dsread() int temperature ---> float temperature some change in itoa10(char, int ); */ #include /* PIN define */ #define LCDRS RA1 #define LCDRW RA2 #define LCDE RA3 #define LCDDATA PORTC #define DSDQ RA0 /* ds18b20 */ #define TRISDQ TRISA0 /* function define */ void lcdinit(); /* two line mode */ void wcmd (char cmd); void wdata (char data); void poscursor(char line, char col); void print(char *s); void lcdbusy(); void delay ( int t); void itoa10(unsigned char *buf, int i); int strlen (const char *s); void dsinit(); void wdscmd(char cmd); float dsread (); /* constant define */ char bank1 title[]= "Temperature is"; char dsfound[]="DS1820 FOUND"; char dsnotfound[]="DS1820 NOT FOUND"; char bank1 blank[]= " "; /* LCD command define */ #define CLRLCD 0X01 #define LCDMOD 0X38 /* 8 BIT, TWO LINE, 5X7 DOT MATRIX */ #define TURNON 0X0F /* turn on LCD, CURSOR, BLINKING */ #define CURMODE 0X06 /* character don't move, cursor move right automaticall */ /* DS1820 command */ #define SKIPROM 0XCC #define READSCRACHPAD 0XBE #define TCONVERT 0X44 /* ORIGINAL CURSOR POSITION */ #define ORG1 0X80 #define ORG2 0XC0 /* TMR0 */ static int count; #define PRETMR0 210 /* aproximately 50us INT interval, 256-210 PLUS some headcost,*/ float temperature; #define DSRESET 10 #define DSRECOVER 1 char bank1 atemperature[10]; /* used for store ascii code of digital temperature */ void main(){ int len; ADCON1=0X07; /* SET PORTA AS DIGITAL I/O */ lcdinit(); print(title); LCDE=0; /* when LCDE=0, MCU will not affect LCD, and we can operate DS1820 */ /* INIT TIMER0 */ OPTION=0B11001111; /* bit5=0, using internal instruciton cycle clock */ TMR0IE=1; /* enable timer0 */ PEIE=0; /* disables all peripheral interrupts */ GIE=1; poscursor(1,0); while (1) { dsinit(); wdscmd(SKIPROM); wdscmd(TCONVERT); TRISDQ=0; DSDQ=0; TRISDQ=1; while(1) { //test if the conversion finished if (DSDQ) break; else continue; } dsinit(); wdscmd(SKIPROM); wdscmd(READSCRACHPAD); temperature=dsread(); /* read temperature */ itoa10(atemperature, (int) (temperature * 10)); /* because the itoa10 only works with integer */ // so use temperature * 10 to enlarge the temperature // and then add a decimal point in the function /* the following put a decimal dot '.' before the last digit of the atemperature */ len=strlen(atemperature); atemperature[len]=atemperature[len-1]; atemperature[len-1]='.'; atemperature[len+1]=0; poscursor(0,0); print (title); poscursor(1,0); print (blank); poscursor(1,2); print (atemperature); print (blank); delay(10000); /* wait for 10000*50 us=0.5 s before get new temperature */ } } void delay (int t){ count=0; /* reset timer 0 */ TMR0=PRETMR0; while (count0;tmp--) { TRISDQ=0; DSDQ= 0; asm ("NOP"); asm ("NOP"); asm ("NOP"); asm ("NOP"); asm ("NOP"); if (cmd & 0x01) { TRISDQ=1; /* release the bus */ delay(1); /* wait for more than 60 us */ for (i=5;i>0;i--); } else { DSDQ=0 ; delay(1); for (i=5;i>0;i--); TRISDQ=1; } cmd=cmd/2; } } /* READ temperature */ float dsread () { char tmp=0x01; float t; union{ char c[2]; int x; }temp; temp.x=0; while (tmp){ // read first 8 bits TRISDQ=0; DSDQ=0; asm("NOP"); TRISDQ=1; // release the bus if (DSDQ) // "1" presented temp.c[0] |= tmp; tmp=tmp<<1; delay(2); } tmp=1; while (tmp){ // read first 8 bits TRISDQ=0; DSDQ=0; asm("NOP"); TRISDQ=1; // release the bus asm("NOP"); if (DSDQ) // "1" presented temp.c[1] |= tmp; tmp=tmp<<1; delay(2); } t=((float) temp.x)/16.0 ; return t; } /* Convert integer 'i', radix 10 to a string */ void itoa10(unsigned char *buf, int i) { unsigned int rem; unsigned char *s,length=0; s = buf; if (i == 0) *s++ = '0'; else { if (i < 0) { *buf++ = '-'; s = buf; i = -i; } while (i) { ++length; rem = i % 10; *s++ = rem + '0'; i /= 10; } for(rem=0; ((unsigned char)rem)