7段式数码管显示时间,ds1302芯片,89c51单片机,protues+keil-c仿真电路加源程序,比较简单,属于校内课程实验,
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- #define uchar unsigned char
- uchar dot,time1[8],flash;
- unsigned int tt;
- uchar flag=0;
- code seven_tab[15]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x37,0x5c,0x77,0x73};//0--9,-,N,o,A,p
- sbit rtc_clk=P3^6;
- sbit rtc_data=P3^4;
- sbit rtc_rst=P3^5;
- sbit p2_2=P2^2;
- sbit p2_3=P2^3;
- sbit p2_4=P2^4;
- sbit p3_0=P3^2;
- sbit p2_7=P3^3;
- sbit p2_6=P2^6;
- sbit a0=ACC^0;
- sbit a7=ACC^7;
- void write_rtc(uchar date) //写一字节
- {
- uchar i;
- ACC=date;
- for(i=8;i>0;i--)
- {
- rtc_data=a0;
- rtc_clk=1;
- rtc_clk=0;
- ACC=ACC>>1;
- }
- }
- uchar read_rtc() //读一字节
- {
- uchar i;
- for(i=8;i>0;i--)
- {
- ACC=ACC>>1;
- a7=rtc_data;
- rtc_clk=1;
- rtc_clk=0;
- }
- return(ACC);
- }
- void write1302(uchar address,uchar date) //写1302数据
- {
- rtc_rst = 0;
- rtc_clk = 0;
- rtc_rst = 1;
- write_rtc(address);
- write_rtc(date);
- rtc_clk = 1;
- rtc_rst = 0;
- }
- uchar read1302(uchar address)//读1302数据
- {
- uchar temp;
- rtc_rst = 0;
- rtc_clk = 0;
- rtc_rst = 1;
- write_rtc(address);
- temp=read_rtc();
- rtc_clk = 1;
- rtc_rst = 0;
- return(temp);
- }
- void init1302() //1302初始化
- {
- write1302(0x8e,0x00); //写操作
- write1302(0x80,0x21); //写秒
- write1302(0x82,0x50); //写分
- write1302(0x84,0x14); //写时
- write1302(0x88,0x05); //写月
- write1302(0x86,0x22); //写日
- write1302(0x8a,0x02); //写星期
- write1302(0x8c,0x18); //写年
- write1302(0x8e,0x80); //写保护
- }
- void get_time() //获取1302的时间数据(时、分、秒),存入time1数组中
- {
- uchar d;
- d = read1302(0x81);
- time1[0] = d & 0x0f;
- time1[1] = (d >> 4) & 0x0f;
- d = read1302(0x83);
- time1[3] = d & 0x0f;
- time1[4] = (d >> 4) & 0x0f;
- d = read1302(0x85);
- time1[6] = d & 0x0f;
- time1[7] = (d >>4 ) & 0x0f;
- time1[2]=time1[5]=10;
- }
- void get_date() //获取1302的日期数据(日月年),存入time1数组中
- { uchar d;
- d = read1302(0x87);
- time1[0] = d & 0x0f;
- time1[1] = (d >> 4) & 0x0f;
- d = read1302(0x89);
- time1[3] = d & 0x0f;
- time1[4] = (d >> 4) & 0x0f;
- d = read1302(0x8d);
- time1[6] = d & 0x0f;
- time1[7] = (d >>4 ) & 0x0f;
- time1[2]=time1[5]=10;
- }
- void get_week() //获取1302的星期数据,存入time1数组中
- { uchar d;
- d = read1302(0x8b);
- time1[3] = d & 0x0f;
- time1[4] =10;
- time1[1]=10;
- time1[6]=12;
- time1[7]=11;
- d = read1302(0x85);
- if(((((d >>4 ) & 0x0f)==1)&(d & 0x0f)>=2)||((((d >>4 ) & 0x0f)==2)))
- {
- time1[0]=14;
- }
- else
- time1[0]=13;
- time1[2]=time1[5]=10;
- }
- void set_min() //设置分钟显示 ---分钟---
- {
- uchar d;
- d = read1302(0x83);
- time1[3] = d & 0x0f;
- time1[4] = (d >> 4) & 0x0f;
- d = read1302(0x85);
- time1[6] = d & 0x0f;
- time1[7] = (d >>4 ) & 0x0f;
- time1[0]=time1[1]=time1[2]=time1[5]=10;
- }
- void set_hour() //设置时钟显示 时钟------
- {
- uchar d;
- d = read1302(0x85);
- time1[6] = d & 0x0f;
- time1[7] = (d >>4 ) & 0x0f;
- time1[0]=time1[1]=time1[2]=time1[5]=time1[3]=time1[4]=10;
- }
- void set_day() //设置日期显示 ------日期
- {
- uchar d;
- d = read1302(0x87);
- time1[0] = d & 0x0f;
- time1[1] = (d >> 4) & 0x0f;
- d = read1302(0x89);
- time1[3] = d & 0x0f;
- time1[4] = (d >> 4) & 0x0f;
- d = read1302(0x8d);
- time1[6] = d & 0x0f;
- time1[7] = (d >>4 ) & 0x0f;
- time1[2]=time1[5]=10;
- }
- void set_month() //设置月份显示 ---月份---
- {
- uchar d;
- d = read1302(0x89);
- time1[3] = d & 0x0f;
- time1[4] = (d >> 4) & 0x0f;
- d = read1302(0x8d);
- time1[6] = d & 0x0f;
- time1[7] = (d >>4 ) & 0x0f;
- time1[2]=time1[5]=time1[0]=time1[1]=10;
- }
- void set_year() //设置年份显示 年份------
- {
- uchar d;
- d = read1302(0x8d);
- time1[6] = d & 0x0f;
- time1[7] = (d >>4 ) & 0x0f;
- time1[3]=time1[4]=time1[2]=time1[5]=time1[0]=time1[1]=10;
- }
- void set_week() //设置星期显示 No--星期---
- {
- uchar d;
- d = read1302(0x8b);
- time1[3] = d & 0x0f;
- time1[6]=time1[4]=time1[2]=time1[5]=time1[0]=time1[1]=time1[7]=10;
- }
- /*void time0() interrupt 1 //使用T0定时器刷新数码管显示,刷新间隔为2ms
- {
- uchar i;
- TR0=0;
- TH0 = (65536 - 2000) / 256;
- TL0 = (65536 - 2000) % 256;
- TR0 = 1;
- switch(i) //位选,选择点亮的数码管,
- {
- case(7): p2_2=0; p2_3=0; p2_4=0; break;//显示第0位
- case(6): p2_2=1; p2_3=0; p2_4=0; break;//显示第1位
- case(5): p2_2=0; p2_3=1; p2_4=0; break;//显示第2位
- case(4): p2_2=1; p2_3=1; p2_4=0; break;//显示第3位
- case(3): p2_2=0; p2_3=0; p2_4=1; break;//显示第4位
- case(2): p2_2=1; p2_3=0; p2_4=1; break;//显示第5位
- case(1): p2_2=0; p2_3=1; p2_4=1; break;//显示第6位
- case(0): p2_2=1; p2_3=1; p2_4=1; break;//显示第7位
- }
- P1=seven_tab[time1[i]];
- i++;
- if(i==8)
- i=0;
- }
- void init_timer0() //初始化T0定时器
- {
- TMOD = 0x01;
- TH0 = (65536-2000) / 256;
- TL0 = (65536-2000) % 256;
- TR0 = 1;
- ET0 = 1;
- EA = 1;
- }*/
- void start() interrupt 0 //按下切屏键,切换时间,日期,星期;按下调节键,在调节分时日月年星期间切换
- {
-
- flag++;
- if(flag>2)
- {
- flag=0;
- }
-
- }
- void sart() interrupt 2
- {
-
- if(flag<3)
- flag=3;
- else
- {
- flag++;
- if(flag>8)
- flag=3;
- }
-
- }
- void delay(uchar t) //延时函数
- {
- uchar j=0;
- for(;t>0;t--)
- for(j=0;j<125;j++);
- }
- void main()
- {
- uchar n,i,d,t;
- /*init_timer0();*/
- init1302();
- IT0=1;
- EX0=1;
- EA=1;
- IT1=1;
- EX1=0;
- while(1)
- {
-
- switch(flag)
- {
- case 0:get_time(); //调用子函数,把存入数组time的数据给显示出来
- break;
- case 1:get_date(); //调用子函数,把存入数组date的数据给显示出来
- break;
- case 2:get_week(); //调用子函数,把存入数组week的数据给显示出来
- break;
- case 3:set_min(); //调整分
- if(p2_6==0)
- {
- delay(1000);
- if(p2_6==0)
- {
- n= read1302(0x83);
- d = n & 0x0f;
- t = (n >> 4) & 0x0f;
- d++;
- if(d>9)
- {
- d=0;
- t++;
- if(t>5)
- {
- t=0;
- }
- }
- n=(0x0f&d)|(0xf0&(t<<4));
- write1302(0x82,n);
- delay(1000);
- }
- }
- break;
- case 4:set_hour(); //调整时
- if(p2_6==0)
- {
- delay(1000);
- if(p2_6==0)
- {
- n= read1302(0x85);
- d = n & 0x0f;
- t = (n >> 4) & 0x0f;
- d++;
- if(t==2)
- {
- if(d>3)
- {
- d=0;
- t=0;
- }
- }
- if(d>9)
- {
- d=0;
- t++;
- }
-
- n=(0x0f&d)|(0xf0&(t<<4));
- write1302(0x84,n);
- delay(1000);
- }
- }
- break;
- case 5:set_day(); //调整日
- if(p2_6==0)
- {
- delay(1000);
- if(p2_6==0)
- {
- n= read1302(0x87);
- d = n & 0x0f;
- t = (n >> 4) & 0x0f;
- d++;
- if(t==3)
- {
- if(d>1)
- {
- d=1;
- t=0;
- }
- }
- if(d>9)
- {
- d=0;
- t++;
- }
-
- n=(0x0f&d)|(0xf0&(t<<4));
- write1302(0x86,n);
- delay(1000);
- }
- }
- break;
- case 6:set_month(); //调整月
- if(p2_6==0)
- {
- delay(1000);
- if(p2_6==0)
- {
- n= read1302(0x89);
- d = n & 0x0f;
- t = (n >> 4) & 0x0f;
- d++;
- if(t==1)
- {
- if(d>2)
- {
- d=1;
- t=0;
- }
- }
- if(d>9)
- {
- d=0;
- t++;
- }
-
- n=(0x0f&d)|(0xf0&(t<<4));
- write1302(0x88,n);
- delay(1000);
- }
- }
- break;
- case 7:set_year(); //调整年
- if(p2_6==0)
- {
- delay(1000);
- if(p2_6==0)
- {
- n= read1302(0x8d);
- d = n & 0x0f;
- t = (n >> 4) & 0x0f;
- d++;
- if(d>9)
- {
- d=0;
- t++;
- if(t>9)
- {
- t=0;
- }
- }
-
- n=(0x0f&d)|(0xf0&(t<<4));
- write1302(0x8c,n);
- delay(1000);
- }
- }
- break;
- case 8:set_week(); //调整星期
- if(p2_6==0)
- {
- delay(1000);
- if(p2_6==0)
- {
- n= read1302(0x8b);
- d = n & 0x0f;
- d++;
- if(d>7)
- {
- d=1;
- }
-
- n=0x0f&d;
- write1302(0x8a,n);
- delay(1000);
- }
- }
- break;
- }
- for(i=0;i<8;i++)
- {
- switch(i) //位选,选择点亮的数码管,
- {
- case(7): p2_2=0; p2_3=0; p2_4=0; break;//显示第0位
- case(6): p2_2=1; p2_3=0; p2_4=0; break;//显示第1位
- case(5): p2_2=0; p2_3=1; p2_4=0; break;//显示第2位
- case(4): p2_2=1; p2_3=1; p2_4=0; break;//显示第3位
- case(3): p2_2=0; p2_3=0; p2_4=1; break;//显示第4位
- case(2): p2_2=1; p2_3=0; p2_4=1; break;//显示第5位
- case(1): p2_2=0; p2_3=1; p2_4=1; break;//显示第6位
- case(0): p2_2=1; p2_3=1; p2_4=1; break;//显示第7位
- }
- P1=seven_tab[time1[i]];
- delay(2);
- }
- }
-
- }
复制代码
所有资料51hei提供下载:
ds1302.rar
(69.94 KB, 下载次数: 45)
|