標(biāo)題: 比較好的電子時(shí)鐘 [打印本頁(yè)]
作者: 瀚海沒(méi)有水 時(shí)間: 2018-1-11 21:21
標(biāo)題: 比較好的電子時(shí)鐘
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
/////////////////
sbit rw = P2^6;//
sbit rs = P2^5;// 1602 IO口位定義
sbit en = P2^7;//
/////////////////
///////////////////
sbit rst = P3^5; //
sbit sclk = P3^6;// 1302 IO口位定義
sbit io = P3^4; //
///////////////////
///////////////////
sbit key1 = P1^0;//
sbit key2 = P1^1;// 獨(dú)立按鍵位定義
sbit key3 = P1^2;//
sbit key4 = P1^3;//
///////////////////
///////////////////
sbit DQ = P2^2;////
///////////////////
uchar tempL=0; //臨時(shí)變量低位
uchar tempH=0; //臨時(shí)變量高位
uint temperature;
uint hour, minute, second, year, month, day;
uint key = 0;
uchar tab_num[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x2d}; //對(duì)應(yīng)字符為: { 0 1 2 3 4 5 6 7 8 9 : - }
uchar tab_time[] = {1,2,10,3,4,10,5,6};
uchar tab_date[] = {2,0,1,0,11,0,9,11,2,7};
// 延時(shí)函數(shù),延時(shí)z毫秒 ******
void delay(uint z)
{
uint x, y;
for(x=0;x<z;x++)
for(y=0;y<110;y++);
}
//***************************
/****************************************************************************
函數(shù)功能:延時(shí)子程序
入口參數(shù):k
出口參數(shù):
****************************************************************************/
void delay18b20(unsigned int k)
{
unsigned int n;
n=0;
while(n < k)
{n++;}
return;
}
/****************************************************************************
函數(shù)功能:DS18B20初始化子程序
入口參數(shù):
出口參數(shù):
****************************************************************************/
Init_DS18B20(void)
{
unsigned char x=0;
DQ=1; //DQ先置高
delay18b20(8); //延時(shí)
DQ=0; //發(fā)送復(fù)位脈沖
delay18b20(85); //延時(shí)(>480ms)
DQ=1; //拉高數(shù)據(jù)線(xiàn)
delay18b20(14); //等待(15~60ms)
}
/****************************************************************************
函數(shù)功能:向DS18B20讀一字節(jié)數(shù)據(jù)
入口參數(shù):
出口參數(shù):dat
****************************************************************************/
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat=0;
for (i=8;i>0;i--)
{
DQ=1;
delay18b20(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay18b20(4);
}
return(dat);
}
/****************************************************************************
函數(shù)功能:向DS18B20寫(xiě)一字節(jié)數(shù)據(jù)
入口參數(shù):dat
出口參數(shù):
****************************************************************************/
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay18b20(5);
DQ=1;
dat>>=1;
}
delay18b20(4);
}
/****************************************************************************
函數(shù)功能:向DS18B20讀溫度值
入口參數(shù):
出口參數(shù):temperature
****************************************************************************/
uint ReadTemperature(void)
{
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳過(guò)讀序列號(hào)的操作
WriteOneChar(0x44); //啟動(dòng)溫度轉(zhuǎn)換
delay18b20(125); //轉(zhuǎn)換需要一點(diǎn)時(shí)間,延時(shí)
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳過(guò)讀序列號(hào)的操作
WriteOneChar(0xbe); //讀溫度寄存器(頭兩個(gè)值分別為溫度的低位和高位)
tempL=ReadOneChar(); //讀出溫度的低位LSB
tempH=ReadOneChar(); //讀出溫度的高位MSB
//溫度轉(zhuǎn)換,把高低位做相應(yīng)的運(yùn)算轉(zhuǎn)化為實(shí)際溫度
temperature=((tempH*256)+tempL)*5/8;
delay18b20(200);
return(temperature);
}
//========1302寫(xiě)一個(gè)字節(jié)=========
void write_byte(uchar dat)
{
uchar i, dat_w;
dat_w = dat;
for(i=0;i<8;i++)
{
io = 0;
if(dat_w & 0x01)
io = 1;
else
io = 0;
dat_w = dat_w >> 1;
sclk = 0;
sclk = 1;
}
sclk = 0;
}
//===============================
//========1302讀一個(gè)字節(jié)=========
uchar read_byte()
{
uchar i, k;
k = 0;
for(i=0;i<8;i++)
{
k = k >> 1;
if(io)
k = k|0x80;
sclk = 1;
sclk = 0;
}
sclk = 0;
return (k);
}
//===============================
//========1302把數(shù)據(jù)寫(xiě)入地址=====
void write_add(uchar add, uchar dat)
{
rst = 0;
sclk = 0;
rst = 1;
write_byte(add);
write_byte((dat / 10 << 4) | (dat % 10));
sclk = 0;
rst = 0;
}
//===============================
//========1302從地址讀出數(shù)據(jù)=====
uchar read_add(uchar add)
{
uchar temp, dat1, dat2;
rst = 0;
sclk = 0;
rst = 1;
write_byte(add);
temp = read_byte();
sclk = 0;
rst = 0;
dat1 = temp / 16;
dat2 = temp % 16;
temp = dat1 * 10 + dat2;
return (temp);
}
//===============================
//=========1302時(shí)間初始化========
void ds1302_init()
{
write_add(0x8e,0x00); //打開(kāi)寫(xiě)保護(hù),寫(xiě)入時(shí)間;
write_add(0x80,50); //初始化--秒 50;
write_add(0x82,59); //初始化--分 59;
write_add(0x84,23); //初始化--時(shí) 23;
write_add(0x86,31); //初始化--日 31;
write_add(0x88,12); //初始化--月 12;
write_add(0x8c,10); //初始化--年 2010;
write_add(0x8e,0x80); //關(guān)閉寫(xiě)保護(hù),禁止寫(xiě)入。
}
//===============================
//=========1302讀出時(shí)間==========
void ds1302()
{
write_add(0x8e,0x00); //打開(kāi)寫(xiě)保護(hù),讀出時(shí)間;
second = read_add(0x81); //從1302讀出時(shí)間--秒;
minute = read_add(0x83); //從1302讀出時(shí)間--分;
hour = read_add(0x85); //從1302讀出時(shí)間--時(shí);
day = read_add(0x87); //從1302讀出時(shí)間--日;
month = read_add(0x89); //從1302讀出時(shí)間--月;
year = read_add(0x8d); //從1302讀出時(shí)間--年;
write_add(0x8e,0x80); //關(guān)閉寫(xiě)保護(hù),禁止讀出;
}
//===============================
//寫(xiě)命令函數(shù) ****************
void write_com(uchar com)
{
rs = 0;
rw = 0;
en = 0;
delay(5);
P0 = com;
delay(5);
en = 1;
delay(5);
en = 0;
}
//***************************
//寫(xiě)數(shù)據(jù)函數(shù)*****************
void write_data(uchar date)
{
rs = 1;
rw = 0;
en = 0;
delay(5);
P0 = date;
delay(5);
en = 1;
delay(5);
en = 0;
}
//***************************
//1602顯示一個(gè)字符===========
void DisplayOne(uchar *p)
{
write_data(*p);
}
//===========================
//======時(shí)間重新賦值=========
void time()
{
tab_time[0] = hour / 10;
tab_time[1] = hour % 10;
tab_time[3] = minute /10;
tab_time[4] = minute % 10;
tab_time[6] = second / 10;
tab_time[7] = second % 10;
tab_date[2] = year / 10;
tab_date[3] = year % 10;
tab_date[5] = month / 10;
tab_date[6] = month % 10;
tab_date[8] = day / 10;
tab_date[9] = day % 10;
}
//===========================
//======1602初始化===========
void init()
{
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
//===========================
//=====時(shí)間顯示函數(shù)==========
void DisplayTime()
{
uint n;
ds1302();
time();
write_com(0x80 + 6);
for(n=0;n<10;n++)
{
DisplayOne(tab_num + tab_date[n]); //顯示日期
}
write_com(0x80 + 0x40 + 6);
for(n=0;n<8;n++)
{
DisplayOne(tab_num + tab_time[n]); //顯示時(shí)間
}
}
//===========================
//=========時(shí)鐘停止==========
void stop()
{
write_add(0x8e, 00); //打開(kāi)寫(xiě)保護(hù)
write_add(0x80,80); //時(shí)鐘停止
write_add(0x8e, 80); //禁止寫(xiě)保護(hù)
write_com(0x80+0x40+12); //===================
write_data(tab_num[second/10]); // 顯示秒
write_data(tab_num[second%10]); //===================
}
//===========================
//==========時(shí)鐘開(kāi)始=========
void start()
{
write_add(0x8e, 00); //打開(kāi)寫(xiě)保護(hù)
write_add(0x80,second); //讀入秒
write_add(0x8e, 80); //禁止寫(xiě)保護(hù)
}
//=====矩陣鍵盤(pán)掃描函數(shù)======
void KeyScan()
{
P1 = 0xff;
if(key1 == 0) //即獨(dú)立鍵盤(pán)中的k1
{
delay(10);
if(key1 == 0)
{
key = 1;
while(!key1);
}
}
if(key2 == 0) //即獨(dú)立鍵盤(pán)中的k2
{
delay(10);
if(key2 == 0)
{
key = 2;
while(!key2);
}
}
if(key3 == 0) //即獨(dú)立鍵盤(pán)中的k3
{
delay(10);
if(key3 == 0)
{
key = 3;
while(!key3);
}
}
if(key4 == 0) //即獨(dú)立鍵盤(pán)中的k6
{
delay(10);
if(key4 == 0)
{
key = 4;
while(!key4);
}
}
}
//============================
//======按鍵操作函數(shù)==========
void KeyDo()
{
uint m = 15; //用以修改日期(第一行)時(shí),移動(dòng)閃爍光標(biāo)。
uint n = 13; //用以修改時(shí)間(第二行)時(shí),移動(dòng)閃爍光標(biāo)。
if(key == 1)
{
key = 0;
stop();
write_com(0x80 + 0x40 + n);
write_com(0x0f);
while(1)
{
KeyScan();
if(key == 3)
{
n = n + 3;
if(n > 13)
n = 7;
write_com(0x80 + 0x40 + n);
write_com(0x0f);
key = 0;
}
switch(n)
{
case 13 :
if(key == 2)
{
second++;
if(second == 60)
second = 0;
time();
write_add(0x8e,0x00);
write_add(0x80,second);
write_add(0x8e,0x80);
write_com(0x80 + 0x40 + 12);
DisplayOne(tab_num + tab_time[6]);
DisplayOne(tab_num + tab_time[7]);
write_com(0x80 + 0x40 + 13);
write_com(0x0f);
key = 0;
}
if(key == 4)
{
second--;
if(second == -1)
second = 59;
time();
write_add(0x8e,0x00);
write_add(0x80,second);
write_add(0x8e,0x80);
write_com(0x80 + 0x40 + 12);
DisplayOne(tab_num + tab_time[6]);
DisplayOne(tab_num + tab_time[7]);
write_com(0x80 + 0x40 + 13);
write_com(0x0f);
key = 0;
}
case 10 :
if(key == 2)
{
minute++;
if(minute == 60)
minute = 0;
time();
write_add(0x8e,0x00);
write_add(0x82,minute);
write_add(0x8e,0x80);
write_com(0x80 + 0x40 + 9);
DisplayOne(tab_num + tab_time[3]);
DisplayOne(tab_num + tab_time[4]);
write_com(0x80 + 0x40 + 10);
write_com(0x0f);
key = 0;
}
if(key == 4)
{
minute--;
if(minute == -1)
minute = 59;
time();
write_add(0x8e,0x00);
write_add(0x82,minute);
write_add(0x8e,0x80);
write_com(0x80 + 0x40 + 9);
DisplayOne(tab_num + tab_time[3]);
DisplayOne(tab_num + tab_time[4]);
write_com(0x80 + 0x40 + 10);
write_com(0x0f);
key = 0;
}
case 7 :
if(key == 2)
{
hour++;
if(hour == 24)
hour = 0;
time();
write_add(0x8e,0x00);
write_add(0x84,hour);
write_add(0x8e,0x80);
write_com(0x80 + 0x40 + 6);
DisplayOne(tab_num + tab_time[0]);
DisplayOne(tab_num + tab_time[1]);
write_com(0x80 + 0x40 + 7);
write_com(0x0f);
key = 0;
}
if(key == 4)
{
hour--;
if(hour == -1)
hour = 23;
time();
write_add(0x8e,0x00);
write_add(0x84,hour);
write_add(0x8e,0x80);
write_com(0x80 + 0x40 + 6);
DisplayOne(tab_num + tab_time[0]);
DisplayOne(tab_num + tab_time[1]);
write_com(0x80 + 0x40 + 7);
write_com(0x0f);
key = 0;
}
}
if(key == 1)
{
start();
key = 0;
write_com(0x0c);
break;
}
}
}
if(key == 3)
{
stop();
write_com(0x80 + m);
write_com(0x0f);
while(1)
{
KeyScan();
if(key == 3)
{
m = m + 3;
if(m > 15)
m = 9;
write_com(0x80 + m);
write_com(0x0f);
key = 0;
}
switch(m)
{
case 15 :
if(key == 2)
{
day++;
if(day == 32)
day = 1;
time();
write_add(0x8e,0x00);
write_add(0x86,day);
write_add(0x8e,0x80);
write_com(0x80 + 14);
DisplayOne(tab_num + tab_date[8]);
DisplayOne(tab_num + tab_date[9]);
write_com(0x80 + 15);
write_com(0x0f);
key = 0;
}
if(key == 4)
{
day--;
if(day == 0)
day = 31;
time();
write_add(0x8e,0x00);
write_add(0x86,day);
write_add(0x8e,0x80);
write_com(0x80 + 14);
DisplayOne(tab_num + tab_date[8]);
DisplayOne(tab_num + tab_date[9]);
write_com(0x80 + 15);
write_com(0x0f);
key = 0;
}
case 12 :
if(key == 2)
{
month++;
if(month == 13)
month = 1;
time();
write_add(0x8e,0x00);
write_add(0x88,month);
write_add(0x8e,0x80);
write_com(0x80 + 11);
DisplayOne(tab_num + tab_date[5]);
DisplayOne(tab_num + tab_date[6]);
write_com(0x80 + 12);
write_com(0x0f);
key = 0;
}
if(key == 4)
{
month--;
if(month == -1)
month = 12;
time();
write_add(0x8e,0x00);
write_add(0x88,month);
write_add(0x8e,0x80);
write_com(0x80 + 11);
DisplayOne(tab_num + tab_date[5]);
DisplayOne(tab_num + tab_date[6]);
write_com(0x80 + 12);
write_com(0x0f);
key = 0;
}
case 9 :
if(key == 2)
{
year++;
if(year == 100)
year = 0;
time();
write_add(0x8e,0x00);
write_add(0x8c,year);
write_add(0x8e,0x80);
write_com(0x80 + 8);
DisplayOne(tab_num + tab_date[2]);
DisplayOne(tab_num + tab_date[3]);
write_com(0x80 + 9);
write_com(0x0f);
key = 0;
}
if(key == 4)
{
year--;
if(year == -1)
year = 23;
time();
write_add(0x8e,0x00);
write_add(0x8c,year);
write_add(0x8e,0x80);
write_com(0x80 + 8);
DisplayOne(tab_num + tab_date[2]);
DisplayOne(tab_num + tab_date[3]);
write_com(0x80 + 9);
write_com(0x0f);
key = 0;
}
}
if(key == 1)
{
key = 0;
start();
write_com(0x0c);
break;
}
}
}
}
void Display_18b20()
{
uint t1,t2,t3;
t1 = ReadTemperature()/100%10;
t2 = ReadTemperature()/10%10;
t3 = ReadTemperature()%10;
write_com(0x80);
write_data(tab_num[t1]);
write_data(tab_num[t2]);
DisplayOne(".");
write_data(tab_num[t3]);
}
//============================
void main()
{
init();
ds1302_init();
while(1)
{
Display_18b20();
KeyScan();
KeyDo();
DisplayTime();
}
}
作者: 瀚海沒(méi)有水 時(shí)間: 2018-1-11 21:26
大家來(lái)看看 提點(diǎn)建議
作者: wxyyxr 時(shí)間: 2018-1-11 22:32
看起來(lái)不錯(cuò),感謝分享!
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |