⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainthermo float.c

📁 自己动手做的一个自动温度计,用的是PIC作为控制器.
💻 C
字号:
/* 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 <pic.h>

/* 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 (count<t);
}

static void interrupt isr(void)			// Here be interrupt function - the name is
				                        // unimportant.
{
	if(TMR0IF)		// Was this a timer overflow?
		count++;		// Add 1 to count - insert idle comment
	TMR0IF = 0;		// Clear interrupt flag, ready for next
    TMR0=PRETMR0;
}

int strlen(const char * s)
{
	const char *cp;

	cp = s;
	while(*cp++)
		continue;
	return cp-s-1;
}

void print(char *s){
 int len;
 int atmp;
 len=strlen(s);
 for (atmp=0; atmp<len; atmp++)
   wdata(s[atmp]);
}


/* before we write to LCD , must check if the LCD IS busy */
void lcdbusy(){
 // char tmpbusy;
 TRISA &= 0xF1;
 TRISC=0XFF;
 LCDRS=0;
 LCDRW=1; 
 LCDE=1;                  /* SET the LCD read/writing operation IN TO IDLE */
 while(LCDDATA & 0X80);
}

/* position cursor, 
   line= 0 for first line, or 1 for second line,
   col=0 - 15 ;
  */
void poscursor(char line, char col){
 char pos;
 lcdbusy();
 pos = line * 0X40 + 0X80 + col;
 wcmd(pos);
}

void wdata(char data) {

 lcdbusy();
 TRISA & =0XF1;
 TRISC=0;
 LCDDATA=data;
 LCDRS=1;
 LCDRW=0;
 LCDE=0;
 asm("NOP");
 asm("NOP");
 LCDE=1;
}

void wcmd(char cmd){
 
 lcdbusy();
 TRISA & =0XF1;
 TRISC=0;
 LCDDATA=cmd;
 LCDRS=0;
 LCDRW=0;
 LCDE=0;
 asm("NOP");
 asm("NOP");
 LCDE=1;
}
  
void lcdinit() {
 lcdbusy();
 TRISA &= 0XF1;
 TRISC=0;
 
 wcmd(CLRLCD); 
 wcmd(LCDMOD);
 wcmd(TURNON);
 wcmd(CURMODE); 
 poscursor(0,0);      /* set cursor to first position of first line */
}



/* DS1820  
  This file working with 16F877 using
  RA0 pin to communate  */

/* INIT   */
void dsinit(){
 TRISDQ=0;
 DSDQ=0;
 delay(20);  /* keep DSDQ low for 10*50 us, to reset the DS1820 */
 TRISDQ=1;   
 delay(1);   /* here we can only use delay(1), more then one may go out of the sample window */ 


// if (!DSDQ)  /* sample window between min end:15+60, max begin,60 */
             /* garrente sample window is between 60 to 75 us */
//  print(dsfound);
// else 
//  print(dsnotfound);
delay(10); /* wait for more then 480us, as required by the DS18B20  */ 
}

/* write command  to DS1820*/

void wdscmd(char cmd){
 char tmp;
 char i;
 TRISDQ=0;
 for(tmp=8;tmp>0;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)<length/2; rem++) {
			*(buf+length) = *(buf+((unsigned char)rem));
			*(buf+((unsigned char)rem)) = *(buf+(length-((unsigned char)rem)-1));
			*(buf+(length-((unsigned char)rem)-1)) = *(buf+length);
		}
	}
    *s=0;
}





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -