|
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
/*------------LCD12864相關聲明-----------------------------*/
#define com 0
#define dat 1
sbit cs =P1^0;
sbit sid=P1^1;
sbit sck=P1^2;
uchar code TAB1[]={"電字鐘Q154938862"};//第一行初始化
uchar code TAB2[]={"20 年 月 日"}; //第二行
uchar code TAB3[]={"星期 : : "}; //第三行
uchar code TAB4[]={"室溫: ℃"}; //第四行
/*----------------------DS1302相關聲明-------------------------*/
char TAB_1302[]={ 0x00,0x29,0x02, //秒:分:時
0x18,0x06,0x06,0x08}; //日:月:星期:年
uchar code TAB_XQ[]={"一二三四五六日"};//把DS1302數字日期轉換為中文字符
sbit T_CLK=P2^2; /* 實時時鐘的時鐘線引腳*/
sbit T_IO=P2^1; /* 實時時鐘的數據線*/
sbit T_RST=P2^0; /* 實時時鐘的復位線引腳*/
uchar bdata datbyte;
sbit datbyte0=datbyte^0;
sbit datbyte7=datbyte^7;
/*--------------18B20相關聲明-------------------------------*/
uchar dis1[16];
sbit DQ=P1^0; /*DS18B20溫度檢測*/
/*----------鍵盤相關聲明-------------------------------------*/
sbit key=P0^0; //功能鍵
sbit key1=P0^1; //只有加1鍵
uchar sum,keyflag=0; //調用時,分,秒,標志,調用鍵盤處理標志.
/*--------------以下為LCD12864相關函數--------------------------*/
/**************************************************************
函數名稱:void delay1ms(uint x)
函數功能: 延時1MS
***************************************************************/
void delay1ms(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
/**************************************************************
函數名稱:void w_12864byte(uchar byte)
函數功能: 寫字節
*************************************************************/
void w_12864byte(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
sck=0;
byte<<=1;
sid=CY;
sck=1;
}
}
/**************************************************************
函數名稱:uchar r_12864byte(void)
函數功能: 讀字節
***************************************************************/
uchar r_12864byte(void)
{
uchar i,temp1,temp2;
temp1 = 0;
temp2 = 0;
for(i=0;i<8;i++)
{
temp1=temp1<<1;
sck = 0;
sck = 1;
sck = 0;
if(sid) temp1++;
}
for(i=0;i<8;i++)
{
temp2=temp2<<1;
sck = 0;
sck = 1;
sck = 0;
if(sid) temp2++;
}
return ((0xf0&temp1)+(0x0f&temp2));
}
/**************************************************************
函數名稱:void c_12864busy( void )
函數功能: 檢測忙函數
**************************************************************/
void c_12864busy( void )
{
do
w_12864byte(0xfc); //11111,RW(1),RS(0),0
while(0x80&r_12864byte());
}
/**************************************************************
函數名稱:void w_12864(bit dat_com,uchar byt)
函數功能: 寫入函數
***************************************************************/
void w_12864(bit dat_com,uchar byt)
{
uchar temp;
if(dat_com==0) //為零,寫入指令
temp=0xf8; //11111,RS(0),RW(0),0
else //否則,寫入數據
temp=0xfa; //11111,RS(1),RW(0),0
cs=1;
c_12864busy();
w_12864byte(temp);
w_12864byte(byt&0xf0); //寫入高四位
w_12864byte(byt<<4); //寫入低四位
cs=0;
}
/**************************************************************
函數名稱:void init_12864(void)
函數功能:初始化12864
***************************************************************/
void init_12864(void)
{
w_12864(com,0x30); //基本指令功能.
w_12864(com,0x0c); //顯示打開,關光標,反白關.
w_12864(com,0x01); //清屏指令.
w_12864(com,0x06); //AC自動加一
}
/*----------------以下為DS1302相關函數-------------------------*/
/**************************************************************
函數名稱:void w_1302byte(uchar date)
函數功能:寫一個字節(上升沿)
***************************************************************/
void w_1302byte(uchar date)
{ uchar i;
datbyte=date;
for(i=0;i<8;i++)
{ T_IO=datbyte0; //寫最低位
T_CLK=0;
T_CLK=1;
datbyte>>=1;
}
}
/************************************************************** 函數名稱:uchar r_1302byte(void) 函數功能:讀一個字節(下降沿) ***************************************************************/
uchar r_1302byte(void)
{ uchar i;
datbyte=0;
for(i=0;i<8;i++)
{ datbyte7=T_IO; //讀最低位
T_CLK=1;
T_CLK=0;
datbyte>>=1;
}
return(datbyte);
}
/*************************************************************** 函數名稱:void write_1302(uchar addr,uchar date) 函數功能: 指定位置寫數據 ****************************************************************/
void write_1302(uchar addr,uchar date)
{ T_RST=0;
T_CLK=0;
T_RST=1;
w_1302byte(addr);
w_1302byte(date);
T_CLK=0;
T_RST=0;
}
/**************************************************************函數名稱:uchar read_1302(uchar addr) 函數功能: 指定位置讀數據 ****************************************************************/
uchar read_1302(uchar addr)
{ uchar dat1,dat2,temp;
T_RST=0;
T_CLK=0;
T_RST=1;
w_1302byte(addr);
temp=r_1302byte();
T_RST=0;
T_CLK=0;
dat1=temp/16;
dat2=temp%16;
temp=dat1*10+dat2;
return(temp);
}
/*************************************************************** 函數名稱:void init_1302(void) 函數功能: 初始化 *****************************************************************/
void init_1302(void)
{ uchar i;
uchar addr=0x80;
write_1302(0x8e,0x00);
for(i=0;i<7;i++)
{
write_1302(addr,TAB_1302[i]);
addr+=2;
}
write_1302(0x8e,0x80);
}
/**************************************************************** 函數名稱:void get_1302(void) 功能說明:讀取DS1302時鐘信息.*****************************************************************/
void get_1302(void)
{ uchar i,addr=0x81;
for(i=0;i<7;i++)
{ TAB_1302[i]=read_1302(addr);
addr+=2;
}
}
/*---------------以下為18B20相關函數-----------------------------*/
/****************************************************************** 函數名稱:void delay (uint x) 功能說明:若機器周期為1us,則本延時程序為延時 4*x(us) ******************************************************************/
void delay (uint x) //本板延時8us
{
while (--x);
}
/***************************************************************** 函數名稱:uchar bus_rest(void) 功能說明:產生單總線系統信號的總線復位信號,并返回 總線上是否存在單總線器件信息 ******************************************************************/
uchar bus_rest(void)
{ uchar presence;
DQ=0; //將DQ信號線拉低
delay(29); //持續48US
DQ=1; //釋放總線
delay(3); //等待從設備將總線拉低
presence=DQ; //保存當前總線狀態
delay(25); //等待總線初始化過程結束
return presence;//返回是否有從設備將總線拉低
}
/**************************************************************** 函數名稱:uchar r_1820BYTE(void) 功能說明:向單總線讀取一個數據字節 *****************************************************************/
uchar r_1820BYTE(void)
{ uchar i=0;
uchar date = 0;
for (i=8;i>0;i--)
{ DQ = 0; // 將DQ信號線拉低啟動讀時隙
DQ=1;// 釋放總線,等待從機動車輛返回數據位
delay(1); //越接近15us越好; 準備采樣總線上的信號
date>>=1;
if (DQ)
date=date|0x80;
delay(6);
}
return(date);
}
/***************************************************************** 函數名稱:void w_1280Byte(uchar bytevalue) 功能說明:向單總線寫一個數據字節 ******************************************************************/
void w_1280Byte(uchar bytevalue)
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0; // 將DQ信號線拉低啟動讀時隙
DQ=bytevalue&0x01; //
delay(5);//等待寫時隙結束
DQ=1; //釋放
bytevalue>>=1;
}
delay(5); //等待寫時隙結束
}
/***************************************************************** 函數名稱:uint read_T(void) 功能說明:讀取1820溫度 *******************************************************************/
uint read_T(void)
{ uchar a=0;
uchar b=0;
uint t=0;
bus_rest();
w_1280Byte(0xCC); // 跳過讀序號列號的操作 ;
w_1280Byte(0x44); // 啟動溫度轉換,模數轉化;
bus_rest();
w_1280Byte(0xCC); //跳過讀序號列號的操作 ;
w_1280Byte(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度 ;
a=r_1820BYTE();// 低8位
b=r_1820BYTE();// 高8位
t=(b*256)+a;
return(t);
}
/************************************************************** 函數名稱:void show_T(uint temp) 函數功能:顯示溫度 **************************************************************/
void show_T(uint temp)
{ int i;
float ftemp;
ftemp = temp* 0.0625;
sprintf(dis1,"%f",ftemp);//把溫度值寫入數組內存
w_12864(com,0x98+3);
for(i=0;i<5;i++)
w_12864(dat,dis1[i]); //寫入溫度
}
/*---------------以下為顯示相關函數--------------------------*/
/****************************** 函數名稱: void fenli(uchar x,uchar y,uchar val) 功能描述: 指定位置寫入數據 ********************************/
void fenli(uchar x,uchar y,uchar val)
{ uchar ge,shi,addr,i=0;
if(val==5)//這里把星期數字顯示的轉換為中文
{
w_12864(com,0x88+2);
for(i=0;i<2;i++)
{ //一個漢字寫兩次
if(TAB_1302[5]==0)w_12864(dat,TAB_XQ[i]);
if(TAB_1302[5]==1)w_12864(dat,TAB_XQ[2+i]); //
if(TAB_1302[5]==2)w_12864(dat,TAB_XQ[3+i]); //!!??星期三顯示沒規律,不知咋回事.
if(TAB_1302[5]==3)w_12864(dat,TAB_XQ[5+i]);
if(TAB_1302[5]==4)w_12864(dat,TAB_XQ[7+i]);
if(TAB_1302[5]==5)w_12864(dat,TAB_XQ[9+i]);
if(TAB_1302[5]==6)w_12864(dat,TAB_XQ[11+i]);
}
}
else {
shi=TAB_1302[val]/10;//分離十位
ge=TAB_1302[val]%10;
if(x==1)x=0x80;
if(x==2)x=0x90;
if(x==3)x=0x88;
if(x==4)x=0x98;
addr=x+y;
w_12864(com,addr);//指定位置
w_12864(dat,0x30+shi);//寫入
w_12864(dat,0x30+ge);
}
}
/************************************************************* 函數名稱:void display(void) 功能描述: 顯示函數 **************************************************************/
void display(void)
{
//uchar month,year,day;
get_1302(); //讀1302
fenli(3,7,0); //讀秒
fenli(3,5,1); //讀分
fenli(3,3,2); //讀時
fenli(2,5,3); //讀日
fenli(2,3,4); //讀月
fenli(3,2,5); //讀星期
fenli(2,1,6); //讀年
//month=fenli(2,3,4);
//year=fenli(2,1,6);
//day=fenli(2,5,3);
//conversion(year,month,day);
}
/*---------------按鍵處理相關函數--------------------------*/
/************************************************************ 函數名稱:void scanner() 功能描述: 按鍵函數 *************************************************************/
void scanner()
{ uchar i,j;
if(!key) //功能鍵按下
{ delay1ms(500); //延時500MS
if(!key) //還按下,退出時間調整
{ keyflag=0; //標志位為0
sum=0; //清0
w_12864(com,0x0c);//清閃爍
for(i=0;i<7;i++)//十進制轉十六進制
{ j=TAB_1302[i]/10;
TAB_1302[i]=TAB_1302[i]%10;
TAB_1302[i]=TAB_1302[i]+16*j;
}
init_1302(); //寫入1302
while(!key); //等待釋放
delay1ms(10); //延時消抖
}
else //500MS內放開
{ keyflag=1; //標志為1,進行時間調整
sum++; //功能鍵加1
if(sum==8)
sum=0;
switch(sum)
{ case 1: //
{ w_12864(com,0x98+7);
w_12864(com,0x0f);
break;
}
case 2: //為2,年閃爍
w_12864(com,0x90+1);
break;
case 3: //月閃爍
w_12864(com,0x90+3);
break;
case 4: //日閃爍
w_12864(com,0x90+5);
break;
case 5: //星期閃爍
w_12864(com,0x88+2);
break;
case 6: //分閃爍
w_12864(com,0x88+5);
break;
case 7: //時閃爍
w_12864(com,0x88+3);
break;
}
}
}
if(sum) //功能鍵按下
{
if(!key1)
{ delay1ms(10);
if(!key1)
{ while(!key1);//等待加1鍵釋放
delay1ms(10);
if(sum==1)
{ //備用 }
if(sum==2)
{ TAB_1302[6]++;
if(TAB_1302[6]==100)
TAB_1302[6]=0;
fenli(2,1,6);
w_12864(com,0x90+1);//閃爍歸位
}
if(sum==3)
{ TAB_1302[4]++;
if(TAB_1302[4]==13)
TAB_1302[4]=1;
fenli(2,3,4);
w_12864(com,0x90+3);
}
if(sum==4)
{TAB_1302[3]++;
if(TAB_1302[3]==32)
TAB_1302[3]=1;
fenli(2,5,3);
w_12864(com,0x90+5);
}
if(sum==5)
{TAB_1302[5]++;
if(TAB_1302[5]==7)
TAB_1302[5]=0;
fenli(3,2,5);
w_12864(com,0x88+2);
}
if(sum==6)
{ TAB_1302[1]++;
if(TAB_1302[1]==60)
TAB_1302[1]=0;
fenli(3,5,1);
w_12864(com,0x88+5);
}
if(sum==7)
{TAB_1302[2]++;
if(TAB_1302[2]==24)
TAB_1302[2]=0;
fenli(3,3,2);
w_12864(com,0x88+3);
}
}
}
}
}
}
//=============================================================
void init(void)
{
uchar i;
init_12864();
init_1302();
while(TAB1[i]!='\0')
{
w_12864(dat,TAB1[i]);
i++;
}
i=0;
w_12864(com,0x90);
while(TAB2[i]!='\0')
{
w_12864(dat,TAB2[i]);
i++;
}
i=0;
w_12864(com,0x88);
while(TAB3[i]!='\0')
{
w_12864(dat,TAB3[i]);
i++;
}
i=0;
w_12864(com,0x98);
while(TAB4[i]!='\0')
{
w_12864(dat,TAB4[i]);
i++;
}
}
/************************************************************* 函數名稱:主函數 函數功能: **************************************************************/
void main()
{
init();
while(1)
{
scanner(); //檢測鍵盤
if(!keyflag) //標志為0
{ display(); //調用顯示
show_T(read_T()); //顯示溫度
delay1ms(500);
}
}
}
|
|