打印

ds1302时钟芯片编程在液晶上显示

[复制链接]
1905|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小涛xty|  楼主 | 2011-8-22 21:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*-----------------------------------------------
  名称:ds1302时钟芯片编程
  修改:无
  内容:在液晶上以二行的形式显示出时钟
------------------------------------------------*/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
sbit RS=P2^4;//位声明
sbit RW=P2^5;
sbit E =P2^6;
sbit SCLK=P3^6;//串行时钟
sbit IO  =P3^4;//数据输入/输出
sbit RST =P3^5;//
void write_ds1302_byte(uchar dat);
void write_ds1302(uchar add,uchar dat);
uchar read_ds1302(uchar add);
void set_rtc(void);
void read_rtc(void);
void time_pros(void);
void init();
void write_com(uchar com);
void write_data(uchar date);
void delay(uint z);
uchar time_date[7]={11,6,8,6,20,22,30};//设置初值。年周月日时分秒
uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//写地址
uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//读地址
uchar disp1[11],disp2[8];
uchar code displcd[]="0123456789-: ";
/*------------------------------------------------
   延时子函数
-------------------------------------------------*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
{
  for(y=110;y>0;y--);
}
}
/*------------------------------------------------
      单字节的写子函数
------------------------------------------------*/
void write_ds1302_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
    SCLK=0;//SCLK为低电平时,数据可改;SCLK为高电平时,数据稳定
   IO=dat&0x01;//准备数据,数据从最低位开始传
   dat=dat>>1;//移位
   SCLK=1;
}
}
/*------------------------------------------------
       写多字节子函数
------------------------------------------------*/
void write_ds1302(uchar add,uchar dat)
{
RST=0;
_nop_();//停顿1个CPU周期 。需包含#include<intrins.h>
SCLK=0;
_nop_();
RST=1;//此时可写数据
_nop_();
write_ds1302_byte(add);//单字节的写数据地址
write_ds1302_byte(dat);//单字节的写数据
RST=0; //
_nop_();
IO=1;// 释放
SCLK=1;//释放
}
/*------------------------------------------------
        读函数
------------------------------------------------*/
uchar read_ds1302(uchar add)
{
  uchar i,value;
RST=0;
_nop_();//停顿1个CPU周期
SCLK=0;
_nop_();
RST=1;
_nop_();
write_ds1302_byte(add);//写地址。此时SCLK为高电平
for(i=0;i<8;i++)
{
  value=value>>1;
  SCLK=0;
  if(IO)
  {
   value=value|0x80;//读和写都是从最低位开始的
  }
  SCLK=1;
}
RST=0;//芯片停止
_nop_();
SCLK=0;
_nop_();
SCLK=1;
IO=1;
return( value);
}
/*------------------------------------------------
     设置实时时钟(rtc)
------------------------------------------------*/
void set_rtc(void)
{
uchar i,j;
for(i=0;i<7;i++)
{
j=time_date[i]/10;       //转化为BCD码
time_date[i]=time_date[i]%10;    //
time_date[i]=time_date[i]+j*16;    //
}           
write_ds1302(0x8e,0x00);//去除写保护
for(i=0;i<7;i++)       //写数据
{
  write_ds1302(write_add[i],time_date[i]);
}
write_ds1302(0x8e,0x80);//加写保护
}
/*------------------------------------------------
       读时间子函数
-------------------------------------------------*/
void read_rtc(void)
{
uchar i;
for(i=0;i<7;i++)
{
  time_date[i]=read_ds1302(read_add[i]);//读的数放入数组time_date[i]
}
}
/*-----------------------------------------------
      处理函数(BCD转换为十进制)
------------------------------------------------*/
void time_pros(void)
{
disp1[0]=time_date[0]/16;//年的十位
disp1[1]=time_date[0]%16;//年的个位
disp1[2]=10;
disp1[3]=time_date[2]/16;//月的十位
disp1[4]=time_date[2]%16;//月的个位
disp1[5]=10;
disp1[6]=time_date[3]/16;//日的十位
disp1[7]=time_date[3]%16;//日的个位
disp1[8]=12;
disp1[9]=12;
disp1[10]=time_date[1]%16;//周的个位
disp2[0]=time_date[4]/16;//时的十位
disp2[1]=time_date[4]%16;//时的个位
disp2[2]=11;
disp2[3]=time_date[5]/16;//分的十位
disp2[4]=time_date[5]%16;//分的个位
disp2[5]=11;
disp2[6]=time_date[6]/16;//秒的十位
disp2[7]=time_date[6]%16;//秒的个位     
}
/*------------------------------------------------
   写指令子函数
------------------------------------------------*/
void write_com(uchar com)
{
RS=0;//写指令
P0=com;//输入指令
delay(5);//延时5ms
E=1;
delay(5);
E=0;
}
/*------------------------------------------------
   写数据子函数
------------------------------------------------*/
void write_data(uchar date)
{
RS=1;//写数据
P0=date;//输入数据
delay(5);//延时5ms
E=1;
delay(5);
E=0;
}
/*------------------------------------------------
   初始化子函数
------------------------------------------------*/
void init()
{
RW=0;//一直为写状态
E=0;//使能端置0
write_com(0x38);//显示模式设置,即设置16*2显示,5*7点阵,8位数据接口
write_com(0x06);//当读或写一个字符后地址指针加1,且光标加1
write_com(0x0e);//开显示,显示光标,光标不闪烁
write_com(0x80);//数据指针初始化
}
/*------------------------------------------------
    主函数
------------------------------------------------*/
main()
{
uchar num,j;
init();
set_rtc();
while(1)
{
  read_rtc();
  time_pros();
  write_com(0x80);
  for(num=0;num<11;num++)//写入第1行字符
  {
   j=disp1[num];
   write_data(displcd[j]);
   delay(2);
  }
  write_com(0x80+0x40);
  for(num=0;num<8;num++)//写入第2行字符
  {
   j=disp2[num];
   write_data(displcd[j]);
   delay(2);
  }
}
}

相关帖子

沙发
小涛xty|  楼主 | 2011-8-22 21:27 | 只看该作者
:D

使用特权

评论回复
板凳
gaoyuaug| | 2011-9-24 07:50 | 只看该作者
/*------------------------------------------------
     设置实时时钟(rtc)
------------------------------------------------*/
void set_rtc(void)
{
uchar i,j;
for(i=0;i<7;i++)
{
j=time_date[i]/10;       //转化为BCD码
time_date[i]=time_date[i]%10;    //
time_date[i]=time_date[i]+j*16;    //
}           
write_ds1302(0x8e,0x00);//去除写保护
for(i=0;i<7;i++)       //写数据
{
  write_ds1302(write_add[i],time_date[i]);
}
write_ds1302(0x8e,0x80);//加写保护
}
/*------------------------------------------------
楼上,这段BCD码转换看不懂能解释一下吗?二-十进制不就是BCD吗?为什么要这样转换一下呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

50

帖子

1

粉丝