- #include<reg52.h>
- #include<intrins.h>
- #include<string.h> //字符串操作函数
- //宏定义
- #define uchar unsigned char
- #define uint unsigned char
- //定义全局变量
- #define lcddata P2 //液晶8位并口数据
- uchar hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;
- sbit lcd_rs=P0^7;
- sbit lcd_rw=P0^6;
- sbit lcd_e=P0^5;
- sbit lcd_psw=P0^4;
- sbit lcd_rst=P0^3;
- uchar week_value[3];
- sbit DS1302_RST=P1^0;
- sbit DS1302_SCLK=P1^2;
- sbit DS1302_DATA=P1^1;
- void show_all();//定义特殊位
- void delaynms(uint aa)
- {
- uchar bb;
- while(aa--)
- {
- for(bb=0;bb<115;bb++) //1ms基准延时程序
- {
- ;
- }
- }
- }
- void chkbusy_lcd(void)
- {
- lcddata=0xff; //把忙碌标志位BF置1
- lcd_rs=0; //指令操作
- lcd_rw=1; //读操作
- lcd_e=1; //拉高使能,读取数据
- _nop_(); //判断忙碌位是否为0,若果为1,液晶忙,一直等待(BF=1,状态忙)
- lcd_e=0; //拉低使能
- }
- void wr_lcd(uchar dat_comm,uchar content)
- {
- chkbusy_lcd();
- if(dat_comm==1)
- {
- lcd_rs=1; //data
- lcd_rw=0; //write
- }
- else
- {
- lcd_rs=0; //command
- lcd_rw=0; //write
- }
- lcd_e=1; //拉高使能
- lcddata=content;//放上数据
- _nop_(); //等待
- lcd_e=0; //拉低使能,使数据写入
- }
- void init_lcd(void)
- {
- wr_lcd(0,0x30); //基本指令集
- delaynms(1); //等待
- wr_lcd(0,0x30); //再设置一次为基本指令集,因为ST7920中有2个寄存器用来设置使用哪个指令集
- delaynms(1); //等待
- wr_lcd(0,0x0c); //开显示,关游标,关游标位置
- delaynms(1); //等待
- wr_lcd(0,0x01); //清屏,地址指针指向00H
- delaynms(20); //等待>10ms
- wr_lcd(0,0x06); //光标右移,整体不移
- }
- void lcd_clr(void)
- {
- wr_lcd(0,0x30); //基本指令集
- wr_lcd(0,0x01); //清除显示
- delaynms(1);
- }
- void gotoxy(unsigned char y, unsigned char x)
- {
- if(y==1)
- wr_lcd(0,0x80|x); //Line 1
- if(y==2)
- wr_lcd(0,0x90|x); //Line 2
- if(y==3)
- wr_lcd(0,((0x80|x)+8)); //Line 3
- if(y==4)
- wr_lcd(0,((0x90|x)+8)); //Line 4
- }
- void print(uchar *str)
- {
- while(*str!='\0') //检查是否到字符串尾
- {
- wr_lcd(1,*str++); //输入*str后str++
- }
- }
- void DS1302InputByte(uchar d)
- {
- uchar i;
- DS1302_SCLK=0; //拉低SCLK,为上升沿写入数据做好准备
- for(i=0;i<8;i++) //连续写入8个二进制数据
- {
- DS1302_DATA=d&0x01; //取出d的第0位,写入1302, 低位在前,高位在后
- _nop_(); //等待
- DS1302_SCLK=1; // 拉高SCLK,上升沿写入数据
- _nop_(); // 等待
- DS1302_SCLK=0; //拉低SCLK形成脉冲
- d>>=1; //将d的数据向右移一位,准备写入下一个二进制数据
- }
- }
- uchar DS1302OutputByte(void)
- {
- uchar i;
- uchar dat;
- for(i=0;i<8;i++) //连续读出8个二进制数
- {
- dat>>=1; //向右移一位
- if(DS1302_DATA==1) //如果读出数据是1,(上一个写入控制字结束后,保存一个读出数据)
- {
- dat|=0x80;
- }
- DS1302_SCLK=1; //拉高SCLK
- _nop_();
- DS1302_SCLK=0; //拉低SCLK,读取数据
- }
- return dat; //将读出的数据返回
- }
- void Write1302(uchar ADDRorCOMM,uchar DATA)
- {
- DS1302_RST=0; //禁止数据传输
- DS1302_SCLK=0; //确保写写之前SCLK被拉低
- DS1302_RST=1; //启动数据传输
- DS1302InputByte(ADDRorCOMM); //写入命令或地址
- DS1302InputByte(DATA); //
- DS1302_SCLK=1; //将时钟电平置于高电平状态 $$ 置高是为了让下次写的时候 能准确的被拉低 保证电平
- //状态的正确性
- DS1302_RST=0; //禁止数据传输
- }
- uchar Read1302(uchar ADDRorCOMM)
- {
- uchar dat;
- DS1302_RST=0; //禁止数据传输
- DS1302_SCLK=0; //确保写写之前SCLK被拉低
- DS1302_RST=1; //启动数据传输
- DS1302InputByte(ADDRorCOMM); //写入命令或地址
- dat=DS1302OutputByte(); // 读出数据
- DS1302_SCLK=1; //将时钟电平置于高电平状态置高是为了让下次写的时候 能准确的被拉低 保证电平
- //状态的正确性
- DS1302_RST=0; //禁止数据传输
- return(dat);
- }
- void Init_1302(void) //(2008年7月12日12时00分00秒星期六)
- {
- uchar flag;
- flag=Read1302(0x81); //读秒寄存器
- if(flag&0x80) //CH为0(flag最高位是0),时钟走动,不用初始化 。
- {
- Write1302(0x8e,0x00); //允许写操作
- Write1302(0x8c,((14/10)<<4|(14%10))); //YEAR
- Write1302(0x8a,0x01); //DAY
- Write1302(0x88,((4/10)<<4|(4%10))); //MONTH
- Write1302(0x86,((29/10)<<4|(29%10))); //DATE
- Write1302(0x84,((11/10)<<4|(11%10))); //HR
- Write1302(0x82,((0/10)<<4|(7%10))); //MIN
- Write1302(0x80,((0/10)<<4|(0%10))); //SEC
- Write1302(0x90,0xa5); //打开充电功能
- Write1302(0x8e,0x80); //禁止写操作
- }
- }
- typedef struct _SYSTEMTIME_
- {
- uchar Second;
- uchar Minute;
- uchar Hour;
- uchar Week;
- uchar Day;
- uchar Month;
- uchar Year;
- uchar DateString[11];
- uchar TimeString[9];
- }SYSTEMTIME;
- SYSTEMTIME CurrentTime;
- void DS1302_GetTime(SYSTEMTIME *Time)
- {
- uchar ReadValue;
- ReadValue=Read1302(0x81); //从秒寄存器里读数据
- Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f); //把读出的数据转换成BCD码
- ReadValue=Read1302(0x83); //从分寄存器里读数据
- Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f); //把读出的数据转换成BCD码
- ReadValue=Read1302(0x85); //从小时寄存器里读数据
- Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f); //把读出的数据转换成BCD码
- ReadValue=Read1302(0x8b); //从星期寄存器里读数据
- Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f); //把读出的数据转换成BCD码
- ReadValue=Read1302(0x87); //从日寄存器里读数据
- Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f); //把读出的数据转换成BCD码
- ReadValue=Read1302(0x89); //从月寄存器里读数据
- Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f); //把读出的数据转换成BCD码
- ReadValue=Read1302(0x8d); //从年寄存器里读数据
- Time->Year=((ReadValue&0xf0)>>4)*10+(ReadValue&0x0f); //把读出的数据转换成BCD码 //注意是0xF0
- }
- void Date2Str(SYSTEMTIME *Time)
- {
- // uchar tab[]={0xc8,0xd5,0xbb6,0xfe,0xc8,0xfd,0xcb,0xc4,0xce,0xe5,0xc1,0xf9,0xd2,0xbb};
- uchar tab[]={"一二三四五六日"};
-
- if(hide_year<2) ////这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,
- {
- Time->DateString[0]='2';
- Time->DateString[1]='0';
- Time->DateString[2]=Time->Year/10+'0';
- Time->DateString[3]=Time->Year%10+'0';
- }
- else
- {
- Time->DateString[0]=' ';
- Time->DateString[1]=' ';
- Time->DateString[2]=' ';
- Time->DateString[3]=' ';
- }
- Time->DateString[4]='-';
- if(hide_month<2)
- {
- Time->DateString[5]=Time->Month/10+'0';
- Time->DateString[6]=Time->Month%10+'0';
- }
- else
- {
- Time->DateString[5]=' ';
- Time->DateString[6]=' ';
- }
- Time->DateString[7]='-';
- if(hide_day<2)
- {
- Time->DateString[8]=Time->Day/10+'0';
- Time->DateString[9]=Time->Day%10+'0';
- }
- else
- {
- Time->DateString[8]=' ';
- Time->DateString[9]=' ';
- }
- if(hide_week<2)
- {
-
- week_value[0]=tab[2*(Time->Week%10)-2]; //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示
- week_value[1]=tab[2*(Time->Week%10)-1];
- }
- else
- {
- week_value[0]=' ';
- week_value[1]=' ';
- }
- week_value[2]='\0';
- Time->DateString[10]='\0'; //字符串末尾加 '\0' ,判断结束字符
- }
- void Time2Str(SYSTEMTIME *Time)
- {
- if(hide_hour<2)
- {
- Time->TimeString[0]=Time->Hour/10+'0';
- Time->TimeString[1]=Time->Hour%10+'0';
- }
- else
- {
- Time->TimeString[0]=' ';
- Time->TimeString[1]=' ';
- }
- Time->TimeString[2]=':';
- if(hide_min<2)
- {
- Time->TimeString[3]=Time->Minute/10+'0';
- Time->TimeString[4]=Time->Minute%10+'0';
- }
- else
- {
- Time->TimeString[3]=' ';
- Time->TimeString[4]=' ';
- }
- Time->TimeString[5]=':';
- if(hide_sec<2)
- {
- Time->TimeString[6]=Time->Second/10+'0';
- Time->TimeString[7]=Time->Second%10+'0';
- }
- else
- {
- Time->TimeString[6]=' ';
- Time->TimeString[7]=' ';
- }
- Time->TimeString[8]='\0';
- }
- //********************************************************************************************
- //
- // 液晶显示主程序模块
- //*********************************************************************************************
- void show_all(void)
- {
- DS1302_GetTime(&CurrentTime); //获取时钟芯片数据
- Time2Str(&CurrentTime); //日期数据转化为液晶字符,放在TimeString[9]里,“12:00:00”
- Date2Str(&CurrentTime); //时间数据转化为液晶字符,放在DateString[11]里,“2008-07-12”
- //星期数据放在week_value[3]里
- gotoxy(1,0); //第一行显示
- print("【xx的万年历】");
- gotoxy(2,0); //
- print(CurrentTime.DateString);
- gotoxy(2,5); //
- print("星期");
- gotoxy(2,7);
- print(week_value);
- gotoxy(3,0); //
- print("时间:");
- gotoxy(3,3); //
- print(CurrentTime.TimeString);
- gotoxy(4,0); //
- print("制作");
- // gotoxy(4,2); //
- // print(TempBuffer);
- // gotoxy(4,6);
- // print("℃");
- delaynms(500); //扫描延时
- }
- void main(void)
- {
- Init_1302();
- while(1)
- {
- init_lcd(); //液晶初始化
- lcd_clr(); //清屏
- show_all();
-
- }
- }
-
你先看看程序,我不知道怎么调试程序了