打印

求大神指点:我的时钟不跳动?

[复制链接]
794|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
919106096|  楼主 | 2016-5-19 21:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是我的程序:
#include <intrins.h>
#include <reg51.h>
/*********************************端口定义**********************************/
sbit sclk =P3^6;
sbit io=P3^4;
sbit rst=P3^5;
sbit rs=P2^6;
sbit en=P2^7;
sbit rw=P2^5;
sbit key=P1^0;
sbit K1=P1^1;
sbit K2=P1^2;
#define uchar unsigned char
#define uint  unsigned int
uchar S1num,flag,second,minute,hour,week,day,month,year;//秒、分、时、星期、日、月、年
bit keyflag=0;

void delay(uint z) //延时子程序
{
   uint x,y;
   for(x=z;x>0;x--)
      for(y=110;y>0;y--);
}
void delayus()
{
_nop_();
_nop_();
_nop_();
_nop_();
}

void write_1602dat(uchar dat)//定义一个带参数的写数据子程序
{
  rs=1; //1602的rs为0时,接收命令,为1时接收数据
  P0=dat;//把void write_shu(uchar shu)中的COM中的数据给P0口
  delay(5);
  en=1;
  delay(5);
  en=0;
  delay(5);
}
  
  

void write_1602com(uchar com)//定义一个带参数的写命令子程序
{
  rs=0; //1602的rs为0时,接收命令,为1时接收数据
  P0=com;//把void write_com(uchar com)中的COM中的数据给P0口
  delay(5);
  en=1;
  delay(5);
  en=0;
  delay(5);
}
void Write1602(uchar add,uchar dat)
{
  write_1602com(add);
  write_1602dat(dat);
}
void init1602()//定义一个初始化子程序
{
  en=0;
  rw=0;
write_1602com(0x38);//调用 write_com子程序并把0x38赋给P0口,显示模式打开
write_1602com(0x0e);//调用 write_com子程序并把“开显示,显示光标,光标闪烁”指令码赋给P0口
write_1602com(0x06);//调用 write_com子程序并把“地址指针加1,整屏不移动”指令码赋给P0口
  //write_com(0x80+0x10);//数据指针初始化,让指针指向可显示的最右端
write_1602com(0x80);//数据指针初始化,让指针指向最左端,显示从第一行开始
write_1602com(0x01);//调用 write_com子程序并把"清零指"令码赋给P0口
Write1602(0x80,'2');
Write1602(0x81,'0');
Write1602(0x80+4,'-');
Write1602(0x80+7,'-');
Write1602(0x80+0x40+5,':');
Write1602(0x80+0x40+8,':');
  }
/********************写一个字节**************/
void write_1302byte(dat)
{
uchar i;
sclk=0;
delayus();
for(i=8;i>0;i--)
   {
    io=dat&0x01;//只要是从低位取数,向高位一定要和0X01与
    delayus();
    sclk=1;//为写数据制造上升沿。
    delayus();
    sclk=0;//为下一次上升沿写下一个字节做准备
    dat>>=1;//将数据向左移一位,准备写入下一个数据
   }
}

/********************读一个字节***************/
uchar read_1302byte()
{
uchar i,dat;
delayus();
for(i=8;i>0;i--)
   {
    dat>>=1;
    if(io==1)
    {
      dat|=0x80;//将1取出,写在dat的最高位。
    }
   
    sclk=1;//把sclk拉高,为读一个字节的下降沿做准备
    delayus();//稍等制造一个高电平
    sclk=0;//为读一个字节制造下降沿
    delayus();
   }
return dat;
}

/*************写入一个时间位*****************/
void write_1302(uchar add,uchar dat)
{
  rst=0;
delayus();
sclk=0;
delayus();
rst=1;
write_1302byte(add);
delayus();
write_1302byte(dat);
delayus();
rst=0;
}
/****************读1302的地址******************/
uchar read_1302add(uchar add)
{
uchar timedat;
rst=0;
_nop_();
sclk=0;
_nop_();
rst=1;
write_1302byte(add);//写入要读的地址
timedat=read_1302byte();//将上面地址中的数据赋给timedat
sclk=1;
_nop_();
rst=0;
return timedat;
}
/****************初始化1302*********************/
void init_1302()
{
  
   flag=read_1302add(0x81);//读秒寄存器的最高位,读出时钟状态
   if(flag&0x80)//判断时钟是否关闭,若内部关闭,则初始,若没关闭,不初始化,还在走
   
    {
    write_1302(0x8e,0x00);//去除写保护
    write_1302(0x80,((55/10)<<4|(55%10)));//写秒寄存器,并写入初值55
    write_1302(0x82,((59/10)<<4|(59%10)));//写分寄存器,并写入初值59
    write_1302(0x84,((22/10)<<4|(22%10)));//写小时寄存器,并写入初值23
    write_1302(0x86,((24/10)<<4|(24%10)));//写日寄存器,并写入初值18
    write_1302(0x88,((2/10)<<4|(2%10)));//写月寄存器,并写入初值2
    write_1302(0x8a,((5/10)<<4|(5%10)));//写周寄存器,并写入初值5
    write_1302(0x8c,((12/10)<<4|(12%10)));//写年寄存器,并写入初值12,不能写2012年
     write_1302(0x90,0xa5);//写充电方式
     write_1302(0x8e,0x80);//加上写保护
    }
}
/*****************读出秒的十进制数***************************/

uchar readsecond()
{
uchar dat;
dat=read_1302add(0x81);
second=((dat&0x70)>>4)*10+(dat&0x0f);
return second;
}

/*****************读出分的十进制数***************************/

uchar readminute()
{
uchar dat;
dat=read_1302add(0x83);
minute=((dat&0x70)>>4)*10+(dat&0x0f);
return minute;
}

/*****************读出小时的十进制数***************************/

uchar readhour()
{
uchar dat;
dat=read_1302add(0x85);
hour=((dat&0x70)>>4)*10+(dat&0x0f);
return hour;
}
/*****************读出天的十进制数***************************/

uchar readday()
{
uchar dat;
dat=read_1302add(0x87);
day=((dat&0x70)>>4)*10+(dat&0x0f);
return day;
}

/*****************读出月的十进制数***************************/

uchar readmonth()
{
uchar dat;
dat=read_1302add(0x89);
month=((dat&0x70)>>4)*10+(dat&0x0f);
return month;
}
/*****************读出周的十进制数***************************/

uchar readweek()
{
uchar dat;
dat=read_1302add(0x8b);
week=((dat&0x70)>>4)*10+(dat&0x0f);
return week;
}

/*****************读出年的十进制数***************************/

uchar readyear()
{
uchar dat;
dat=read_1302add(0x8d);
year=((dat&0xf0)>>4)*10+(dat&0x0f);
return year;
}
  
/************************读出所有时间**********************/
readtime()
{
readsecond();
readminute();
readhour();
readday();
readmonth();
readweek();
readyear();
}
/*********************向1602写入时间****************************/
void write_second()
{
uchar shi,ge;
shi=second/10;
ge=second%10;
Write1602(0x80+0x40+9,0x30+shi);
Write1602(0x80+0x40+10,0x30+ge);
}
void write_minute()
{
uchar shi,ge;
shi=minute/10;
ge=minute%10;
Write1602(0x80+0x40+6,0x30+shi);
Write1602(0x80+0x40+7,0x30+ge);
}
void write_hour()
{
uchar shi,ge;
shi=hour/10;
ge=hour%10;
Write1602(0x80+0x40+3,0x30+shi);
Write1602(0x80+0x40+4,0x30+ge);
}

void write_day()
{
uchar shi,ge;
shi=day/10;
ge=day%10;
Write1602(0x80+8,0x30+shi);
Write1602(0x80+9,0x30+ge);
}
void write_month()
{
uchar shi,ge;
shi=month/10;
ge=month%10;
Write1602(0x80+5,0x30+shi);
Write1602(0x80+6,0x30+ge);
}
void write_year()
{
uchar shi,ge;
shi=year/10;
ge=year%10;
Write1602(0x80+2,0x30+shi);
Write1602(0x80+3,0x30+ge);
}
void write_week()
{
Write1602(0x80+12,0x30+week);
//uchar week;
switch(week)
   {
    case 1: Write1602(0x80+12,'M');
         Write1602(0x80+13,'O');
      Write1602(0x80+14,'N');
      break;
     case 2:Write1602(0x80+12,'T');
         Write1602(0x80+13,'U');
      Write1602(0x80+14,'E');
      break;
     case 3:Write1602(0x80+12,'W');
         Write1602(0x80+13,'E');
      Write1602(0x80+14,'N');
      break;
     case 4:Write1602(0x80+12,'T');
         Write1602(0x80+13,'H');
      Write1602(0x80+14,'U');
      break;
  case 5:Write1602(0x80+12,'F');
         Write1602(0x80+13,'R');
      Write1602(0x80+14,'I');
      break;
     case 6:Write1602(0x80+12,'S');
         Write1602(0x80+13,'A');
      Write1602(0x80+14,'T');
      break;
  case 7:Write1602(0x80+12,'S');
         Write1602(0x80+13,'U');
      Write1602(0x80+14,'N');
      break;
   }
}
/*********************键盘扫描****************************/
void keyscan()
{
   if(key==0)
   {
     delay(5);
      if(key==0);//防止误动作
   {
     
      S1num++;
      while(!key);
      switch(S1num)
      {
       case 1:
         keyflag=1;
         write_1302(0x8e,0x00);//去除写保护
      write_1302(0x80,0x80);//时钟停下
      write_1602com(0x80+0x40+10);
      write_1602com(0x0f);
      break;
       case 2:
         write_1602com(0x80+0x40+7);
         break;
       case 3:
         write_1602com(0x80+0x40+4);
         break;
       case 4:
         write_1602com(0x80+9);
         break;
       case 5:
         write_1602com(0x80+6);
         break;
       case 6:
         write_1602com(0x80+3);
         break;
       case 7:
         write_1602com(0x80+12);
         break;
       case 8:
         S1num=0;
      keyflag=0;
     
                  write_1602com(0x0c);//不显示光标                           
                   write_1302(0x80,0x00);//禁止写保护
          write_1302(0x80,(second/10)<<4|second%10);//将调节后的秒写入DS1302
                   write_1302(0x82,(minute/10)<<4|minute%10);//将调节后的分写入DS1302
                   write_1302(0x84,(hour/10)<<4|hour%10);//将调节后的时写入DS1302
          write_1302(0x8a,(week/10)<<4|week%10);//将调节后的星期写入DS1302
                   write_1302(0x86,(day/10)<<4|day%10);//将调节后的日写入DS1302
                   write_1302(0x88,(month/10)<<4|month%10);//将调节后的月写入DS1302
          write_1302(0x8c,(year/10)<<4|year%10);//
         //write_1302(0x80,0x00);//时钟继续走这一句不能加在这,否则每次调 完时后秒会归O
      write_1302(0x8e,0x80);//写保护关
      //write_1602com(0x0c);
         break;
    }
   }
   }
   if(S1num!=0)
   {
     if(K1==0)
     {
      delay(5);
   while(!K1);
   switch(S1num)
   {
    case 1:
     second++;
     if(second==60)second=0;
     //write_1302(0x8e,0x00);//去除写保护
     write_second();
     write_1602com(0x80+0x40+10);
     break;
    case 2:
     minute++;
     if(minute==60)minute=0;
     write_minute();
     write_1602com(0x80+0x40+7);
     break;
    case 3:
     hour++;
     if(hour==24)hour=0;
     write_hour();
     write_1602com(0x80+0x40+4);
     break;
    case 4:
     day++;
     write_day();
     write_1602com(0x80+9);
     break;
      case 5:
     month++;
     write_month();
     write_1602com(0x80+6);
     break;
      case 6:
     year++;
     write_year();
     write_1602com(0x80+3);
     break;
      case 7:
     week++;
     write_week();
     write_1602com(0x80+12);
     break;
     // default:break;
      }
     }
     if(K2==0)
     {
      delay(5);
   while(!K2);
   switch(S1num)
   {
    case 1:
     second--;
     if(second<0)second=59;
     write_second();
     write_1602com(0x80+0x40+10);
     break;
    case 2:
     minute--;
     if(minute<0)minute=59;
     write_minute();
     write_1602com(0x80+0x40+7);
     break;
    case 3:
     hour--;
     if(hour<0)hour=23;
     write_hour();
     write_1602com(0x80+0x40+4);
     break;
    case 4:
     day--;
     write_day();
     write_1602com(0x80+9);
     break;
      case 5:
     month--;
     write_month();
     write_1602com(0x80+6);
     break;
      case 6:
     year--;
     write_year();
     write_1602com(0x80+3);
     break;
      case 7:
     week--;
     write_week();
     write_1602com(0x80+12);
     break;
    //  default:break;
   }
     }
   }
}

void main()
{
   delay(100);
   init1602();
   init_1302();
   while(1)
     {
   keyscan();
   if(keyflag==0)
   {
   readtime();
   write_second();
   write_minute();
   write_hour();
   write_day();
   write_month();
   write_year();
   write_week();
   }
  }
}

相关帖子

沙发
NE5532| | 2016-5-20 08:26 | 只看该作者
写成这个样子才来调试程序,神仙也救不了你。读“侃单片机”精华贴《程序调试黑宝书》

使用特权

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

本版积分规则

1

主题

1

帖子

0

粉丝