#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;// 独立按键位定义 sbit key3 = P1^2;// sbit key4 = P1^3;// /////////////////// /////////////////// sbit DQ = P2^2;//// /////////////////// uchar tempL=0; //临时变量低位 uchar tempH=0; //临时变量高位 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}; //对应字符为: { 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}; // 延时函数,延时z毫秒 ****** void delay(uint z) { uint x, y; for(x=0;x<z;x++) for(y=0;y<110;y++); } //*************************** /**************************************************************************** 函数功能:延时子程序 入口参数:k 出口参数: ****************************************************************************/ void delay18b20(unsigned int k) { unsigned int n; n=0; while(n < k) {n++;} return; } /**************************************************************************** 函数功能:DS18B20初始化子程序 入口参数: 出口参数: ****************************************************************************/ Init_DS18B20(void) { unsigned char x=0; DQ=1; //DQ先置高 delay18b20(8); //延时 DQ=0; //发送复位脉冲 delay18b20(85); //延时(>480ms) DQ=1; //拉高数据线 delay18b20(14); //等待(15~60ms) } /**************************************************************************** 函数功能:向DS18B20读一字节数据 入口参数: 出口参数: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); } /**************************************************************************** 函数功能:向DS18B20写一字节数据 入口参数:dat 出口参数: ****************************************************************************/ 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); } /**************************************************************************** 函数功能:向DS18B20读温度值 入口参数: 出口参数:temperature ****************************************************************************/ uint ReadTemperature(void) { Init_DS18B20(); //初始化 WriteOneChar(0xcc); //跳过读序列号的操作 WriteOneChar(0x44); //启动温度转换 delay18b20(125); //转换需要一点时间,延时 Init_DS18B20(); //初始化 WriteOneChar(0xcc); //跳过读序列号的操作 WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位) tempL=ReadOneChar(); //读出温度的低位LSB tempH=ReadOneChar(); //读出温度的高位MSB //温度转换,把高低位做相应的运算转化为实际温度 temperature=((tempH*256)+tempL)*5/8; delay18b20(200); return(temperature); } //========1302写一个字节========= 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读一个字节========= 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把数据写入地址===== 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从地址读出数据===== 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时间初始化======== void ds1302_init() { write_add(0x8e,0x00); //打开写保护,写入时间; write_add(0x80,50); //初始化--秒 50; write_add(0x82,59); //初始化--分 59; write_add(0x84,23); //初始化--时 23; write_add(0x86,31); //初始化--日 31; write_add(0x88,12); //初始化--月 12; write_add(0x8c,10); //初始化--年 2010; write_add(0x8e,0x80); //关闭写保护,禁止写入。 } //=============================== //=========1302读出时间========== void ds1302() { write_add(0x8e,0x00); //打开写保护,读出时间; second = read_add(0x81); //从1302读出时间--秒; minute = read_add(0x83); //从1302读出时间--分; hour = read_add(0x85); //从1302读出时间--时; day = read_add(0x87); //从1302读出时间--日; month = read_add(0x89); //从1302读出时间--月; year = read_add(0x8d); //从1302读出时间--年; write_add(0x8e,0x80); //关闭写保护,禁止读出; } //=============================== //写命令函数 **************** void write_com(uchar com) { rs = 0; rw = 0; en = 0; delay(5); P0 = com; delay(5); en = 1; delay(5); en = 0; } //*************************** //写数据函数***************** void write_data(uchar date) { rs = 1; rw = 0; en = 0; delay(5); P0 = date; delay(5); en = 1; delay(5); en = 0; } //*************************** //1602显示一个字符=========== void DisplayOne(uchar *p) { write_data(*p); } //=========================== //======时间重新赋值========= 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); } //=========================== //=====时间显示函数========== 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]); //显示时间 } } //=========================== //=========时钟停止========== void stop() { write_add(0x8e, 00); //打开写保护 write_add(0x80,80); //时钟停止 write_add(0x8e, 80); //禁止写保护 write_com(0x80+0x40+12); //=================== write_data(tab_num[second/10]); // 显示秒 write_data(tab_num[second%10]); //=================== } //=========================== //==========时钟开始========= void start() { write_add(0x8e, 00); //打开写保护 write_add(0x80,second); //读入秒 write_add(0x8e, 80); //禁止写保护 } //=====矩阵键盘扫描函数====== void KeyScan() { P1 = 0xff; if(key1 == 0) //即独立键盘中的k1 { delay(10); if(key1 == 0) { key = 1; while(!key1); } } if(key2 == 0) //即独立键盘中的k2 { delay(10); if(key2 == 0) { key = 2; while(!key2); } } if(key3 == 0) //即独立键盘中的k3 { delay(10); if(key3 == 0) { key = 3; while(!key3); } } if(key4 == 0) //即独立键盘中的k6 { delay(10); if(key4 == 0) { key = 4; while(!key4); } } } //============================ //======按键操作函数========== void KeyDo() { uint m = 15; //用以修改日期(第一行)时,移动闪烁光标。 uint n = 13; //用以修改时间(第二行)时,移动闪烁光标。 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(); } }
|