万年历程序

  • 格式:doc
  • 大小:68.00 KB
  • 文档页数:12

#include <REGX52.H>#include <intrins.h>#define uchar unsigned char#define unit unsigned intsbit LCD_RS=P2^5; //LCD指令数据控制端口0 指令1 数据sbit LCD_RW=P2^6; //LCD 读写控制端0 向lcd写指令或是信息 1 读取lcd的信息sbit LCD_EN=P2^7; //LCD 使能端 1 读取信号1——0 执行程序(下降沿)sbit reset=P2^2; //DS1602的复位sbit K1=P1^0; // K1键sbit K2=P1^1; // K2键sbit K3=P1^2; // K3键sbit io=P2^1; //ds1602的6脚I/Osbit sclk=P2^0; //DS1602的时钟bit flag=1;hour=0;min=0;sec=0;bit year=0;month=0;day=0;week=0;uchar timecount=0;count=0;uchar init[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};uchar init1[]={0x00,0x00};uchar init2[]={0x50,0x59,0x23,0x31,0x12,0x05,0x10}; //秒分时日月星期年的默认时间设置void delayNOP(){_nop_();_nop_();_nop_();_nop_();}void delayl(int ms){unsigned char y;while(ms--){for(y=0;y<250;y++){_nop_();_nop_();_nop_();_nop_();}}}/*******检查LCD是否处于忙碌状态1 忙碌0 空闲,可以写指令程序**********/ bit lcd_busy(){bit result;LCD_RS=0;LCD_RW=1;LCD_EN=1;delayNOP();result=(bit)(P3&0X80);LCD_EN=0;return(result);}/* ***** 写指令数据到LCD RS=L RW=L EN高脉冲D0~D7=指令码***** */ void lcd_wcmd(uchar cmd){while(lcd_busy());LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();P3=cmd;delayNOP();LCD_EN=1;delayNOP();LCD_EN=0;}/***** 写显示数据到LCD RS=H RW=L EN高脉冲D0~D7数据*******/void lcd_wdat(uchar dat){while(lcd_busy());LCD_RS=1;LCD_RW=0;LCD_EN=0;P3=dat;delayNOP();LCD_EN=1;delayNOP();LCD_EN=0;}/******* LCD 的初始化************/void init_lcd(){delayl(15);lcd_wcmd(0x01); //清楚LCD的显示内容lcd_wcmd(0x38); //16*2显示5*7点阵8位数据接口delayl(5);lcd_wcmd(0x38); //16*2显示5*7点阵8位数据接口delayl(5);lcd_wcmd(0x38); //16*2显示5*7点阵8位数据接口delayl(5);lcd_wcmd(0x0c);//显示开光标关delayl(5);lcd_wcmd(0x06);//地址指针自动加1 整屏数据不移动delayl(5);lcd_wcmd(0x01);// 清屏,为写数据做准备delayl(5);}void delay(){uchar j;for(j=250;j>0;j--);}/******* 设定显示位置********/void write_position(uchar row,uchar col){uchar place;if(row==1){place=0x80+col-1;lcd_wcmd(place);}else{place=0x80+0x40+col-1;lcd_wcmd(place);}}void write_byte(uchar inbyte){uchar i;for(i=0;i<8;i++){sclk=0; //写的时候低电平改数据if(inbyte&0x01)io=1;elseio=0;sclk=1; // 高电平写数据入DS1302_nop_();inbyte=inbyte>>1;}}uchar read_byte(){uchar i,temp;io=1; // 设置输入口for(i=0;i<7;i++){sclk=0;if(io==1)temp=temp&0x08;elsetemp=temp&0x7f;sclk=1; //产生下跳沿temp=temp>>1; //右移1位}return(temp);}/******* 向DS1302里写入数据*****/void write_ds1302(uchar cmd,uchar indate){sclk=0;reset=1;write_byte(cmd);write_byte(indate);sclk=0;reset=0;}/********读DS1302 里某地址的数据*******/uchar read_ds1302(uchar addr){uchar backdate;sclk=0;reset=1;write_byte(addr);backdate=read_byte();sclk=0;reset=0;return(backdate);}/******设置初始时间********/void set_ds1302(uchar addr,uchar *p,uchar n){write_ds1302(0x8e,0x00); //写控制字允许写操作for(n=7;n>0;n--){write_ds1302(addr,*p);p++;addr=addr+2;}write_ds1302(0x8e,0x80);//写保护不允许写}/******* 读取当前时间*****/void read_nowtime(uchar addr,uchar *p,uchar n){for(n=7;n>0;n--){*p=read_ds1302(addr);p++;addr=addr+2;}}/******** LCD的初始化******/void init_ds1302(){reset=0;sclk=0;write_ds1302(0x80,0x00);// 打开保护write_ds1302(0x90,0xa6);write_ds1302(0x8e,0x80); //写保护}/******** Time0终端函数********/ void Time0(void) interrupt 1 using 0{TH0=0X4C;TL0=0X00;timecount++;if(timecount>9){timecount=0;flag=~flag;}}/********设定值写入DS1302*******/ void Set_W1302(uchar addr){uchar temp;write_ds1302(0x8e,0x00);temp=(init1[0]<<4)+init1[1];write_ds1302(addr,temp);write_ds1302(0x8e,0x80);}void Set_W1302sec(uchar addr){uchar temp;write_ds1302(0x8e,0x00);temp=((init1[0]<<4)&0x7f)+init1[1];write_ds1302(addr,temp);write_ds1302(0x8e,0x80);}/******被设置数据闪动******/void Set_Flash(uchar row,uchar col){init1[0]=count/10;init1[1]=count%10;if(flag){write_position(row,col);lcd_wdat(init1[0]+0x30);write_position(row,col+1);lcd_wdat(init1[1]+0x30);}else{write_position(row,col);lcd_wdat(0x20);write_position(row,col+1);lcd_wdat(0x20);}}/******* 指定位置显示调整后的时间*******/void Set_place(uchar row,uchar col){write_position(row,col);lcd_wdat(init1[0]+0x30);write_position(row,col+1);lcd_wdat(init1[1]+0x30);}/****** 显示当前时间******/void Play_nowtime(){read_nowtime(0x81,init,7);//读出当前时间独处7个字节write_position(2,5);lcd_wdat(((init[2]&0xf0)>>4)+0x30);write_position(2,6);lcd_wdat('0'+(init[2]&0x0f));// 读小时write_position(2,8);lcd_wdat('0'+((init[1]&0xf0)>>4));write_position(2,9);lcd_wdat('0'+(init[1]&0x0f)); //读分钟write_position(2,11);lcd_wdat('0'+((init[0]&0x70)>>4));write_position(2,12);lcd_wdat('0'+(init[0]&0x0f)); //秒write_position(1,4);lcd_wdat('0'+((init[6]&0xf0)>>4));write_position(1,5);lcd_wdat('0'+(init[6]&0x0f)); //读年write_position(1,2); //写入年的第一位lcd_wdat('2');write_position(1,3); //写入年的第二位lcd_wdat('0');write_position(1,7);lcd_wdat('0'+((init[4]&0xf0)>>4));write_position(1,8);lcd_wdat('0'+(init[4]&0x0f)); //读月write_position(1,10);lcd_wdat('0'+((init[3]&0xf0)>>4));write_position(1,11);lcd_wdat('0'+(init[3]&0x0f)); //读日write_position(1,14);lcd_wdat('0'+((init[5]&0xf0)>>4));write_position(1,15);lcd_wdat('0'+(init[5]&0x0f)); //读星期write_position(1,6);lcd_wdat('-');write_position(1,9);lcd_wdat('-'); //在年月之间加-write_position(2,7);lcd_wdat(':');write_position(2,10);lcd_wdat(':');}/******* 键设定函数********/void key_set(uchar num,uchar row,uchar col) {if(!K2){delayl(80);if(count!=num)count++;elsecount=0;}if(!K1){delayl(80);if(count!=0)count--;elsecount=num;}Set_Flash(row,col);}/******* 主函数********/void mian(){P1=0xff;TMOD=0x01; //定时器工作方式1,16 位定时TH0=0X4C; // 50msTL0=0X00;EA=1;ET0=1; //允许定时器0中断TR0=1;init_lcd(); // 初始化lcdinit_ds1302(); //初始化ds1302set_ds1302(0x80,init2,7); //自动设置初始时间日期年月while(1){if(!K3){delayl(80);write_ds1302(0x8e,0x00);// 写保护控制字允许写write_ds1302(0x80,0x80);// 停止始终运行write_ds1302(0x8e,0x80); // 写保护控制字,禁止写year=1;count=((init[6]&0xf0)>>4)*10+(init[6]&0x0f);//度当前年数据}while(year) //设定年{key_set(99,1,4); //年的一二位闪烁if(flag){write_position(1,2);lcd_wdat('2');write_position(1,3);lcd_wdat('0');}else{write_position(1,2);lcd_wdat(0x20);write_position(1,3);lcd_wdat(0x20);}if(!K3){delayl(80);Set_W1302(0x8c); //写数据到ds1302 并保存Set_place(1,4); //写数据到1602 并显示write_position(1,2);lcd_wdat('2');write_position(1,3);lcd_wdat('0'); //写年的第一和第二位year=0;month=1;count=((init[4]&0xf0)>>4)*10+(init[4]&0x0f);//读当前月数据}}while(month) //设定月{key_set(12,1,7);if(!K3){delayl(80);Set_W1302(0x88);Set_place(1,7);month=0;day=1;count=((init[3]&0xf0)>>4)*10+(init[3]&0x0f); //读当前日数据}}while(day)key_set(31,1,10);if(!K3){delayl(80);Set_W1302(0x86);Set_place(1,10);day=0;week=1;count=((init[5]&0xf0)>>4)*10+(init[5]&0x0f); //读当前星期数据}}while(week) //设定星期{key_set(7,1,14);if(!K3){delayl(80);Set_W1302(0x8a);Set_place(1,14);week=0;hour=1;count=((init[2]&0xf0)>>4)*10+(init[2]&0x0f); //读当前星期数据}}while(hour) //设定小时{key_set(23,2,5);if(!K3){delayl(80);Set_W1302(0x84);Set_place(2,5);hour=0;min=1;count=((init[1]&0xf0)>>4)*10+(init[1]&0x0f); //读当前小时数据}}while(min) //设定分{key_set(59,2,8);if(!K3){delayl(80);Set_W1302(0x82);Set_place(2,8);min=0;sec=1;count=((init[0]&0x70)>>4)*10+(init[0]&0x0f); //读当前分数据}}while(sec) //设定秒{key_set(59,2,11);if(!K3){delayl(80);Set_W1302(0x80);Set_place(2,11);sec=0; //读当前秒数据}}Play_nowtime();}。