機電之家資源網(wǎng)
單片機首頁|單片機基礎|單片機應用|單片機開發(fā)|單片機文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓信息
贊助商
PIC16F877A_LCD1602溫度顯示
PIC16F877A_LCD1602溫度顯示
 更新時間:2008-7-27 15:50:31  點擊數(shù):4
【字體: 字體顏色
/* 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 LCDRWRA2#define LCDERA3#define LCDDATAPORTC#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 intcount;#define PRETMR0 210     /* aproximately 50us INT interval, 256-210 PLUS some headcost,*/float temperature;#define DSRESET 10#define DSRECOVER 1char 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 commentTMR0IF = 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;}
  • 上一篇: 單片機C51串口中斷接收和發(fā)送測試例程(含通信協(xié)議的實現(xiàn))
  • 下一篇: 16c54四位LED時鐘顯示程序
  • 發(fā)表評論   告訴好友   打印此文  收藏此頁  關閉窗口  返回頂部
    熱點文章
     
    推薦文章
     
    相關文章
    網(wǎng)友評論:(只顯示最新5條。)
    關于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機電之家 | 會員助手 | 免費鏈接

    點擊這里給我發(fā)消息66821730(技術支持)點擊這里給我發(fā)消息66821730(廣告投放) 點擊這里給我發(fā)消息41031197(編輯) 點擊這里給我發(fā)消息58733127(審核)
    本站提供的機電設備,機電供求等信息由機電企業(yè)自行提供,該企業(yè)負責信息內容的真實性、準確性和合法性。
    機電之家對此不承擔任何保證責任,有侵犯您利益的地方請聯(lián)系機電之家,機電之家將及時作出處理。
    Copyright 2007 機電之家 Inc All Rights Reserved.機電之家-由機電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術支持

    主辦:杭州市高新區(qū)(濱江)機電一體化學會
    中國行業(yè)電子商務100強網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1