找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1533|回复: 0
打印 上一主题 下一主题
收起左侧

请问如何将单片机万年历程序修改一下使LCD1602正确显示?

[复制链接]
跳转到指定楼层
楼主
新建 DOC 文档.doc (42.5 KB, 下载次数: 3)

请问如何将程序修改一下使LCD1602正确显示



发现下载附件要花费黑币,所以我把代码发出来吧

  1. /****************************main.c************************************/
  2. #include <reg51.h>
  3. #include <intrins.h>
  4. #include <string.h>

  5. #define uchar unsigned char
  6. #define uint unsigned int

  7. uchar *week[] = {"sun","mon","tus","wes","thu","fri","sat"}; //周信息,周一到周日。
  8. uchar lcd_buf1[] = "00-00-00   ";          //日期信息。
  9. uchar lcd_buf2[] = "00:00:00   ";          //时间信息。

  10. extern void InitTIMER0();
  11. extern void lcd_init();
  12. extern void lcd_showstring(uchar ,uchar ,uchar *);
  13. extern uchar l_tmpdate[7];
  14. extern bit ReadRTC_Flag;
  15. extern void delay(uint i);
  16. extern void Read_RTC();                          
  17. extern void Set_RTC();

  18. //将日期和时间信息转化为数字字符。
  19. void format_datetime(uint d,uchar * a)
  20. {
  21.         *a=(d>>4)+'0';
  22.         *(a+1)=(d&0x0f)+'0';
  23. }

  24. void main()
  25. {
  26.         lcd_init();          //LCD的初始化。
  27.         InitTIMER0(); //初始化定时器0。
  28.         Set_RTC();        //写入时钟值(写入时钟初值),如果不用改时间可以不用这一项。

  29.         while(1)
  30.         {
  31.                 if(ReadRTC_Flag)
  32.                 {
  33.                         ReadRTC_Flag = 0;
  34.                         Read_RTC();
  35.         
  36.                         //日期转换。
  37.                         format_datetime(l_tmpdate[6],lcd_buf1+5);
  38.                         format_datetime(l_tmpdate[4],lcd_buf1+8);
  39.                         format_datetime(l_tmpdate[3],lcd_buf1+11);
  40.                         //星期转换。
  41.                         strcpy(lcd_buf1 + 13,week[l_tmpdate[5]-1]);
  42.                         //定义一个字符串char a[20],和一个字符串c[]="i am a teacher!";
  43.                         //把c复制到a中就可以这样用:strcpy(a,c);
  44.         
  45.                         //时间转换。
  46.                         format_datetime(l_tmpdate[2],lcd_buf2+5);
  47.                         format_datetime(l_tmpdate[1],lcd_buf2+8);
  48.                         format_datetime(l_tmpdate[0],lcd_buf2+11);
  49.         
  50.                         lcd_showstring(0,0,lcd_buf1);                 //将lcd_buf1和lcd_buf2字符输出。
  51.                         lcd_showstring(1,0,lcd_buf2);

  52.                 }
  53.         }
  54. }


  55. /******************************************************************1602.h**************************************************************************/
  56. typedef bit bool;

  57. sbit RS = P2^6;           //复位端
  58. sbit RW = P2^5;           //写数据端
  59. sbit EN = P2^7;           //使能端

  60. #define uint unsigned int
  61. #define uchar unsigned char

  62. void delay(int i);
  63. bit lcd_bz();
  64. void lcd_wcmd(int cmd);
  65. void lcd_showstring(uchar r,uchar c,uchar *str);
  66. void lcd_wdat(uchar dat);
  67. void lcd_init();

  68. /******************************************************************1602.c***************************************************************************/
  69. #include <reg51.h>
  70. #include <intrins.h>
  71. #include "1602.h"

  72. //延时函数
  73. void delay(int i)
  74. {
  75.         int j;
  76.         while(i--)
  77.         {
  78.                 for(j=0;j<250;j++)
  79.                 {
  80.                         _nop_();
  81.                         _nop_();
  82.                         _nop_();
  83.                         _nop_();
  84.                 }
  85.         }
  86. }

  87. //侧忙,判断LCD是否为忙
  88. bool lcd_bz()
  89. {
  90.         bool result;
  91.         RS = 0;
  92.         RW = 1;
  93.         EN = 1;
  94.         _nop_();
  95.         _nop_();
  96.         _nop_();
  97.         _nop_();
  98.         result = (bool)(P0 & 0x80);//检测P0最高位是否为1.
  99.         EN = 0;
  100.         return result;        //返回判断的结果。        
  101. }

  102. //写命令函数。
  103. void lcd_wcmd_8bit(int cmd)
  104. {
  105.         while(lcd_bz());
  106.         RS = 0;
  107.         RW = 0;
  108.         EN = 0;                //先为低电平。
  109.         _nop_();
  110.         _nop_();
  111.         P0 = cmd;         //获得数据。
  112.         _nop_();
  113.         _nop_();
  114.         _nop_();
  115.         _nop_();
  116.         EN = 1;                 //将电平拉高。
  117.         _nop_();
  118.         _nop_();
  119.         _nop_();
  120.         _nop_();
  121.         EN = 0;                 //再拉低。
  122. }  

  123. //写命令函数。
  124. void lcd_wcmd(int cmd)
  125. {
  126.         while(lcd_bz());
  127.         RS = 0;
  128.         RW = 0;
  129.         EN = 0;           //先为低电平。
  130.         _nop_();
  131.         _nop_();
  132.         P0 = cmd;        //获得高四位数据。
  133.         _nop_();
  134.         _nop_();
  135.         _nop_();
  136.         _nop_();
  137.         EN = 1;                //拉高。
  138.         _nop_();
  139.         _nop_();
  140.         _nop_();
  141.         _nop_();
  142.         EN = 0;                //再拉低。

  143.         P0 = (cmd & 0x0f)<<4;  //再获得低四位数据。
  144.         _nop_();
  145.         _nop_();
  146.         _nop_();
  147.         _nop_();
  148.         EN = 1;                 //将电平拉高。
  149.         _nop_();
  150.         _nop_();
  151.         _nop_();
  152.         _nop_();
  153.         EN = 0;                  //再拉低。
  154. }


  155. void lcd_showstring(uchar r,uchar c,uchar *str)
  156. {
  157.         uchar i=0;
  158.         code uchar DDRAM[] = {0x80,0xc0};         //设定显示的位置。
  159.         lcd_wcmd(DDRAM[r] | c);
  160.         for(i=0;str[i] && i<16;i++)
  161.                 lcd_wdat(str[i]);
  162.         for(;i<16;i++)
  163.                 lcd_wdat(' ');
  164. }

  165. //数据写入的函数。
  166. void lcd_wdat(uchar dat)
  167. {
  168.         while(lcd_bz());
  169.         RS = 1;
  170.         RW = 0;
  171.         EN = 0;                //先处于低电平。
  172.         P0 = dat;         //获得数据高四位。
  173.         _nop_();
  174.         _nop_();
  175.         _nop_();
  176.         _nop_();
  177.         EN = 1;
  178.         _nop_();
  179.         _nop_();          //再产生一个负脉冲。
  180.         _nop_();
  181.         _nop_();
  182.         EN = 0;

  183.         RS = 1;
  184.         RW = 0;
  185.         EN = 0;
  186.         _nop_();
  187.         _nop_();
  188.         _nop_();
  189.         _nop_();
  190.         P0 = (dat & 0x0f)<<4;        //同理获得低四位。
  191.         _nop_();
  192.         _nop_();
  193.         _nop_();
  194.         _nop_();
  195.         EN = 1;
  196.         _nop_();
  197.         _nop_();
  198.         _nop_();
  199.         _nop_();
  200.         EN = 0;
  201. }

  202. //LCD初始化。
  203. void lcd_init()
  204. {
  205.         lcd_wcmd_8bit(0x38);
  206.         delay(1);
  207.         lcd_wcmd_8bit(0x38);
  208.         delay(1);
  209.         lcd_wcmd_8bit(0x38);
  210.         delay(1);
  211.         lcd_wcmd(0x38);
  212.         delay(1);
  213.         lcd_wcmd(0x0c);
  214.         delay(1);
  215.         lcd_wcmd(0x02);
  216.         delay(1);
  217.         lcd_wcmd(0x01);
  218.         delay(1);
  219. }

  220. /****************************************************************ds1302.c****************************************************/
  221. #include <reg52.h>
  222. #include <intrins.h>

  223. sbit SCK = P3^6;  //时钟线
  224. sbit IO = P3^4;          //数据线
  225. sbit RST = P3^5;  //DS1302复位线

  226. bit ReadRTC_Flag; //读DS1302的标志

  227. #define uint unsigned int
  228. #define uchar unsigned char

  229. //七项数据:秒分时日月周年
  230. uchar l_tmpdate[7] = {0,0,12,19,11,5,1};
  231. //用来存放转化好的时间数据
  232. uchar l_tmpdisplay[8];

  233. //7个数据的写地址
  234. code uchar write_rtc_add[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
  235. //7个数据的读地址
  236. code uchar read_rtc_add[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};

  237. //函数的声明
  238. void Write_Ds1302_byte(uchar temp);
  239. void write_Ds1302(uchar add,uchar dat);
  240. uchar Read_Ds1302(uchar add);
  241. void Read_RTC();
  242. void Set_RTC();
  243. void InitTIMER0();

  244. //定时器的初始化
  245. void InitTIMER0()
  246. {
  247.         TMOD |= 0x01;
  248.         TH0 = 0xef;
  249.         TL0 = 0xf0;
  250.         ET0 = 1;
  251.         TR0 = 1;
  252.         EA = 1;
  253. }

  254. //向1302中发送一个字节数据。
  255. void Write_Ds1302_Byte(uchar temp)
  256. {
  257.         uchar i;
  258.         for(i=0;i<8;i++)  //循环8位依次写入数据
  259.         {
  260.                 SCK = 0;
  261.                 IO = temp & 0x01;        //传输时从低到高
  262.                 temp>>=1;          //右移1位。
  263.                 SCK = 1;

  264.         }
  265. }

  266. //向1302中写入数据。参数有要写入的地址和数据
  267. void Write_Ds1302(uchar add,uchar dat)
  268. {
  269.         RST = 0;
  270.         _nop_();
  271.         SCK = 0;
  272.         _nop_();
  273.         RST = 1;
  274.         _nop_();
  275.         Write_Ds1302_Byte(add);        //发送地址
  276.         Write_Ds1302_Byte(dat);        //发送数据
  277.         RST = 0;
  278. }

  279. //从1302中的读出数据
  280. uchar Read_Ds1302(uchar add)
  281. {
  282.         uchar i,temp=0x00;
  283.         RST = 0;
  284.         _nop_();
  285.         _nop_();
  286.         SCK = 0;
  287.         _nop_();
  288.         _nop_();
  289.         RST = 1;
  290.         _nop_();
  291.         _nop_();
  292.         Write_Ds1302_Byte(add);         //发送地址,找到地址
  293.         for(i=0;i<8;i++)   //循环8次读出数据
  294.         {
  295.                 if(IO)                //传输从低到高
  296.                         temp |= 0x80;
  297.                 SCK = 0;
  298.                 temp>>=1;        //右移1位
  299.                 _nop_();
  300.                 _nop_();
  301.                 _nop_();
  302.                 SCK = 1;
  303.         }
  304.         RST = 0;                        //之后为DS1302复位
  305.         _nop_();
  306.         _nop_();
  307. //        RST = 0;    //试验时去掉该句没有影响
  308.         SCK = 0;
  309.         _nop_();
  310.         _nop_();
  311.         _nop_();
  312.         _nop_();
  313.         SCK = 1;
  314.         _nop_();
  315.         _nop_();
  316.         IO = 0;
  317.         _nop_();
  318.         _nop_();
  319.         IO = 1;
  320.         _nop_();
  321.         _nop_();
  322.         return temp;        //将读到的数据返回
  323. }

  324. //从时钟中读取数据
  325. void Read_RTC()
  326. {
  327.         uchar i,*p;
  328.         p = read_rtc_add;  //读日历数据对应的地址
  329.         for(i=0;i<7;i++)        //分7次分别将:时分秒日月周年读出
  330.         {
  331.                 l_tmpdate[i] = Read_Ds1302(*p);
  332.                 p++;
  333.         }
  334. }

  335. //设定时钟的时间数据
  336. void Set_RTC()
  337. {
  338.         uchar i,*p,tmp;
  339.         for(i=0;i<7;i++)   //将数从BCD码转化出来,因为1302中用BCD码表示数值
  340.         {
  341.                 tmp = l_tmpdate[i]/10;
  342.                 l_tmpdate[i] = l_tmpdate[i]%10;
  343.                 l_tmpdate[i] = l_tmpdate[i] + tmp*16;
  344.         }

  345.         Write_Ds1302(0x8e,0x00);  //清除写入保护

  346.         p = write_rtc_add;                //传送地址
  347.         for(i=0;i<7;i++)                //将数据依次写入
  348.         {
  349.                 Write_Ds1302(*p,l_tmpdate[i]);
  350.                 p++;
  351.         }

  352.         Write_Ds1302(0x8e,0x80);  //打开写入保护,不能再写入
  353. }


  354. //定时器中断函数
  355. void tim() interrupt 1 using 1
  356. {
  357.         static uchar i,num;
  358.         TH0 = 0xf5;
  359.         TL0 = 0xe0;

  360.         i++;

  361.         if(i==8)
  362.         {
  363.                 i=0;
  364.                 num++;
  365.                 if(10==num)                  //间隔一定时间读取1302中数据,更新数码管数据
  366.                 {
  367.                         ReadRTC_Flag = 1;         //置标志位,从而进行判断
  368.                         num = 0;
  369.                 }
  370.         }
  371. }
复制代码
求大佬解答。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表