发新帖我要提问
12
返回列表
打印
[51单片机]

万年历程序,12864屏幕不显示

[复制链接]
楼主: fsi091347
手机看帖
扫描二维码
随时随地手机跟帖
21
651927693| | 2014-4-26 23:51 | 只看该作者 回帖奖励 |倒序浏览
读进去的时间?什么意思?

使用特权

评论回复
22
fsi091347|  楼主 | 2014-4-29 22:06 | 只看该作者
651927693 发表于 2014-4-26 23:51
读进去的时间?什么意思?

就是时间日期都没问题,现在是日期对不上星期了,无论日期多少号,都显示星期天了

使用特权

评论回复
23
651927693| | 2014-4-30 17:15 | 只看该作者
有没有是程序逻辑本身有问题,比如读到的时间是对的,但是显示的不对。
也有可能是芯片的问题。

使用特权

评论回复
24
fsi091347|  楼主 | 2014-5-1 23:27 | 只看该作者
651927693 发表于 2014-4-30 17:15
有没有是程序逻辑本身有问题,比如读到的时间是对的,但是显示的不对。
也有可能是芯片的问题。 ...
#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();
        
   }
}



你先看看程序,我不知道怎么调试程序了

使用特权

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

本版积分规则