久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7225|回復: 9
打印 上一主題 下一主題
收起左側

用1602LCD與DS18B20設計的溫度報警器

  [復制鏈接]
跳轉到指定樓層
樓主
ID:110638 發表于 2016-3-24 21:16 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <reg52.h>
#include<intrins.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
sbit RW = P1^1;          //定義LCD的讀、寫選擇端
sbit RS = P1^0;           //定義LCD的數據、命令選擇端
sbit EN = P1^2;                 //定義LCD的使能信號端
sbit DS = P3^5;                 //定義DS18B20的IO口
sbit L=P1^3;                 //綠燈
sbit H=P1^4;                 //紅燈
sbit LS=P3^4;                 //蜂鳴器
sbit k1=P2^4;                 //顯示64位的ROM
sbit k2=P2^3;                 //顯示當前溫度
sbit k3=P2^0;                 //顯示溫度上限及下線,并支持調節
sbit k4=P2^1;                 //        上限加
sbit k5=P2^2;                  //        下限減
uchar k=2;                         //當前溫度顯示標志位
uchar table0[] = " Current Temp : ";         //當前溫度
uchar table1[] = " -- ROM CODE -- ";         //顯示DS18B20的ROM
uchar table2[] = "ALARM TEMP Hi Lo";         //顯示上下限溫度
uchar table3[] = "Hi:    Lo:      ";
uchar table4[] = {0,0,0,0,0,0,0,0};
uchar tempHL[] = { 20, 1};                                 //上下限溫度的初始值                                                                                  
void delayms(uint a)     //延時函數
{
    uint i,j;
    for(i = a; i > 0; i--) for(j = 100; j > 0; j--);
}
void writecom(uchar com)  //寫地址,也就是顯示的數據的位置
{
        RS = 0;                
        P0 = com;
        EN = 1;
        delayms(1);
        EN = 0;
}
void writedata(uchar dat) //寫數據,也就是顯示的數據
{
        RS = 1;
        P0 = dat;
        EN = 1;
        delayms(1);
        EN = 0;
}
void init()                   //LCD初始化
{
        RW = 0;
        writecom(0x38);          //16*2顯示,5*7點陣
        writecom(0x0c);
        writecom(0x06);
        writecom(0x01);   //清除LCD的顯示內容
}

void writestring(uchar * str, uchar length)           //寫數據的過度函數。length:長度
{
    uchar i;
    for(i = 0; i < length; i++)
    {
         writedata(str[i]);
     }
}
void delay(uint num)        //延時函數
{
  while( --num );
}

DSinit(void)        //初始化ds1820  
{  
     DS= 1;      //DS復位
     delay(8);    //稍做延時
     DS= 0;      //將DS拉低
     delay(90);   //精確延時 大于 480u
     DS= 1;       //拉高總線
     delay(110);
     DS= 1;

}

uchar read_bit(void)     //讀一位(bit)
{
uchar i;
DS= 0;                      //將DS拉低開始讀時間隙
DS= 1;                         // then return high
for (i=0; i<3; i++);         // 延時15μs
return(DS);                         // 返回 DS線上的電平值
}

uchar readbyte()        // 讀一個字節  
{
uchar i = 0;
uchar dat = 0;
for (i=0;i<8;i++)
{                                  // 讀取字節,每次讀取一個字節
if(read_bit()) dat|=0x01<<i;           // 然后將其左移
    delay(4);
  }
    return (dat);
}

void write_bit(char bitval)       //寫一位  
{
DS= 0;                                        // 將DS拉低開始寫時間隙
if(bitval==1) DS=1;          // 如果寫1,DS返回高電平
delay(5);                                       // 在時間隙內保持電平值,
DS= 1;                      // delay函數每次循環延時16μs,因此delay(5) = 104μs
}       

void writebyte(uchar dat)  //寫一個字節
{
  uchar i = 0;
  uchar temp;
   for (i=0; i<8; i++)         // 寫入字節, 每次寫入一位
   {

   temp = dat>>i;                
   temp &= 0x01;                
   write_bit(temp);

  }
  delay(5);
}         
void sendchangecmd()           //DS18B20?開始獲取溫度并轉換
{
    DSinit();                         //DS18B20復位
    delayms(1);                      
    writebyte(0xcc);           //寫跳過讀ROM指令
    writebyte(0x44);           //寫溫度轉換指令
}

void sendreadcmd()                   //讀取寄存器中存儲的溫度數據
{
    DSinit();                           //DS18B20復位
    delayms(1);
    writebyte(0xcc);            //寫跳過讀ROM指令
    writebyte(0xbe);            //讀取暫存器的內容
}         

int gettmpvalue()
{
    uint tmpvalue;
    float t;
    uchar low, high;
    sendreadcmd();                   //讀取寄存器中存儲的溫度數據
    low = readbyte();            //讀取低八位
    high = readbyte();           //讀取高八位
    tmpvalue = high;
    tmpvalue <<= 8;                   //高八位左移八位
    tmpvalue |= low;       //兩個字節組合為1個字
    t = tmpvalue * 0.0625 * 100;   //分辨率為0.0625,在此將值擴大100倍
    return t;
}

void display(int v)            //顯示子函數
{
    uchar i;
    uchar datas[] = {0, 0, 0, 0, 0, 0, 0, 0};  //定義緩存數組datas
    uint tmp = abs(v);                                                   //abs是求絕對值函數
    datas[0] = tmp % 10000 / 1000;
    datas[1] = tmp % 1000 / 100;
    datas[2] = tmp % 100 / 10;
    datas[3] = tmp % 10;
        datas[4] = 80;                                                //空格的前30的ASCALL碼
        datas[5] = 175;                                                //溫度符號的前30的ASCALL碼
        datas[6] = 19;                                                //C的前30的ASCALL碼
    writecom(0xc0+3);
    if(v < 0)                                  //當V小于0則輸出負號
    {
        writestring("- ", 2);
   }
    else
    {
       writestring("+ ", 2);          //當V大于0則輸出正號
    }
    for(i = 0; i != 7; i++)
    {
        writedata('0'+datas[i]);   //顯示溫度
        if(i == 1)
        {
           writedata('.');                  //顯示溫度的小數點
        }
    }

}

void Read_RomCord()                   //讀取64位序列碼
{
     unsigned char j;
     DSinit();
     writebyte(0x33);      // 讀序列碼的操作
     for (j = 0; j < 8; j++)
         {
          table4[j] = readbyte();
         }
}

void Disp_RomCode()                           //數據轉換與顯示
{
   uchar j,i;
   writecom(0xc0);         //LCD第二行初始位置
   for(j=0;j<8;j++)
   {
    i=((table4[j]&0xf0)>>4);
    if(i>9)
     { i=i+0x37;}
    else{i=i+0x30;}         
    writedata(i);        //高位數顯示
    i=(table4[j]&0x0f);
    if(i>9)
     {i=i+0x37;}
    else {i=i+0x30;}         
    writedata(i);        //低位數顯示
   }
}

void lcd_display()                 //按鍵掃描
{
  uchar i,m;
  uchar hl[]={0, 0, 0, 0, 0};
  if(k1 == 0) k = 1;
  if(k2 == 0) k = 2;                                                                                                                                                                                          
  if(k3 == 0) k = 3;
  if(tempHL[0]<=gettmpvalue()/100)
       delayms(100),LS=!LS,H=~H;
  else
       LS=1,H=1;
  if(m==1)
{
          if(tempHL[1]>=gettmpvalue()/100)
               delayms(100),LS=!LS,L=~L;
          else
               LS=1,L=1;
  }
  switch(k)
  {
        case 1:                                                       //顯示64位的ROM
                   writecom(0x01);
                   writecom(0x80);
                   writestring(table1, 16);
                   Read_RomCord();           //讀取64位序列碼
                   Disp_RomCode();                 //顯示64位序列
           delayms(500);                         //溫度轉換時間需要750ms以上
                   break;
        case 2:                                                 //顯示當前溫度
                   delayms(750);                         //溫度轉換時間需要750ms以上
                   sendchangecmd();
                   writecom(0x01);
                   writecom(0x80);
                   writestring(table0, 16);
                   display(gettmpvalue());
                   break;
        case 3:                                                     //顯示溫度上限及下線,并支持調節
                   writecom(0x80);
                   writestring(table2, 16);
                   writecom(0xC0);
                   writestring(table3, 16);
                   if(k4==0) {tempHL[0]++;if(m==1) tempHL[1]++;if(m==0){tempHL[1]--;if(tempHL[1]==0)m=1;}delayms(100);}
                   if(k5==0) {tempHL[0]--;if(m==0) tempHL[1]++;if(m==1){tempHL[1]--;if(tempHL[1]==0)m=0;}delayms(100);}
                   hl[0] = tempHL[0] / 10;
                   hl[1] = tempHL[0] % 10;
                   if(m==1) hl[2] = 80;
                   if(m==0) hl[2] = 128;
                   hl[3] = tempHL[1] / 10;
                   hl[4] = tempHL[1] % 10;
                   writecom(0xC0+4);
                   for(i = 0; i != 2; i++)
                    {
                        writedata('0'+hl[i]);        //顯示上限溫度
                         }
                   writecom(0xC0+11);
                   for(i = 2; i != 5; i++)
                    {
                        writedata('0'+hl[i]);         //顯示下限溫度
                         }
                   break;
  }
}
void main()
{
        sendchangecmd();                        //讀取寄存器中存儲的溫度數據
    init();                                                //LCD初始化
    writecom(0x80);                                //選擇LCD第一行
    writestring(table0, 16);        //顯示當前溫度的英文字母
    while(1)
    {
        lcd_display();                         //掃描按鍵
    }
}


評分

參與人數 2黑幣 +60 收起 理由
send + 10 贊一個!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1 發表于 2016-3-27 19:44 | 只看該作者
樓主能分享個電路圖嗎?
回復

使用道具 舉報

板凳
ID:121641 發表于 2016-5-24 22:33 | 只看該作者
樓主棒!我已經仿真好了,坐等焊板子
回復

使用道具 舉報

地板
ID:97714 發表于 2016-5-28 09:33 | 只看該作者
感謝樓主,正需要這類資料
回復

使用道具 舉報

5#
ID:125111 發表于 2016-6-4 20:32 | 只看該作者
分地區二姐夫脾氣額閥門哦我去
回復

使用道具 舉報

6#
ID:184584 發表于 2017-4-19 19:48 | 只看該作者
能不能把仿真電路圖發一下??
回復

使用道具 舉報

7#
ID:184584 發表于 2017-4-19 19:48 | 只看該作者
能不能把仿真電路圖發一下??
回復

使用道具 舉報

8#
ID:170098 發表于 2017-5-16 15:27 | 只看該作者
我覺得還是發個圖,這樣學習起來也比較快
回復

使用道具 舉報

9#
ID:830316 發表于 2020-11-6 18:54 | 只看該作者
15966025623 發表于 2016-5-28 09:33
感謝樓主,正需要這類資料

求分享一下。謝謝
回復

使用道具 舉報

10#
ID:312000 發表于 2020-12-1 10:25 | 只看該作者
有沒有原理圖
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩在线一区二区 | 91精品久久久久久久久中文字幕 | 精品国产视频在线观看 | 欧美日韩网站 | 午夜a级理论片915影院 | 99久久中文字幕三级久久日本 | 日韩免费毛片视频 | 精品国产乱码久久久久久图片 | 网址黄 | 日本高清在线一区 | 黄色国产大片 | 亚洲精品久久久久久久久久久久久 | 午夜视频一区二区 | 新91视频网| 精精国产xxxx视频在线播放 | 精品乱子伦一区二区三区 | 一区二区三区中文字幕 | 国产成人99av超碰超爽 | 国产特级毛片 | 国产视频二区 | 亚洲+变态+欧美+另类+精品 | 精品视频在线观看 | 欧美a区 | 久草网站| 国产玖玖| 久久久精品国产 | 午夜看看 | 一区二区三区国产在线观看 | 中文字幕一区二区三区日韩精品 | 久久在线看 | a级片在线观看 | 精品国产第一区二区三区 | 国产欧美日韩在线 | 一区二区三区影院 | 日韩视频一区二区 | v亚洲| 国产日韩电影 | 午夜在线视频 | 日本一区二区三区免费观看 | 亚洲精品九九 | 在线观看国产 |