?? clock.c
字號:
//聲明:在“蘋果”兄的程序的基礎上增加溫度控制功能2005/6/6
//更新歷史:
// 增加溫度顯示,調整時閃動。12/1
// 增加零下溫度顯示 12/15
/*============================================================
使用1602液晶顯示DS1302+S51時鐘+溫度顯示 馬文壘 2004/12/01
==============================================================
聲明:1. 1602驅動程序照搬 明皓 的,非常好用
2. DS1302驅動程序是參考網友修改而來
SMC1602A(16*2)模擬口線接線方式
連接線圖:
---------------------------------------------------
|LCM-----51 | LCM-----51 | LCM------51 |
---------------------------------------------|
|DB0-----P1.0 | DB4-----P1.4 | RS-------P2.0 |
|DB1-----P1.1 | DB5-----P1.5 | RW-------P2.1 |
|DB2-----P1.2 | DB6-----P1.6 | E--------P2.2 |
|DB3-----P1.3 | DB7-----P1.7 | VLCD接1K電阻到GND|
---------------------------------------------------
DS1302 接線圖
Vcc2 CLK I/O /RST
| | | |
--------------
| 8 7 6 5|
| DS1302 |
| |
| 1 2 3 4|
--------------
| | | |
VCC1 GND
1 腳接+5V 2,3腳32768HZ晶振 4腳接地 5腳接S51的P02 6腳接S51的P01 7接S51的P00
8腳接后備電源,可以接老計算機主板上的3.6V電池,也可以通過二級管隔離接一個大容量電解電容
電壓在2.5V以上即可維持
按鍵說明:1. 共三個鍵,低電平有效
2. P04 和 P05 同時按:初始化
3. P06 端口按鍵:選擇要調整的項目
4. P05 端口按鍵:增加;P04端口按鍵:減少
5. P03 端口按鍵:選擇顯示模式;新增按鍵
[注:AT89S51使用12M晶振]
=============================================================*/
#include <AT89x51.h>
#include <string.h>
#include<intrins.h>
#define LCM_RS P2_0 //定義引腳
#define LCM_RW P2_1
#define LCM_E P2_2
#define LCM_Data P1
#define Busy 0x80 //用于檢測LCM狀態字中的Busy標識
#define uchar unsigned char
uchar id,timecount,dipsmodid;
bit lmcinit_or_not; //是否需要清屏標志位“1”為需要“0”為不需要
bit flag,sflag; //flag是時鐘冒號閃爍標志,sflag是溫度負號顯示標志
void Disp_line1(void); //顯示屏幕第一行
void Disp_line2(void); //顯示屏幕第二行
void id_case1_key();
//void Dispmod_id_case_key(void);//選擇顯示模式
void Disp_mod0(void);//顯示模式0
void Disp_mod1(void);//顯示模式
//*********** DS1302 時間顯示定義部分
sbit T_CLK=P0^0;
sbit T_IO =P0^1;
sbit T_RST=P0^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
void Set(uchar,uchar); //根據選擇調整相應項目
void RTInputByte(uchar); /* 輸入 1Byte */
uchar RTOutputByte(void); /* 輸出 1Byte */
void W1302(uchar, uchar); // 向DS1302寫入一個字節
uchar R1302(uchar); // 從DS1302讀出一個字節
void Set1302(unsigned char * ); // 設置時間
bit sec,min,hour,year,mon,day,weekk; //閃爍標志位
//初始化后設置為:04年12月2日星期4 0點0分0秒
unsigned char inittime[7]={0x00,0x00,0x00,0x02,0x12,0x04,0x04};
// 秒 分鐘 小時 日 月 年 星期
//***** 18B20溫度顯示定義部
sbit DQ=P0^7; //18B20 接P07口
typedef unsigned char byte;
typedef unsigned int word;
Read_Temperature(char,char);
void mychar(void);
byte ow_reset(void);
byte read_byte(void);
void write_byte(char val);
void adjust_res(char res); //res 分別等于 0x1f, 0x3f, 0x5f 溫度讀數分辨率分別對應
// 0.5, 0.25, 0.125
//*******溫度控制部分*********
bit tl_flash_flag; //下限閃爍標志
bit th_flash_flag; //上限閃爍標志
bit tl_flag; //下限越限標志
bit th_flag; //上限越限標志
bit tl_sign,th_sign; //溫度零下標志 0:零上,1:零下
char tempid;
void Disp_Temp(void); //顯示上下限溫度
void Set_TH_Temp(void); //設置溫度上限
void Set_TL_Temp(void); //設置溫度下限
signed char tl=20,th=45;
void Compare_Temp(signed char l,signed char h); //比較溫度
void Tl_Al(void); //下限越限報警
void Th_Al(void); //上限越限報警
//******* 1602LCD驅動 **********************************************************
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
unsigned char code week[]={"Week."};
void main(void)
{
Delay400Ms(); //啟動等待,等LCM講入工作狀態
LCMInit(); //LCM初始化
Delay5Ms(); //延時片刻(可不要)
mychar();
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
TR0=1;
ET0=1;
W1302(0x90,0xa5);//打開充電二級管 一個二級管串聯一個2K電阻
W1302(0x8e,0x80);//寫保護,禁止寫操作
adjust_res(0x1f); //調整18B20的分辨率 0x1f:0.5; 0x3f:0.25; 0x5f:0.125
while(1)
{
if (P0_3==0)
{dipsmodid++;
lmcinit_or_not=1;
if(dipsmodid>2) dipsmodid=0;
while(P0_3==0);
}
switch(dipsmodid)
{
case 0:
Disp_mod0();
break;
case 1:
Disp_mod1();
break;
}
}
}
/*//選擇顯示模?void Dispmod_id_case_key()
{
if (P0_3==0)
{dipsmodid++;
if(dipsmodid>1) dipsmodid=0;
}
}*/
//顯示模式0
void Disp_mod0(void)
{
if(lmcinit_or_not==1)
{LCMInit();
lmcinit_or_not=0;
}
if ((P0_4|P0_5)==0) //初始化
{
Delay5Ms();
if ((P0_4|P0_5)==0) Set1302(inittime);
}
//mychar(); //顯示自定義字符
if (P0_6==0) // 設置和選擇項目鍵
{
Delay5Ms();
if(P0_6==0){id++;if(id>7) id=0;}
while(P0_6==0);
}
switch(id)
{
case 0:
sec=0;
Disp_line1(); Disp_line2();
break;
case 1://年
year=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 2://月
year=0;mon=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 3://日
mon=0;day=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 4://星期
day=0;weekk=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 5://小時
weekk=0;hour=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 6://分鐘
hour=0;min=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 7://秒
min=0;sec=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
}
}
//顯示模式1
void Disp_mod1(void)
{
if(lmcinit_or_not==1)
{LCMInit();
lmcinit_or_not=0;
}
Read_Temperature(1,0);
DisplayOneChar(0,1,'T');
DisplayOneChar(1,1,'L');
DisplayOneChar(2,1,':');
DisplayOneChar(7,1,'T');
DisplayOneChar(8,1,'H');
DisplayOneChar(9,1,':');
if(P0_6==0)
{
if(P0_6==0)
{
tempid++;
if(tempid>2) tempid=0;
while(P0_6==0);
}
}
switch(tempid)
{
case 0:
tl_flash_flag=0;
th_flash_flag=0;
Disp_Temp();
break;
case 1:
tl_flash_flag=1;
th_flash_flag=0;
Disp_Temp();
Set_TL_Temp();
break;
case 2:
tl_flash_flag=0;
th_flash_flag=1;
Disp_Temp();
Set_TH_Temp();
break;
}
Compare_Temp(tl,th);
Tl_Al();
Th_Al();
}
//顯示上下限溫度
void Disp_Temp(void)
{
unsigned char tl_gw,tl_sw,tl_bw; //下限溫度的個位,十位,百位
unsigned char th_gw,th_sw,th_bw; //上限溫度的個位,十位,百位
tl_sign=tl>>7;
if(tl_sign)
{
tl_bw=(~(tl-1))/100; //計算百位
tl_sw=((~(tl-1))-tl_bw*100)/10; //計算十位
tl_gw=(~(tl-1))-tl_bw*100-tl_sw*10; //計算個位
}
else
{
tl_bw=(tl)/100;
tl_sw=(tl-tl_bw*100)/10;
tl_gw=tl-tl_bw*100-tl_sw*10;
}
if(tl_flash_flag==1)
{
if(flag==1)
{if(tl_sign)
{
DisplayOneChar(3,1,0x2d);
DisplayOneChar(4,1,tl_sw+0x30);
DisplayOneChar(5,1,tl_gw+0x30);
}
else
{
DisplayOneChar(3,1,tl_bw+0x30);
DisplayOneChar(4,1,tl_sw+0x30); //顯示下限溫度
DisplayOneChar(5,1,tl_gw+0x30);
}
}
else
{DisplayOneChar(3,1,0x20);
DisplayOneChar(4,1,0x20); //顯示下限溫度
DisplayOneChar(5,1,0x20);
}
}
else
{
DisplayOneChar(3,1,tl_bw+0x30);
DisplayOneChar(4,1,tl_sw+0x30); //顯示下限溫度
DisplayOneChar(5,1,tl_gw+0x30);
}
th_sign=th>>7;
if(th_sign)
{
th_bw=(~(th-1))/100; //計算百位
th_sw=((~(th-1))-th_bw*100)/10; //計算十位
th_gw=(~(th-1))-th_bw*100-th_sw*10; //計算個位
}
else
{
th_bw=(th)/100;
th_sw=(th-th_bw*100)/10;
th_gw=th-th_bw*100-th_sw*10;
}
if(th_flash_flag==1)
{
if(flag==1)
{if(th_sign)
{
DisplayOneChar(10,1,0x2d);
DisplayOneChar(11,1,th_sw+0x30); //顯示下限溫度
DisplayOneChar(12,1,th_gw+0x30);
}
else
{
DisplayOneChar(10,1,th_bw+0x30);
DisplayOneChar(11,1,th_sw+0x30); //顯示下限溫度
DisplayOneChar(12,1,th_gw+0x30);
}
}
else
{
DisplayOneChar(10,1,0x20);
DisplayOneChar(11,1,0x20); //顯示下限溫度
DisplayOneChar(12,1,0x20);
}
}
else
{
DisplayOneChar(10,1,th_bw+0x30);
DisplayOneChar(11,1,th_sw+0x30); //顯示下限溫度
DisplayOneChar(12,1,th_gw+0x30);
}
}
//設置溫度下限
void Set_TL_Temp(void)
{
if(P0_5==0)
{
Delay5Ms();
if(P0_5==0)
{
tl++;
if(tl>125) tl=-55;
//if(tl<-55) tl=155;
}
while(P0_5==0);
}
if(P0_4==0)
{
Delay5Ms();
if(P0_4==0)
{
tl--;
if(tl<-55) tl=125;
}
}
}
//設置溫度上限
void Set_TH_Temp(void)
{
if(P0_5==0)
{
Delay5Ms();
if(P0_5==0)
{
th++;
if(th>125) th=-55;
//if(tl<-55) tl=155;
}
while(P0_5==0);
}
if(P0_4==0)
{
Delay5Ms();
if(P0_4==0)
{
th--;
if(th<-55) th=125;
}
}
}
void Compare_Temp(signed char l,signed char h) //比較溫度
{
unsigned char tl_temp;
unsigned char y,s;
//unsigned int x;
//unsigned char ct[8];
union{byte c[2]; int x;}temp;
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 轉換溫度
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0xbe); // 讀取寄存器
temp.c[1]=read_byte();//讀出溫度低8位
temp.c[0]=read_byte();//讀出溫度高8位
// 零下溫度判斷
sflag=0; //溫度零下標志 0:零上,1:零下
if((temp.c[0]&0xf8)!=0x00)
{
sflag=1; //零下標志位置1
temp.c[1]=~temp.c[1]; //低8位取反
temp.c[0]=~temp.c[0]; //高8位取反
tl_temp=temp.c[1]+1; //低8位加1
temp.c[1]=tl_temp; //計算后重新存入數組
if(tl_temp>255) temp.c[0]++; //如果低8位大于255,向高8位進1
}
y=0;
s=0;
y=temp.c[0]<<4;
s=temp.c[1]>>4;
y=s|y;
//x=((temp.c[0]&0x07)*256+temp.c[1])*.625;
if(y<l)
tl_flag=1;
else
tl_flag=0;
if(y>h)
th_flag=1;
else
th_flag=0;
}
void Tl_Al(void) //下限越限報?{
if(tl_flag==1)
{
if(flag==1)
{
DisplayOneChar(9,0,'A');
DisplayOneChar(10,0,'L');
}
else
{
DisplayOneChar(9,0,0x20);
DisplayOneChar(10,0,0x20);
}
}
else
{
DisplayOneChar(9,0,0x20);
DisplayOneChar(10,0,0x20);
}
}
void Th_Al(void) //上限越限報警
{
if(th_flag==1)
{
if(flag==1)
{
DisplayOneChar(13,0,'A');
DisplayOneChar(14,0,'H');
}
else
{
DisplayOneChar(13,0,0x20);
DisplayOneChar(14,0,0x20);
}
}
else
{
DisplayOneChar(13,0,0x20);
DisplayOneChar(14,0,0x20);
}
}
//中斷入口,冒號閃爍
void t0(void) interrupt 1 using 0
{
TH0=(65535-50000)/256; //50ms定時
TL0=(65535-50000)%256;
timecount++;
if(timecount>9)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -