×
单片机 > 单片机程序设计 > 详情

用ds1302制作一个精密的电子时钟

发布时间:2020-09-01 发布时间:
|
题目:用ds1302制作一个精密的电子时钟

感想:我看视频的时候讲的是DS12CR887这块芯片,两块毕竟是不一样的,所以,我只是看了他讲怎样看时序,之后的就没再看了。我就拿着自己下载打印的DS1302数据手册,研习,研习,再研习。还查了书上的,网上的,源程序。但是,你别指望着谁会把所有的东西都给你写上去。只能作为参考。后来,我终于写出了一个程序,可是一编译,就漏洞百出。最主要的有两点:for循环和BCD码。不过还好,都得到了很好的解决。

解决方案:

#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar data table[]="2009-01-01 Mon.";
uchar data table1[]="  00:00:00";
uchar code xingqi[]="Mon. Tue. Wed. Thu. Fri. Sat. Sun.";
uchar num;
uchar hour,min,sec,week,day,month,year;
sbit ds1302_sclk=P1^4;
sbit ds1302_io=P1^5;
sbit ds1302_ce=P2^2;
sbit acc0=ACC^0;
sbit acc7=ACC^7;
sbit lcdrs=P1^7;    //端口定义
sbit lcdrw=P1^6;
sbit lcde=P2^4;
sbit le=P3^ 6;
sbit leden=P2^5;
sbit  dkle=P3^7;
void delay(uint a);
void write_byte(uchar dat) //写入一个字节
{
 uchar i;
 ACC=dat;
 for(i=8;i>0;i--)
 {
  ds1302_io=acc0;
  ds1302_sclk=1;
  ds1302_sclk=0;
  ACC=ACC>>1; 
 }
}

uchar read_byte()  //读出一个字节
{
 uchar i;
 for(i=8;i>0;i--)
 {
  ACC=ACC>>1;
  acc7=ds1302_io;
  ds1302_sclk=1;
  ds1302_sclk=0;
 }
 return(ACC); 
}

void  s_write(uchar add,uchar dat)//单字节写入子函数
{
 ds1302_ce=0;
 ds1302_sclk=0;
 ds1302_ce=1;
 write_byte(add);
 write_byte(dat);
 ds1302_sclk=1;
 ds1302_ce=0;
}
uchar s_read(uchar add)   //单字节读出子函数
{
 uchar temp;
 ds1302_ce=0;
 ds1302_sclk=0;
 ds1302_ce=1;
 write_byte(add);
 temp=read_byte();
 ds1302_sclk=1;
 ds1302_ce=0;

 temp=(temp/0x0a)*10+temp%0x0a;

 return(temp); 
}
void set_ds1302(uchar *pClock) //设置ds1302的时间
{
 uchar i;
 uchar add=0x80;
 EA=0;
 s_write(0x8e,0x00);
 for(i=7;i>0;i--)
 {
  s_write(add,*pClock);
  pClock++;
  add+=2;
 }
 s_write(0x8e,0x80);
 EA=1;
}
void read_ds1302(uchar Curtime[])  //读取ds1302的时间
{
 uchar i;
 uchar add=0x81;
 EA=0;
 for(i=7;i>0;i--)
 {
  Curtime[i]=s_read(add);
  add+=2;    
 }
 EA=1;
}
void write_com(uchar com)   //写命令子函数
{
 lcde=0;
 lcdrw=0;
 lcdrs=0;
 delay(1);
 lcde=1;
 delay(1);
 P0=com;
 delay(1);
 lcde=0;
}
void write_data(uchar dat) //写数据子函数
{
 lcde=0;
 lcdrw=0;
 lcdrs=1;
 delay(1);
 lcde=1;
 delay(1);
 P0=dat;
 delay(1);
 lcde=0;
}
void init()
{
 month=1;
 day=1;
 year=9; 
     
 lcde=0;      //LCD1602初始化
 le=0;
 leden=0;
 write_com(0x38);
 delay(100);
 write_com(0x38);
 delay(50);
 write_com(0x38);
 delay(10);
 write_com(0x08);
 write_com(0x01);
 write_com(0x0c);
 write_com(0x80);

 for(num=0;num<15;num++)   //在第一行显示“ 2000-00-00  Mon.”
 {
  write_data(table[num]);
 }
 write_com(0x80+0x40);
 for(num=0;num<10;num++)  //在第二行末尾显示“   00:00:00”
 {
  write_data(table1[num]);
 }
  
}
void write_time(uchar add,uchar dat)  //写入时间子函数
{
 uchar shi,ge;
 shi=dat/16;
 ge=dat%16;
 write_com(0x80+0x40+add);
 write_data(0x30+shi);
 write_data(0x30+ge);
}
void write_riqi(uchar add,uchar dat)  //写入日期子函数
{
 uchar shi,ge;
 shi=dat/16;
 ge=dat%16;
 write_com(0x80+add);
 write_data(0x30+shi);
 write_data(0x30+ge);
}
void write_xingqi(uchar dat)  //写入星期子函数
{
 write_com(0x80+0x0b);
 switch(dat)
 {
  case 1: for(num=0;num<4;num++)
    {
     write_data(xingqi[num]); 
    };break;
  case 2: for(num=5;num<9;num++)
    {
     write_data(xingqi[num]); 
    };break;
  case 3: for(num=10;num<14;num++)
    {
     write_data(xingqi[num]); 
    };break;
  case 4: for(num=15;num<19;num++)
    {
     write_data(xingqi[num]); 
    };break;
  case 5: for(num=20;num<24;num++)
    {
     write_data(xingqi[num]); 
    };break;
  case 6: for(num=25;num<29;num++)
    {
     write_data(xingqi[num]); 
    };break;
  case 7: for(num=30;num<34;num++)
    {
     write_data(xingqi[num]); 
    };break;

 }
}
void main()
{
 init();
 delay(5);
 s_write(0x8e,0x00); //控制写入WP=0
 s_write(0x90,0xa5);
 s_write(0x80,0x00); //秒
 s_write(0x82,0x20); //分
 s_write(0x84,0x09); //时24时制
 s_write(0x86,0x27); //日
 s_write(0x88,0x08); //月
 s_write(0x8a,0x04); //星期
 s_write(0x8c,0x09); //年 */
 s_write(0x8e,0x80);//控制写入WP=1;

 P0=0xff;

 while(1)
 
 sec=s_read(0x81);
  write_time(8,sec);
  write_com(0x80+0x40+9);
 min=s_read(0x83);
  write_time(5,min);
  write_com(0x80+0x40+6);
 hour=s_read(0x85);
  write_time(2,hour);
  write_com(0x80+0x40+3);
 week=s_read(0x8b);
  write_xingqi(week);
  write_com(0x80+0x0d);
 day=s_read(0x87);
  write_riqi(8,day);
  write_com(0x80+9);
 month=s_read(0x89);
  write_riqi(5,month);
  write_com(0x80+6);
 year=s_read(0x8d);
  write_riqi(2,year);
  write_com(0x80+3);
 }
}
void delay(uint a) {   //延时子函数
 uint i,j;
 for(j=a;j>0;j--)
     for(i=250;i>0;i--) ;
}

关键字:ds1302  精密  电子时钟

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多