找回密码
 立即注册

QQ登录

只需一步,快速开始

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

ds1302时钟数码管数字显示的很乱 怎么办 程序也没有错误

[复制链接]
跳转到指定楼层
楼主
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define MAIN_Fosc    11059200UL

  4. /*自定义类型明*/
  5. typedef unsigned char INT8U;
  6. typedef unsigned char uchar;

  7. typedef unsigned int INT16U;
  8. typedef unsigned int uint;
  9. /*声明硬件的接口*/
  10. sbit TSCLK = P1^0;//时钟线
  11. sbit TIO = P1^1;  //数据线
  12. sbit TRST = P1^2; //使能端

  13. sbit DU = P2^6;//段选
  14. sbit WE = P2^7;//位选
  15. /*共阳极数码管段选码*/
  16. uchar code table[]={
  17. //         0                1           2          3                  4                5
  18.         0xc0,  0xf9,  0xa4,  0xb0,  0x99,  0x92,  
  19. //         6                 7                8           9          .                 关显示
  20.     0x82,  0xf8,  0x80,  0x90,  0x7f,   0xff
  21. };
  22. /*位选码*/
  23. uchar code T_COM[] = {
  24. //1      2     3       4     5      6
  25. 0x01,  0x02,  0x04,  0x08,  0x10,  0x20
  26. };
  27. /*延时函数*/
  28. void Delay_Ms(INT16U ms)
  29. {
  30.   INT16U i;
  31.   do{
  32.             i = MAIN_Fosc/96000;
  33.           while(--i);
  34.     }while(--ms);
  35. }
  36. /*显示函数*/
  37. void Display(uchar Hour,Min,Sec)
  38. {
  39.    //第一位数码管 小时十位
  40.    DU = 0;
  41.    P0 = table[Hour/10];
  42.    DU = 1;
  43.    DU = 0;

  44.    WE = 0;
  45.    P0 = T_COM[0];
  46.    WE = 1;
  47.    WE = 0;
  48.    Delay_Ms(3);
  49.    //第二位数码管 小时个位
  50.    DU = 0;
  51.    P0 = table[Hour%10] | 0x7f;// 0111 1111 显示小数点
  52.    DU = 1;
  53.    DU = 0;

  54.    WE = 0;
  55.    P0 = T_COM[1];
  56.    WE = 1;
  57.    WE = 0;
  58.    Delay_Ms(3);
  59.    //第三位数码管
  60.    DU = 0;
  61.    P0 = table[Min/10];
  62.    DU = 1;
  63.    DU = 0;

  64.    WE = 0;
  65.    P0 = T_COM[2];
  66.    WE = 1;
  67.    WE = 0;
  68.    Delay_Ms(3);
  69.    //第四位数码管
  70.    DU = 0;
  71.    P0 = table[Min%10] | 0x7f;
  72.    DU = 1;
  73.    DU = 0;

  74.    WE = 0;
  75.    P0 = T_COM[3];
  76.    WE = 1;
  77.    WE = 0;
  78.    Delay_Ms(3);
  79.    //第五位数码管
  80.    DU = 0;
  81.    P0 = table[Sec/10];
  82.    DU = 1;
  83.    DU = 0;
  84.    
  85.    WE = 0;
  86.    P0 = T_COM[4];
  87.    WE = 1;
  88.    WE = 0;
  89.    Delay_Ms(3);
  90.    //第六位数码管
  91.    DU = 0;
  92.    P0 = table[Sec%10];
  93.    DU = 1;
  94.    DU = 0;

  95.    WE = 0;
  96.    P0 = T_COM[5];
  97.    WE = 1;
  98.    WE = 0;
  99.    Delay_Ms(3);
  100. }
  101. //写DS1302
  102. void Writer_DS1302_DAT(uchar cmd,uchar dat)         //命令和数据需要给出
  103. {
  104.     uchar i;
  105.         TRST = 0;
  106.         TSCLK = 0;
  107.         TRST = 1;
  108.         for(i = 0; i < 8; i++)
  109.           {
  110.             TSCLK = 0;
  111.                 TIO = cmd & 0x01;
  112.                 TSCLK = 1;//拉高时钟总线接收数据
  113.             dat >>= 1;//右移一位 往最低位移 左移往最高位移          从低位开始发送 需右移 把八位数据出  从高位发送需左移
  114.       }
  115.    for(i = 0; i < 8; i++)
  116.       {
  117.          TSCLK = 0;
  118.                  TIO  = dat & 0x01;
  119.                  TSCLK = 1;
  120.                  dat >>= 1;  
  121.       }
  122. }
  123. //读DS1302数据
  124. uchar Read_DS1302_DAT(uchar cmd)
  125. {
  126.    uchar i, dat;
  127.    TRST = 0;
  128.    TSCLK = 0;
  129.    TRST = 1;
  130.    for(i = 0;i < 8; i++)// 写入命令
  131.    {
  132.                TSCLK = 0;
  133.                 TIO = cmd & 0x01;
  134.                 TSCLK = 1;
  135.                 dat >>= 1; //
  136.    }
  137.    for(i = 0; i < 8 ; i++)// 读八次
  138.    {
  139.        TSCLK  = 0;
  140.            dat >>= 1;
  141.            if(TIO) dat |= 0x80;
  142.            TSCLK = 1;
  143.         }
  144.         return dat;
  145. }

  146. //数据转BCD
  147. uchar Dat_Chg_BCD(uchar dat)
  148. {
  149.      uchar dat1,dat2;
  150.          dat1 = dat / 10;
  151.          dat2 = dat % 10;
  152.          dat2 = dat2 + dat1 * 16;
  153.          return dat2;
  154. }

  155. //BCD转数据
  156. uchar BCD_Chg_Dat(uchar dat)
  157. {
  158.     uchar dat1,dat2;
  159.         dat1 = dat / 16;
  160.         dat2 = dat % 16;
  161.         dat2 = dat2 + dat1 * 10;
  162.         return dat2;
  163. }
  164. void main()
  165. {
  166.    uchar i;
  167.    uchar Sec,Min,Hour;
  168.    Writer_DS1302_DAT(0x8e, 0);
  169.    Writer_DS1302_DAT(0x80,Dat_Chg_BCD(30));
  170.    Writer_DS1302_DAT(0x82,Dat_Chg_BCD(15));
  171.    Writer_DS1302_DAT(0x84,Dat_Chg_BCD(19));
  172.    Writer_DS1302_DAT(0x8e,0x80);
  173.    while(1)
  174.    {
  175.      Writer_DS1302_DAT(0x8e,0);
  176.          Sec = BCD_Chg_Dat(Read_DS1302_DAT(0x81));
  177.          Min = BCD_Chg_Dat(Read_DS1302_DAT(0x83));
  178.          Hour = BCD_Chg_Dat(Read_DS1302_DAT(0x85));
  179.          Writer_DS1302_DAT(0x8e,0x80);
  180.          for(i = 0;i < 50; i++)
  181.          {
  182.             Display(Hour,Min,Sec);
  183.          }
  184.      }
  185. }
复制代码

为什么仿真的时候 数码管显示数字很乱

捕获3.PNG (59.75 KB, 下载次数: 46)

捕获3.PNG
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111634 发表于 2018-7-30 20:53 | 只看该作者
本帖最后由 zl2168 于 2018-7-31 09:49 编辑

实例94  模拟电子钟(由80C51定时器产生秒时基)
Proteus仿真一下,确认有效。
实例94 模拟电子钟(由80C51定时器产生秒时基).rar (43.05 KB, 下载次数: 6)

以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行。书中电路和程序设计有详细说明,程序语句条条有注解。
回复

使用道具 举报

板凳
ID:380969 发表于 2018-7-31 00:59 | 只看该作者
位选码和段选码和延迟
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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