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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機時鐘溫度計小制作

  [復制鏈接]
跳轉到指定樓層
樓主
ID:83710 發表于 2015-6-24 22:14 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
     最近利用DS1302與DS18B20做了一個能顯示當前時間、日期、溫度的東西。有三個按鍵,正常運行時顯示當前的時間,利用按鍵2、3可以切換到日期與溫度。按下按鍵1進入設置時間狀態,在設置時間狀態利用按鍵2、3可調整時間與日期。調整好后不進行任何操作6秒退出設置狀態。
實物圖:
顯示當前時間:(11時:24分:47秒)


顯示當前日期:(09年:01月:15日)

顯示當前溫度:(17.2度)


源程序:
#include <reg51.h>
#include<intrins.h>
sbit dq = P0^0;//定義P0.0為DS18B20的數據線
sbit t_rst=P0^2;//DS1302數據線
sbit t_clk=P0^4;
sbit t_io=P0^3;
sbit P2_0=P2^0;//按鍵
sbit P2_1=P2^1;
sbit P2_2=P2^2;
sbit P3_0=P3^0;//顯示
sbit P3_1=P3^1;
sbit P3_2=P3^2;
sbit P3_3=P3^3;
sbit P3_4=P3^4;
sbit P3_5=P3^5;
sbit P3_6=P3^6;
sbit P3_7=P3^7;
void delay(unsigned char i);//定義延時函數
bit init_18b20();//定義DS18B20初始化復位函數
void w_18b20(unsigned char dat);//定義寫DS18B20函數
unsigned char r_18b20();//定義讀DS18B20函數
void GetTem(void);//定義獲得溫度函數
void Temdisp(void);//溫度顯示函數
void in_1302(unsigned char tdat);//定義寫一個字節到DS1302函數
unsigned char out_1302(void);//定義從DS1302讀一個字節函數
void w_1302(unsigned char ucAddr, unsigned char ucDa);//定義寫DS1302函數
void set1302(void);//設置時間
void get1302(void);//讀取時間
void timedisp(void);//時間顯示函數
void datedisp(void);//日期顯示函數
void setbom(void);
unsigned char TemL;//溫度低位
unsigned char TemH;//溫度高位
unsigned char Tem1;//轉換后溫度個位
unsigned char Tem2;//轉換后溫度十位
unsigned char Led[4];
unsigned char dis[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//不帶點的0~9
unsigned char dis1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//帶點的0~9
bit TempS;//溫度符號位
unsigned int ms;
unsigned char time[7]={0x00,0x24,0x11,0x15,0x01,0x04,0x09};

main()
{
set1302();
while(1)
{
  if(!P2_1){get1302();datedisp();}
  if(!P2_2){GetTem();Temdisp();}
  if(P2_1 && P2_2){ get1302();timedisp();}
  
  if(!P2_0)
  {
   TMOD=0x01; EA=1;ET0=1;TH0=0xFC;TL0=0x66;
   while(!P2_0);delay(255);delay(255);delay(255);
   setbom();
  }
}
}
void delay (unsigned char i) //延時程序,12M晶振下延時為:(2i+3)us ,i=0~255
{
while (--i);
}
bit init_18b20() //初始化,init_18b20=0初始化成功,init_18b20=1初始化失敗,可能18b20不存在
{
bit SS;
dq=1;
_nop_();
dq=0;
delay(255);
dq=1;
delay(34);
SS=dq;
delay(120);
return (SS);
}
void w_18b20(unsigned char dat) //寫一個字節到18b20
{
unsigned char i=0;
for(i=8;i>0;i--)
{
  dq=0;
  delay(5);
  dq=dat&0x01;
  delay(22);//延時
  dq=1;
  dat>>=1;
}
}
unsigned char r_18b20()//從18b20讀一個字節
{
unsigned char i=0;
unsigned char dat=0;
for(i=8;i>0;i--)
{
  dq=0;
  dat>>=1;
  dq=1;
  delay(6);
  if(dq) dat|=0x80;
  delay(22);
}
return(dat);
}

void GetTem() //獲得溫度函數
{
bit SS;
unsigned char A;
unsigned long Tem;//溫度變量
unsigned char TemLH;//低位溫度高位
unsigned char TemLL;//低位溫度低位
do SS=init_18b20();while(SS);//初始化DS18B20,檢測是否存在,存在繼續
w_18b20(0xCC);//跳過ROM匹配
w_18b20(0x44);//開始溫度轉換
do//等待溫度轉換完成
{
dq=0;
_nop_();
_nop_();
_nop_();
dq=1;
delay(6);
SS=dq;
delay(22);
Temdisp();
}
while (!SS);//溫度轉換完成后繼續

init_18b20();//復位
w_18b20(0xCC);//跳過ROM匹配
w_18b20(0xBE);//讀取溫度值
TemL=r_18b20();//低位
TemH=r_18b20();//高位
if (TemH&0x80)//把讀取的溫度值進行轉換,并存進Led[]中
{
  TemH=~TemH;
  TemL=(~TemL)+1;
  TempS=1;
  Led[0]=0x40;//顯示負號
}
else TempS=0;

TemLH=TemL>>4;
TemLL=TemL&0x0F;
Tem=(TemH*16 + TemLH + TemLL*0.0625)*10000;
A=Tem/100000;
Led[1]=dis[A];
Tem=Tem%100000;
A=Tem/10000;
Led[2]=dis1[A];
Tem=Tem%10000;
A=Tem/1000;
Led[3]=dis[A];
}
void Temdisp()//溫度顯示函數,符號位(為負號顯示),十位(為0不顯示,個位(帶小數點),小數位
{
if (TempS==1)//溫度為負則顯示負號,否則不顯示
{
  if (Led[1]!=0x3f)
  {
   P1=Led[0];
   P3_5=0;
   delay(255);
   P3_5=1;
  }
  else
  {
   P1=Led[0];
   P3_4=0;
   delay(255);
   P3_4=1;
  }
}
if (Led[1]!=0x3f)//十位不為零則顯示,否則不顯示
{
  P1=Led[1];
  P3_4=0;
  delay(255);
  P3_4=1;
}
P1=Led[2];//個位
P3_3=0;
delay(255);
P3_3=1;
P1=Led[3];//小數位
P3_2=0;
delay(255);
P3_2=1;
}
void in_1302(unsigned char tdat) //寫一個字節到DS1302
{
unsigned char i;
for(i=8;i>0;i--)
{
  t_io=tdat&0x01;
  _nop_();
  t_clk=1;
  _nop_();
  t_clk=0;
  tdat>>=1;
}
}
unsigned char out_1302(void) //從DS1302讀一個字節
{
unsigned char i;
unsigned char tdat;
for(i=8;i>0;i--)
{
  tdat>>=1;
  if(t_io){tdat=tdat|0x80;}
  t_clk=1;
  _nop_();
  t_clk=0;
}
return(tdat);
}

void w_1302(unsigned char ucAddr, unsigned char ucDa) //往DS1302寫入數據,先寫地址,后寫命令/數據
{
t_rst = 0;
t_clk = 0;
t_rst = 1;
in_1302(ucAddr); /* 地址,命令 */
in_1302(ucDa); /* 寫1Byte數據*/
t_clk = 1;
t_rst =0;
}
unsigned char r_1302(unsigned char ucAddr)//從DS1302讀出數據,先寫地址,后讀命令/數據
{
unsigned char ucDa;
t_rst = 0;
t_clk = 0;
t_rst = 1;
in_1302(ucAddr); /* 地址,命令 */
ucDa = out_1302(); /* 讀1Byte數據 */
t_clk = 1;
t_rst =0;
return(ucDa);
}
void set1302(void)
{
unsigned char i;
unsigned char ucAddr = 0x80;
w_1302(0x8e,0x00); /* 控制命令,WP=0,寫操作?*/
for(i =0;i<7;i++)
{
  w_1302(ucAddr,time[ i]); /* 秒 分 時 日 月 星期 年 */
  ucAddr +=2;
}
w_1302(0x8e,0x80); /* 控制命令,WP=1,寫保護?*/
}
void get1302(void)
{
unsigned char i;
unsigned char ucAddr = 0x81;
for (i=0;i<7;i++)
{
  time = r_1302(ucAddr);/*格式為: 秒 分 時 日 月 星期 年 */
  ucAddr += 2;
}
}
void timedisp(void)
{
unsigned char m;unsigned char n;
m=time[0]>>4;n=time[0]&0x0f;//顯示秒
P1=dis[m];
P3_3=0;
delay(255);delay(255);delay(255);delay(255);
P3_3=1;
P1=dis1[n];
P3_2=0;
delay(255);delay(255);delay(255);delay(255);
P3_2=1;

m=time[1]>>4;n=time[1]&0x0f;//顯示分
P1=dis[m];
P3_5=0;
delay(255);delay(255);delay(255);delay(255);
P3_5=1;
P1=dis1[n];
P3_4=0;
delay(255);delay(255);delay(255);delay(255);
P3_4=1;
m=time[2]>>4;n=time[2]&0x0f;//顯示時
P1=dis[m];
P3_7=0;
delay(255);delay(255);delay(255);delay(255);
P3_7=1;
P1=dis1[n];
P3_6=0;
delay(255);delay(255);delay(255);delay(255);
P3_6=1;
}
void datedisp(void)
{
unsigned char m;unsigned char n;
m=time[3]>>4;n=time[3]&0x0f;//顯示日
P1=dis[m];
P3_3=0;
delay(255);delay(255);delay(255);delay(255);
P3_3=1;
P1=dis1[n];
P3_2=0;
delay(255);delay(255);delay(255);delay(255);
P3_2=1;

m=time[4]>>4;n=time[4]&0x0f;//顯示月
P1=dis[m];
P3_5=0;
delay(255);delay(255);delay(255);delay(255);
P3_5=1;
P1=dis1[n];
P3_4=0;
delay(255);delay(255);delay(255);delay(255);
P3_4=1;
m=time[6]>>4;n=time[6]&0x0f;//顯示年
P1=dis[m];
P3_7=0;
delay(255);delay(255);delay(255);delay(255);
P3_7=1;
P1=dis1[n];
P3_6=0;
delay(255);delay(255);delay(255);delay(255);
P3_6=1;
}
void setbom(void)
{
unsigned char i,m,n;
TR0=1;
while(ms<6000)
{
  if(!P2_0)
  {
   i++;ms=0;
   if(i==5) {i=6;}
   if(i==7) {i=0;}
   while(!P2_0);
   delay(255);delay(255);delay(255);
   ms=0;
  }
  if(!P2_1)
  {
   m=time>>4; n=time&0x0f;
   if(n!=9) n=n+1;
   else{m=m+1;n=0;}
   time=(m<<4)|n;
   while(!P2_1);
   delay(255);delay(255);delay(255);
   ms=0;
  }
  if(!P2_2)
  {
   m=time>>4; n=time&0x0f;
   if(m!=0 && n==0) {n=9;m=m-1;}
   else if(n!=0) {n=n-1;}
   time=(m<<4)|n;
   while(!P2_2);
   delay(255);delay(255);delay(255);
   ms=0;
  }
  
  if (time[0]==0x60)time[0]=0x00;
  if (time[1]==0x60)time[1]=0x00;
  if (time[2]==0x24)time[2]=0x00;
  if (time[3]==0x32)time[3]=0x00;
  if (time[4]==0x13)time[4]=0x00;
  if (time[6]==0x99)time[6]=0x00;
  set1302();
  if(i<3){get1302();timedisp();}
  else {get1302();datedisp();}
}
TR0=0;
ms=0;
}
void time0() interrupt 1 //定時器0中斷
{
TR0=0;
TH0=0xFC;TL0=0x66;
ms++;
TR0=1;
}


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

使用道具 舉報

沙發
ID:62973 發表于 2015-6-25 17:04 | 只看該作者
精度如何;誤差率多少!
回復

使用道具 舉報

板凳
ID:61954 發表于 2015-6-26 07:48 | 只看該作者
晶振多少MHZ?上原理圖啊
回復

使用道具 舉報

地板
ID:19947 發表于 2015-8-21 13:42 | 只看該作者
是個沃,樓主你發下原理圖嗎,我們小輩學習學習!
回復

使用道具 舉報

5#
ID:19947 發表于 2015-9-5 21:29 | 只看該作者
程序中晶振已經提示了,可是,1302需不需要電池供電?
回復

使用道具 舉報

6#
ID:1 發表于 2015-9-6 13:26 來自手機 | 只看該作者
wxgzf 發表于 2015-9-5 21:29
程序中晶振已經提示了,可是,1302需不需要電池供電?

晶振需要電池,不然無法斷電保存時間。
回復

使用道具 舉報

7#
ID:258202 發表于 2017-12-6 15:37 | 只看該作者
大神,厲害了
回復

使用道具 舉報

8#
ID:256736 發表于 2017-12-6 17:36 | 只看該作者
這個不錯啊,能有原理圖就好了,初學者的好制作。
回復

使用道具 舉報

9#
ID:275642 發表于 2018-1-17 18:49 | 只看該作者
我是初學者,也想要原理圖,謝謝!
回復

使用道具 舉報

10#
ID:257136 發表于 2018-2-8 14:07 | 只看該作者
應該弄個時間日期溫度自動輪流顯示的。我剛自己做了個時鐘,想實現時間日期溫度輪流顯示,可是試了好多辦法都不行,還是只能顯示時間。
回復

使用道具 舉報

11#
ID:286600 發表于 2018-3-5 09:52 | 只看該作者
chen19890708 發表于 2018-2-8 14:07
應該弄個時間日期溫度自動輪流顯示的。我剛自己做了個時鐘,想實現時間日期溫度輪流顯示,可是試了好多辦法 ...

這很容易,設一個標志位,0--顯時間,1--顯溫度,在走時程序中隔幾秒取反一次該位。這是我用過的方法。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久99 | 九九天堂网| 中文字字幕在线中文乱码范文 | av久久| 久久这里只有精品首页 | 欧美一级黄色网 | 欧美精品中文 | 97在线超碰| 国产乱码精品1区2区3区 | 在线观看日韩av | 在线观看特色大片免费网站 | 日本高清视频网站 | 一级做a | 伊人一二三 | 免费午夜电影 | 欧美综合一区二区 | 精品免费视频 | a黄在线观看 | 亚洲香蕉在线视频 | 精品一区二区三区四区在线 | 操操日| 久久久久亚洲精品 | 亚洲美女在线一区 | 久久精品色欧美aⅴ一区二区 | 国产精品波多野结衣 | 成人影院在线 | 中文在线播放 | 欧美在线国产精品 | 久久久91精品国产一区二区三区 | 免费观看国产视频在线 | 国产精品中文字幕在线 | 亚洲精品乱码 | 亚洲91 | 午夜三级视频 | 激情毛片 | 亚洲精品二区 | 久久久青草婷婷精品综合日韩 | 色婷婷av一区二区三区软件 | 国产一区二区三区色淫影院 | 国产精品乱码一区二区三区 | 在线观看日本高清二区 |