[51单片机] 万年历程序,12864屏幕不显示

[复制链接]
4449|23
651927693 发表于 2014-4-26 23:51 | 显示全部楼层
读进去的时间?什么意思?
 楼主| fsi091347 发表于 2014-4-29 22:06 | 显示全部楼层
651927693 发表于 2014-4-26 23:51
读进去的时间?什么意思?

就是时间日期都没问题,现在是日期对不上星期了,无论日期多少号,都显示星期天了
651927693 发表于 2014-4-30 17:15 | 显示全部楼层
有没有是程序逻辑本身有问题,比如读到的时间是对的,但是显示的不对。
也有可能是芯片的问题。
 楼主| fsi091347 发表于 2014-5-1 23:27 | 显示全部楼层
651927693 发表于 2014-4-30 17:15
有没有是程序逻辑本身有问题,比如读到的时间是对的,但是显示的不对。
也有可能是芯片的问题。 ...
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<string.h>  //字符串操作函数
  4. //宏定义
  5. #define uchar unsigned char
  6. #define uint unsigned char

  7. //定义全局变量
  8. #define lcddata P2  //液晶8位并口数据
  9. uchar hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;

  10. sbit lcd_rs=P0^7;
  11. sbit lcd_rw=P0^6;
  12. sbit lcd_e=P0^5;
  13. sbit lcd_psw=P0^4;
  14. sbit lcd_rst=P0^3;
  15. uchar week_value[3];

  16. sbit DS1302_RST=P1^0;
  17. sbit DS1302_SCLK=P1^2;
  18. sbit DS1302_DATA=P1^1;

  19. void show_all();//定义特殊位

  20. void delaynms(uint aa)
  21. {
  22.   uchar bb;
  23.   while(aa--)
  24.   {
  25.    for(bb=0;bb<115;bb++)   //1ms基准延时程序
  26.    {
  27.     ;
  28.    }
  29.   }
  30. }

  31. void chkbusy_lcd(void)
  32. {
  33.   lcddata=0xff;              //把忙碌标志位BF置1
  34.   lcd_rs=0;      //指令操作
  35.   lcd_rw=1;      //读操作
  36.   lcd_e=1;      //拉高使能,读取数据
  37.   _nop_();    //判断忙碌位是否为0,若果为1,液晶忙,一直等待(BF=1,状态忙)
  38.   lcd_e=0;      //拉低使能
  39. }

  40. void wr_lcd(uchar dat_comm,uchar content)
  41. {
  42.   chkbusy_lcd();
  43.   if(dat_comm==1)
  44.   {
  45.    lcd_rs=1;   //data
  46. lcd_rw=0;   //write
  47.   }
  48.   else
  49.   {
  50.    lcd_rs=0;   //command
  51. lcd_rw=0;   //write
  52.   }
  53.   lcd_e=1;    //拉高使能
  54.   lcddata=content;//放上数据
  55.   _nop_();    //等待
  56.   lcd_e=0;    //拉低使能,使数据写入
  57. }

  58. void init_lcd(void)
  59. {
  60.    wr_lcd(0,0x30);  //基本指令集
  61.    delaynms(1);   //等待
  62.    wr_lcd(0,0x30);  //再设置一次为基本指令集,因为ST7920中有2个寄存器用来设置使用哪个指令集
  63.    delaynms(1);   //等待
  64.    wr_lcd(0,0x0c);  //开显示,关游标,关游标位置
  65.    delaynms(1);   //等待
  66.    wr_lcd(0,0x01);  //清屏,地址指针指向00H
  67.    delaynms(20);   //等待>10ms
  68.    wr_lcd(0,0x06);  //光标右移,整体不移
  69. }


  70. void lcd_clr(void)
  71. {
  72.   wr_lcd(0,0x30);        //基本指令集
  73.   wr_lcd(0,0x01);   //清除显示
  74.   delaynms(1);
  75. }

  76. void gotoxy(unsigned char y, unsigned char x)
  77. {
  78. if(y==1)
  79. wr_lcd(0,0x80|x);    //Line 1
  80. if(y==2)
  81.     wr_lcd(0,0x90|x);    //Line 2
  82. if(y==3)
  83. wr_lcd(0,((0x80|x)+8));   //Line 3
  84. if(y==4)
  85.     wr_lcd(0,((0x90|x)+8));   //Line 4
  86. }

  87. void print(uchar *str)
  88. {
  89.   while(*str!='\0')    //检查是否到字符串尾
  90.   {
  91.    wr_lcd(1,*str++);    //输入*str后str++
  92.   }
  93. }

  94. void DS1302InputByte(uchar d)
  95. {
  96.    uchar i;      
  97.    DS1302_SCLK=0;    //拉低SCLK,为上升沿写入数据做好准备
  98.    for(i=0;i<8;i++)    //连续写入8个二进制数据
  99.    {
  100.      DS1302_DATA=d&0x01;  //取出d的第0位,写入1302,  低位在前,高位在后
  101.   _nop_();     //等待
  102.   DS1302_SCLK=1;    // 拉高SCLK,上升沿写入数据
  103.   _nop_();     // 等待
  104.   DS1302_SCLK=0;    //拉低SCLK形成脉冲
  105.   d>>=1;      //将d的数据向右移一位,准备写入下一个二进制数据
  106.    }
  107. }

  108. uchar DS1302OutputByte(void)
  109. {
  110.   uchar i;
  111.   uchar dat;
  112.   for(i=0;i<8;i++)   //连续读出8个二进制数
  113.   {
  114.    dat>>=1;    //向右移一位
  115. if(DS1302_DATA==1)  //如果读出数据是1,(上一个写入控制字结束后,保存一个读出数据)
  116. {
  117.    dat|=0x80;
  118. }
  119. DS1302_SCLK=1;   //拉高SCLK
  120. _nop_();
  121. DS1302_SCLK=0;   //拉低SCLK,读取数据
  122.   }
  123.   return dat;       //将读出的数据返回
  124. }
  125. void Write1302(uchar ADDRorCOMM,uchar DATA)
  126. {
  127. DS1302_RST=0;   //禁止数据传输
  128. DS1302_SCLK=0;   //确保写写之前SCLK被拉低
  129.     DS1302_RST=1;   //启动数据传输
  130. DS1302InputByte(ADDRorCOMM); //写入命令或地址
  131. DS1302InputByte(DATA);   //
  132. DS1302_SCLK=1;   //将时钟电平置于高电平状态 $$ 置高是为了让下次写的时候 能准确的被拉低 保证电平
  133. //状态的正确性
  134. DS1302_RST=0;   //禁止数据传输
  135. }

  136. uchar Read1302(uchar ADDRorCOMM)
  137. {
  138.     uchar dat;
  139. DS1302_RST=0;   //禁止数据传输
  140. DS1302_SCLK=0;   //确保写写之前SCLK被拉低
  141.     DS1302_RST=1;   //启动数据传输
  142. DS1302InputByte(ADDRorCOMM); //写入命令或地址
  143. dat=DS1302OutputByte();   // 读出数据
  144. DS1302_SCLK=1;   //将时钟电平置于高电平状态置高是为了让下次写的时候 能准确的被拉低 保证电平
  145. //状态的正确性
  146. DS1302_RST=0;   //禁止数据传输
  147. return(dat);
  148. }


  149. void Init_1302(void)    //(2008年7月12日12时00分00秒星期六)
  150. {
  151.   uchar flag;
  152.   flag=Read1302(0x81);    //读秒寄存器
  153.   if(flag&0x80)         //CH为0(flag最高位是0),时钟走动,不用初始化 。
  154.   {
  155.    Write1302(0x8e,0x00);  //允许写操作
  156. Write1302(0x8c,((14/10)<<4|(14%10)));  //YEAR
  157. Write1302(0x8a,0x01);  //DAY
  158. Write1302(0x88,((4/10)<<4|(4%10)));  //MONTH
  159. Write1302(0x86,((29/10)<<4|(29%10)));  //DATE
  160. Write1302(0x84,((11/10)<<4|(11%10)));  //HR
  161. Write1302(0x82,((0/10)<<4|(7%10)));  //MIN
  162. Write1302(0x80,((0/10)<<4|(0%10)));  //SEC
  163. Write1302(0x90,0xa5);  //打开充电功能
  164. Write1302(0x8e,0x80);  //禁止写操作
  165.   }
  166. }

  167. typedef struct _SYSTEMTIME_
  168. {
  169.   uchar Second;
  170.   uchar Minute;
  171.   uchar Hour;
  172.   uchar Week;
  173.   uchar Day;
  174.   uchar Month;
  175.   uchar Year;
  176.   uchar DateString[11];
  177.   uchar TimeString[9];
  178. }SYSTEMTIME;
  179. SYSTEMTIME CurrentTime;

  180. void DS1302_GetTime(SYSTEMTIME *Time)
  181. {
  182.   uchar ReadValue;
  183.   ReadValue=Read1302(0x81);                           //从秒寄存器里读数据
  184.   Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f);  //把读出的数据转换成BCD码
  185.   ReadValue=Read1302(0x83);                           //从分寄存器里读数据
  186.   Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f);  //把读出的数据转换成BCD码
  187.   ReadValue=Read1302(0x85);                           //从小时寄存器里读数据
  188.   Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f);  //把读出的数据转换成BCD码
  189.   ReadValue=Read1302(0x8b);                           //从星期寄存器里读数据
  190.   Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f);  //把读出的数据转换成BCD码
  191.   ReadValue=Read1302(0x87);                           //从日寄存器里读数据
  192.   Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f);  //把读出的数据转换成BCD码
  193.   ReadValue=Read1302(0x89);                           //从月寄存器里读数据
  194.   Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0f);  //把读出的数据转换成BCD码
  195.   ReadValue=Read1302(0x8d);                           //从年寄存器里读数据
  196.   Time->Year=((ReadValue&0xf0)>>4)*10+(ReadValue&0x0f);  //把读出的数据转换成BCD码  //注意是0xF0
  197. }

  198. void Date2Str(SYSTEMTIME *Time)
  199. {
  200. //    uchar tab[]={0xc8,0xd5,0xbb6,0xfe,0xc8,0xfd,0xcb,0xc4,0xce,0xe5,0xc1,0xf9,0xd2,0xbb};
  201.       uchar tab[]={"一二三四五六日"};


  202.   if(hide_year<2)  ////这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,
  203.   {
  204.    Time->DateString[0]='2';
  205. Time->DateString[1]='0';
  206. Time->DateString[2]=Time->Year/10+'0';
  207. Time->DateString[3]=Time->Year%10+'0';
  208.   }
  209.   else
  210.   {
  211.     Time->DateString[0]=' ';
  212. Time->DateString[1]=' ';
  213. Time->DateString[2]=' ';
  214. Time->DateString[3]=' ';
  215.   }
  216.   Time->DateString[4]='-';
  217.   if(hide_month<2)
  218.   {
  219.    Time->DateString[5]=Time->Month/10+'0';
  220. Time->DateString[6]=Time->Month%10+'0';
  221.   }
  222.   else
  223.   {
  224.    Time->DateString[5]=' ';
  225. Time->DateString[6]=' ';
  226.   }
  227.   Time->DateString[7]='-';
  228.   if(hide_day<2)
  229.   {
  230.    Time->DateString[8]=Time->Day/10+'0';
  231. Time->DateString[9]=Time->Day%10+'0';
  232.   }
  233.   else
  234.   {
  235.    Time->DateString[8]=' ';
  236. Time->DateString[9]=' ';
  237.   }
  238.   if(hide_week<2)
  239.   {
  240.      
  241.          week_value[0]=tab[2*(Time->Week%10)-2];  //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示
  242.     week_value[1]=tab[2*(Time->Week%10)-1];
  243.   }
  244.   else
  245.   {
  246.    week_value[0]=' ';
  247. week_value[1]=' ';
  248.   }
  249.   week_value[2]='\0';
  250.   Time->DateString[10]='\0';   //字符串末尾加 '\0' ,判断结束字符
  251. }

  252. void Time2Str(SYSTEMTIME *Time)
  253. {
  254.   if(hide_hour<2)
  255.   {
  256.    Time->TimeString[0]=Time->Hour/10+'0';
  257. Time->TimeString[1]=Time->Hour%10+'0';
  258.   }
  259.   else
  260.   {
  261.    Time->TimeString[0]=' ';
  262. Time->TimeString[1]=' ';
  263.   }
  264.   Time->TimeString[2]=':';
  265.   if(hide_min<2)
  266.   {
  267.    Time->TimeString[3]=Time->Minute/10+'0';
  268. Time->TimeString[4]=Time->Minute%10+'0';
  269.   }
  270.   else
  271.   {
  272.    Time->TimeString[3]=' ';
  273. Time->TimeString[4]=' ';
  274.   }
  275.   Time->TimeString[5]=':';
  276.   if(hide_sec<2)
  277.   {
  278.    Time->TimeString[6]=Time->Second/10+'0';
  279. Time->TimeString[7]=Time->Second%10+'0';
  280.   }
  281.   else
  282.   {
  283.    Time->TimeString[6]=' ';
  284. Time->TimeString[7]=' ';
  285.   }
  286.   Time->TimeString[8]='\0';
  287. }


  288. //********************************************************************************************
  289. //
  290. //   液晶显示主程序模块
  291. //*********************************************************************************************
  292. void show_all(void)
  293. {
  294.   DS1302_GetTime(&CurrentTime);  //获取时钟芯片数据
  295.   Time2Str(&CurrentTime);      //日期数据转化为液晶字符,放在TimeString[9]里,“12:00:00”
  296.   Date2Str(&CurrentTime);        //时间数据转化为液晶字符,放在DateString[11]里,“2008-07-12”
  297.                                  //星期数据放在week_value[3]里
  298.   gotoxy(1,0);      //第一行显示
  299.   print("【xx的万年历】");
  300.   gotoxy(2,0);      //
  301.   print(CurrentTime.DateString);
  302.   gotoxy(2,5);      //
  303.   print("星期");
  304.   gotoxy(2,7);
  305.   print(week_value);
  306.   gotoxy(3,0);      //
  307.   print("时间:");
  308.   gotoxy(3,3);      //
  309.   print(CurrentTime.TimeString);
  310.   gotoxy(4,0);      //
  311.   print("制作");
  312. //  gotoxy(4,2);      //
  313. //  print(TempBuffer);
  314. //    gotoxy(4,6);
  315. //  print("℃");
  316.   delaynms(500);     //扫描延时

  317. }

  318. void main(void)
  319. {  
  320.         Init_1302();         
  321.         while(1)
  322.    {
  323.    init_lcd();          //液晶初始化
  324.    lcd_clr();           //清屏

  325.     show_all();
  326.         
  327.    }
  328. }



你先看看程序,我不知道怎么调试程序了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部