数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 3806|回复: 12

[C51] 求助:DS18B20+ DS12c8878位共阳数码管万年历代码更改

[复制链接]
发表于 2020-8-18 10:16:47 | 显示全部楼层 |阅读模式
原文是DS18B20+ DS12c8878位共阳数码管万年历加温度的代码我现在要改为DS12c887共阴极8位数码管万年历不用显示温度部分,经过几天的更改大部分更改,但是还有一些自己水平有限,已经没有能力了,特来这里求助。先谢谢啦!
主要问题是:1、根据自己的电路共阳极数码管转换为共阴极数码管,p端口更改后显示代码的更改。p2口段码的代码更改了,p1口位置码我怎么看都好像是共阴极数码管的,不知道对不对没有更改。
2、就是DS12c8878初始化的代码要删除,不知道我删除的对不对。
3、DS18B20温度部分代码删除的对不对。
我自己的电路

我自更改后的代码:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar hh,mm,ss,year,mouth,day,dd,week,aa,x,y,flag;
uint temp;
uchar code  led[14]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xbf,0x7f,0x00,0x39};//
这两个没有改(0xbf  - ,0x7f  _,
uchar
code led1[11]={ 0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0x00,0xef,0xa3};
//加了小数点最后一位没有改(0xa3  o)
sbit key1=P3^5;    key1
键调整时间时的选择功能
sbit key2=P3^6; key2
执行加功能
sbit key3=P3^7; key3
执行减功能
sbit DS_CS=P3^3; //定义DS12C887芯片片选端          (读哪个芯片)
sbit DS_AS=P3^2;
//定义DS12C887地址选通输入端 (读到那里去)
sbit DS_RW=P3^1;
//定义DS12C887读允许输入      (让读以后,我来输入数据)
sbit DS_DS=P3^0; //定义DS12C887读数据允许输入脚,这里mot接地
#define DS_BUS P0  //DS12CR887
数据总线(端口已改)
//
DS12CR887写数据函数
void ds_write(uchar add,uchar date)
{
DS_CS=0;
//根据时序图,把相应的脚变化高低,片选端,低电平有效
DS_AS=1;
//地址选通输入端
DS_DS=1;
//读允许输入脚
DS_RW=1;
//写输入脚
DS_BUS=add;
//写地址
DS_AS=0;
DS_RW=0;
DS_BUS=date;
//写命令
DS_RW=1;
DS_AS=1;
DS_CS=1;
}
//
读取DS12CR887的数据
uchar ds_read(uchar add)
{
uchar z;  
//定义一个无符号函数
DS_AS=1; //ALE,
地址锁存允许//根据时序图,进行高低电平设置
DS_DS=1; //Read
读入
DS_RW=1; //!WR
禁止写入
DS_CS=0; //
片选输入
DS_BUS=add;
//写地址,确定要读什么位置的值
DS_AS=0;
DS_DS=0;
DS_BUS=0x00;
//先把P1进行置高,清理数据
z=DS_BUS;
//把新的得到了  12c887里面的数值,赋值给ds_bus
DS_DS=1;  //根据时序图继续设置电平
DS_AS=1;
DS_CS=1;
return z;
//谁调用它,什么位置调用的,就会把这个新得到的值在返回给他,//看得出来只有读闹钟值是调用了。
}

void delay(uint z) //
延时
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=10;y>0;y--);
}

//DS12CR887初始化 根据需要修改,第一次用的时候写进去,以后就不用了

void ds_init()
{
DS_AS=0;
DS_DS=0;
DS_RW=0;
ds_write(0x0a,0x20);//DS12CR887寄存器A功能设置,开启时钟振荡器

}

void time_init()
{
ds_init();     //初始化DS12CR887
ds_write(0x0b,0x76) ;//设置寄存器B
ds_write(0x09,11);//2011
ds_write(0x08,2);//2
ds_write(0x07,22);//21
ds_write(0x06,2);//星期1
ds_write(0x05,22);//时闹钟 19
ds_write(0x04,13); //小时 15
ds_write(0x03,30);//分钟闹钟 30
ds_write(0x02,44); //分钟 43
ds_write(0x01,0);//秒闹钟 0
ds_write(0x00,0);// 0

}

//Timer
计时器初始化程序   
void Init_Com(void)
{
TMOD = 0x20; //
定时器1工作在模式2的方式下
PCON = 0x00; //
初始化电源管理寄存器
SCON = 0x50; //
串口工作在模式1的方式下
TH1 = 0xfd;//
定时器高位寄存器初始化
TL1 = 0xfd; //
定时器低位寄存器初始化
TR1 = 1;   //
启动定时器
}

/////
键盘扫描
voidkeyscan()       //
键盘扫描用于调整时间
{
ucharx,y;        //key1
键调整时间时的选择功能
if(key1==0)      //
调整时间时只预示要调整的位
{        //
每按一下key1键,要调整的位就
  delay(30);      //
轮回预示呈现,以便调整
  if(key1==0)
  {
      aa++;
      flag=1;
   while(!key1);
  }
}
if(aa==1)
{
//
读小时
        hh=ds_read(0x04);      //
数码管1显示小时第一位
        x=hh/10;
        P2=0x00;//
先把P进行置高,清理数据(端口已改)
     P1=0xff;
//(端口已改)
     P1=0x7f; //(端口已改)
    P2=led[x]; //(端口已改)
        delay(1);
  //
数码管2显示小时第二位
        y=hh% 10;
        P2=0x00;//
全灭(端口已改)
        P1=0xbf;//
(端口已改)
        P2=led[y];//
(端口已改)
        delay(1);
  }
   if(aa==2)
  {
//
读分钟
        mm=ds_read(0x02);
//
数码管4显示分钟第1
        x=mm/10;
        P2=0x00;   //
全灭(端口已改)     
        P1=0xef;//
(端口已改)
        P2=led[x];//
(端口已改)
        delay(1);      
//
数码管5显示分钟第2
        y=mm% 10;
        P2=0x00;//
全灭(端口已改)
        P1=0xf7;//
(端口已改)
        P2=led[y];//
(端口已改)
        delay(1);
}

   if(aa==3)
{
     aa=0;
    flag=0;
}

if(key2==0)        //key2
键执行‘+’功能
  {
   delay(50);
   if(key2==0)
   {
    switch(aa)
    {

     case 1:hh++;
            if(hh==24)hh=0;
            ds_write(0x04,hh);break;
     case 2:mm++;
            if(mm==60)mm=0;
              ds_write(0x02,mm);break;  
    }
    while(!key2);
   }
  }
if(key3==0)        //key3
执行-功能
{
  delay(5);
  if(key3==0)
  {
   switch(aa)
   {

    case 1:hh--;
          if(hh==-1)hh=23;
          ds_write(0x04,hh);break;
    case 2:mm--;
          if(mm==-1)mm=59;
          ds_write(0x02,mm);break;

   }
   while(!key3);
  }
}
}

/////
void show_time()
{
uint q=4000;//
uchar x,y;
while(q)//
显示时间   小时----
{
    keyscan();
//
读小时
        hh=ds_read(0x04);      
//
数码管1显示小时第一位
        x=hh/10;
        P2=0x00;  //
全灭(端口已改)
        P1=0xff;//
(端口已改)
        P1=0x7f;//
(端口已改)
        P2=led[x];//
(端口已改)
        delay(1);
//
数码管2显示小时第二位
        y=hh% 10;
        P2=0x00;//
全灭(端口已改)
        P1=0xbf;//
(端口已改)
        P2=led[y];//
(端口已改)
        delay(1);
//
数码管3显示"--"
        P2=0x00;//
全灭(端口已改)
        P1=0xdf;//
(端口已改)
        P2=led[10];//
(端口已改)
        delay(1);
//
读分钟
        mm=ds_read(0x02);
//
数码管4显示分钟第1
        x=mm/10;
        P2=0x00;   //
全灭(端口已改)     
        P1=0xef;//
(端口已改)
        P2=led[x];//
(端口已改)
        delay(1);      
//
数码管5显示分钟第2
        y=mm% 10;
        P2=0x00;//
全灭(端口已改)
        P1=0xf7;//
(端口已改)
        P2=led[y];//
(端口已改)
        delay(1);      
//
数码管6显示"--"
        P2=0x00;//
全灭(端口已改)
        P1=0xfb;//
(端口已改)
        P2=led[10];//
(端口已改)
        delay(1);
//
读秒钟
        ss=ds_read(0x00);         
//
数码管7显示秒钟第1
        x=ss/10;
        P2=0x00;//
全灭(端口已改)
        P1=0xfd;//
(端口已改)
        P2=led[x];//
(端口已改)
        delay(1);        
//
数码管7显示秒钟第2
        y=ss% 10 ;
        P2=0x00;//
全灭(端口已改)
        P1=0xfe;//
(端口已改)
        P2=led[y];//
(端口已改)
        delay(1);
  q--;
}
}

void show_day()
{
    uint r=900;
while(r) //
显示年、月、日
{
    keyscan();
//
读月份
        mouth=ds_read(0x08);      
//
数码管5显示月份第1
        x=mouth/10;
        P2=0x00;//
全灭(端口已改)
        P1=0x7f;//
(端口已改)
        if(x==0)
        {
            P0=led[12];
            delay(1);
        }
        else
        {
        P2=led[x];//
(端口已改)
        delay(1);
        }      
//
数码管6显示月份第2
        y=mouth%10;        
        P2=0x00;//
全灭(端口已改)
        P1=0xbf;//
(端口已改)
        P2=led1[y];//
(端口已改)
        delay(1);
//
读日期
        day=ds_read(0x07);         
//
数码管7显示日期第1
        x=day/10;
        P2=0x00;//
全灭(端口已改)
        P1=0xdf;//
(端口已改)
        if(x==0)
        {
            P2=led[12];//
(端口已改)
            delay(1);
        }
        else
        {
        P2=led[x];//
(端口已改)

        delay(1);
        }
//
数码管7显示日期第2
        y=day% 10 ;
        P2=0x00;//
全灭(端口已改)
        P1=0xef;//
(端口已改)
        P2=led1[y];//
(端口已改)
        delay(1);
//
读年
        year=ds_read(0x09);      
//
数码管1显示年"2"
        P2=0x00;//
全灭(端口已改)
        P1=0xf7;//
(端口已改)
        P2=led[2];//
(端口已改)
        delay(1);
//
数码管2显示年"0"
        P2=0x00;//
全灭(端口已改)
        P1=0xfb;//
(端口已改)
        P2=led1[10];//
(端口已改)
        delay(1);
//
数码管3显示年百位
        x=year/10;
        P2=0x00;//
全灭(端口已改)
        P1=0xfd;//
(端口已改)
        P2=led[x];//
(端口已改)
        delay(1);
//
数码管4显示年个位
        y=year%10;
        P2=0x00;     //
全灭(端口已改)   
        P1=0xfe;//
(端口已改)
        P2=led[y];//
(端口已改)
        delay(1);  
    r--;

  }

}
void show_tempture_week()
{
uint m=80;
while(m)  ///
显示温度、星期
{


keyscan();
//
读星期
        week=ds_read(0x06);      
//
数码管8显示星期
        x=week%10;
        P2=0x00;//
全灭(端口已改)
        P1=0xfe;//
(端口已改)
        P2=led[x];//
(端口已改)
        delay(10);
//
数码管7 去亮
        P2=0x00;//
全灭(端口已改)
        P1=0xfd;//
(端口已改)
        P2=led[12];//
(端口已改)
        delay(1);

    m--;
  }
}

void main()

  {
    keyscan();
    show_time();//
时间,日期显示
    show_day();   
    show_tempture_week();
    while(flag)
{
    if(aa=1)
    {show_time();keyscan();}
    else if(aa=2)
    {show_time();keyscan();}
    else   ;

}
}
}

谢谢啦!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
 楼主| 发表于 2020-8-18 10:20:36 | 显示全部楼层
还有就是因为数码管不够日历和时间要轮流显示,在代码中我没有看到相关的段落,如果缺失请一并给出。
谢谢!
回复 支持 反对

使用道具 举报

发表于 2020-8-18 11:16:10 | 显示全部楼层
原版如果正常,共阴改共阳仅需在输出时段、位分别取反;
楼主的程序结构不合章法
回复 支持 反对

使用道具 举报

发表于 2020-8-18 21:28:47 | 显示全部楼层
本帖最后由 慕名而来 于 2020-8-18 21:30 编辑

硬件电路需要改的,我百度了一下ULN2803是一片低电平控制的高电平输出元件,他不适合共阴极数码管的位驱动(共阳极的没问题),这个电路图中的74HC04做什么用的也在此请教各位,单片机I/O口低电平驱动ULN应该没问题的吧,我真的不知道他是起啥作用的。
建议用8个三极管(NPN的SS8050)B极经4.7K电阻连接I/O口、E极接GND、C极接数码管的com端;先建立新工程,写自己的代码驱动数码管,当可以任意的点亮各个数码管并可以显示任意数字后再往工程里移植添加12C887的代码来调试就简单了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-19 10:51:19 | 显示全部楼层
谢谢二位的回复。
1、端口问题已经可以解决了,在网上搜索了取反的方法,就是把P2 = 0xfe;语句改为 P2 = ~0xfe;就可以不知道对不对。
2、楼上关于UNL2803和 74CH04的问题,我是这样理解的,74CH04反相驱动UNL2803,UNL2803对负载起扩流作用,不知道对不对。
3、关于DS12C887 初始化和温度显示代码的问题,我在代码中删除了一些不知道删除的对不对。
4、还有就是时间和日历显示转换的问题没有解决,希望高手指教。
谢谢啦!
回复 支持 反对

使用道具 举报

发表于 2020-8-19 11:12:31 | 显示全部楼层
gxjhgxjh 发表于 2020-8-19 10:51
谢谢二位的回复。
1、端口问题已经可以解决了,在网上搜索了取反的方法,就是把P2 = 0xfe;语句改为 P2 = ~0 ...

我只是想知道楼主的数码管是否已经可以点亮并且随意显示数字了,如果已经点亮并且可以输出数字了就不用考虑数据反向的问题了,而且离成功就不远了,如果数码管还没有能够点亮并且正常显示数字,就请仔细关注下我在楼上的回复,或许那是解决问题的根本。
回复 支持 反对

使用道具 举报

发表于 2020-8-19 12:18:30 | 显示全部楼层
本帖最后由 xixia001 于 2020-8-19 12:32 编辑

将P1口数据按位取反,就可以省去74HC04.
P2口上拉电阻330欧有点小了,建议取1K欧,但这样数码管的亮度可能会比较低。
/***********************************************/
纠正一下,89S52的P1口没接上拉电阻,应该不能直接驱动ULN2803,“将P1口数据按位取反,就可以省去74HC04.”这个说法不对。

回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-19 22:54:05 | 显示全部楼层
谢谢各位的回复。我的情况可能没有说清楚,我不懂英文不会编程,代码全部是从网上拷贝的,只能根据自己的板子改改端口,不懂的就百度,有时候可能因为不懂百度的也不对就找不到解决方法,只能到论坛发贴求助。自己收集了一些废旧电路板就是业余玩玩,打发时间防止老年痴呆而已。电路板上p0口有上拉电阻p1口没有,共用了3片74hc04两片uln2803,利用这个板子做了跑马灯成功,所以想驱动数码管应该没有问题。

p2口的上拉电阻是板子上自带的阻值是100欧母,我的图是从别的图上剪切的没有改,误导大侠对不起啦。
两块板子的图片:
单片机的

数码管的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

发表于 2020-8-20 09:33:45 | 显示全部楼层
gxjhgxjh 发表于 2020-8-19 22:54
谢谢各位的回复。我的情况可能没有说清楚,我不懂英文不会编程,代码全部是从网上拷贝的,只能根据自己的板 ...

因为都是如此走过来的人、也因为都有一个共同的爱好和目的---“打发时间防止老年痴呆而已”就多参与一下,我感觉像楼主这样弄就太累了建议不要如此玩法,首先如果不通过编程修改我真的不知道图一中的板子是怎样被楼主利用起来的,而楼主想用上图的板子驱动下图的数码管板子如果不针对性的编程的话几乎没办法实现功能,其次AT89S51/52系列单片机虽然也能在线编程,但他确实没有STC单片机仅用2根串口线来的方便,非常容易上手,这也正是单片机新手入门都喜欢用STC的根本原因,其实我也是同过一片89S51单片机开始学习单片机的,发现了STC以后就再也没有用过那个了,还建议楼主淘宝一个可以为STC编程的USB_TTL模块(可以转换5V-3V3电源、可以自动断电)再弄一片STC12C5A60S2单片机,用洞洞板焊一个最小系统板,用排针引出引脚,此后通过杜邦线连接就可以玩大部分东西了,此后的工作就只有简单的焊接引线、改编程序了,玩这些C语言初步入门是必要的,至少也要能够读懂别人的代码和简单的修改别人的代码,我学习C语言就是读别人的代码而后百度那些特征字含义、语法、语句**,虽然后来找到了一本入门书但基础也还是那些东西了,一旦玩明白了keil软件建立工程、编译、修改错误代码、改编代码这些关口,再玩啥就都简单了,因为我们能玩的东西在百度上都可以找到例程的,所以说从最小系统板+编程入手玩这些东西才是近路,唠叨了好多,都是与楼主的提问无关的只为参与吧。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-20 17:33:49 | 显示全部楼层
谢谢楼上的回复。本来手里有一些旧单片机的板子就想利用一下,通过一段时间的学习才了解到单片机的发展太快了,手里只剩下AT89C52和AT89S51还可以利用其余的都是电子垃圾了。所以就按AT89S51的使用学习了,烧录线也是从旧板子拆的74hc373自己做的。
第一块板子已经接近单片机最小系统了,多余的东西拆完了,只留了P0和P1端口的三片74hc04和两片uln2803了,自己在使用中又增加p0、p2、p3口直接输出接线端子。
图中的万年历就是按ds12c887+1602液晶屏的代码变通使用的。因为嫌液晶屏字太小稍远一些就看不清了,所以想利用图二的数码管,从新做一个,在网上拷贝的代码自己改一下用,没有想到比液晶屏的代码难多了,所以来论坛求助了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-21 11:05:18 | 显示全部楼层
本帖最后由 gxjhgxjh 于 2020-8-21 11:06 编辑

大家好!
我把程序中关于温度和ds12c887初始化有关的代码删除,把p端口按我的电路更改后,试着编译了一下在最后一段出现三个警告,我看不懂了请大侠指教。谢谢啦!
代码:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar hh,mm,ss,year,mouth,day,dd,week,aa,x,y,flag;
uint temp;
uchar code  led[14]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0x7f,0xff,0xc6};//不加小数点,这个是共阳极的写法,共阴极要取反。
uchar
code led1[11]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xa3}; //加了小数点
sbit key1=P3^5;   //key1键调整时间时的‘位’选择功能
sbit key2=P3^6; //key2执行加功能
sbit key3=P3^7; //key3执行减功能
//sbit beep =P3^3; //暂时改为蜂鸣器代码中没有相关代码
/*定义DS12CR887数据线-------------------------*/
sbit DS_CS=P3^4; //定义DS12C887芯片片选端        (读哪个芯片)(已改端口)
sbit DS_AS=P3^1; //定义DS12C887地址选通输入端 (读到那里去)(已改端口)
sbit DS_RW=P3^2; //定义DS12C887读允许输入(让读以后,我来输入数据)(已改端口)
sbit DS_DS=P3^0; //定义DS12C887读数据允许输入脚,这里mot接地(已改端口)
#define DS_BUS P0   //DS12CR887数据总线(已改端口)
/************//*DS12CR887驱动程序----------------------------*/
//向DS12CR887写数据函数
void ds_write(uchar add,uchar date)
{
DS_CS=0; //根据时序图把相应的脚变化高低,片选端,低电平有效
DS_AS=1; //地址选通输入端
DS_DS=1; //读允许输入脚
DS_RW=1; //写输入脚
DS_BUS=add; //写地址
DS_AS=0;
DS_RW=0;
DS_BUS=date; //写命令
DS_RW=1;
DS_AS=1;
DS_CS=1;
}
//读取DS12CR887的数据
uchar ds_read(uchar add)
{
uchar z;  //定义一个无符号函数
DS_AS=1; //ALE,地址锁存允许//根据时序图,进行高低电平设置
DS_DS=1; //Read读入
DS_RW=1; //!WR 禁止写入
DS_CS=0; //片选输入
DS_BUS=add; //写地址,确定要读什么位置的值
DS_AS=0;
DS_DS=0;
DS_BUS=0xff; //先把P1进行置高,清理数据 可能要取反
z=DS_BUS; //把新的得到12c887里面的数值,赋值给ds_bus
DS_DS=1;  //根据时序图继续设置电平
DS_AS=1;
DS_CS=1;
return z; //谁调用它,什么位置调用的,就会把这个新得到的值在返回给他,看得出来只有读闹钟值是调用了。
}

void delay(uint z) //延时
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=10;y>0;y--);
}

//Timer计时器初始化程序
void Init_Com(void)
{
TMOD = 0x20; //定时器1工作在模式2的方式下
PCON = 0x00; //初始化电源管理寄存器
SCON = 0x50; //串口工作在模式1的方式下
TH1 = 0xfd;//定时器高位寄存器初始化
TL1 = 0xfd; //定时器低位寄存器初始化
TR1 = 1;   //启动定时器
}

/////键盘扫描
void keyscan()       //键盘扫描用于调整时间
{
uchar x,y;        //key1键调整时间时的‘位’选择功能,每按一下key1键,要调整的位就
if(key1==0)       //调整时间时只预示要调整的位
{         
  delay(30);      //轮回预示呈现,以便调整
  if(key1==0)
  {
      aa++;
      flag=1;
   while(!key1);
  }
}
if(aa==1)
{
//读小时
        hh=ds_read(0x04);      // 数码管1显示小时第一位
        x=hh /10;
        P2=0xff; //先把P进行置高,清理数据(已改端口)

        P1=0xff; //(已改端口)
        P1=0x7f; //(已改端口)
        P2=led[x]; //(已改端口)
        delay(1);
  //数码管2显示小时第二位
        y=hh % 10;
        P2=0xff; //(已改端口)
        P1=0xbf; //(已改端口)
        P2=led[y]; //(已改端口)
        delay(1);

}
if(aa==2)
{
//读分钟
        mm=ds_read(0x02);
//数码管4显示分钟第1位
        x=mm /10;
        P2=0xff;    //(已改端口)   
        P1=0xef; //(已改端口)
        P2=led[x]; //(已改端口)
        delay(1);      
//数码管5显示分钟第2位
        y=mm % 10;
        P2=0xff; //(已改端口)
        P1=0xf7; //(已改端口)
        P2=led[y]; //(已改端口)
        delay(1);
}

   if(aa==3)
{
     aa=0;
    flag=0;
}

if(key2==0)        //key2键执行‘+’功能
  {
   delay(50);
   if(key2==0)
   {
    switch(aa)
    {

     case 1:hh++;
            if(hh==24)hh=0;
            ds_write(0x04,hh);break;
     case 2:mm++;
            if(mm==60)mm=0;
               ds_write(0x02,mm);break;  
    }
    while(!key2);
   }
  }
if(key3==0)         //key3执行-功能
{
  delay(5);
  if(key3==0)
  {
   switch(aa)
   {

    case 1:hh--;
           if(hh==-1)hh=23;
           ds_write(0x04,hh);break;
    case 2:mm--;
           if(mm==-1)mm=59;
           ds_write(0x02,mm);break;

   }
   while(!key3);
  }
}
}

/////
void show_time()
{
uint q=4000;//
uchar x,y;
while(q)//显示时间   小时--分--秒
{
    keyscan();
//读小时
        hh=ds_read(0x04);      
// 数码管1显示小时第一位
        x=hh /10;
        P2=0xff; //(已改端口)
        P1=0xff; //(已改端口)
        P1=0x7f; //(已改端口)
        P2=led[x]; //(已改端口)
        delay(1);
//数码管2显示小时第二位
        y=hh % 10;
        P2=0xff; //(已改端口)
        P1=0xbf; //(已改端口)
        P2=led[y]; //(已改端口)
        delay(1);
//数码管3显示"--"
        P2=0xff; //(已改端口)
        P1=0xdf; //(已改端口)
        P2=led[10]; //(已改端口)
        delay(1);
//读分钟
        mm=ds_read(0x02);
//数码管4显示分钟第1位
        x=mm /10;
        P2=0xff;        //(已改端口)
        P1=0xef; //(已改端口)
        P2=led[x]; //(已改端口)
        delay(1);      
//数码管5显示分钟第2位
        y=mm % 10;
        P2=0xff; //(已改端口)
        P1=0xf7; //(已改端口)
        P2=led[y]; //(已改端口)
        delay(1);      
// 数码管6显示"--"
        P2=0xff; //(已改端口)
        P1=0xfb; //(已改端口)
        P2=led[10]; //(已改端口)
        delay(1);
//读秒钟
        ss=ds_read(0x00);         
//数码管7显示秒钟第1位
        x=ss /10;
        P2=0xff; //(已改端口)
        P1=0xfd; //(已改端口)
        P2=led[x]; //(已改端口)
        delay(1);        
//数码管7显示秒钟第2位
        y=ss % 10 ;
        P2=0xff; //(已改端口)
        P1=0xfe; //(已改端口)
        P2=led[y]; //(已改端口)
        delay(1);
     q--;
}
}

void show_day()
{
    uint r=900;
while(r) //显示年、月、日
{
    keyscan();
//读月份
        mouth=ds_read(0x08);      
//数码管5显示月份第1位
        x=mouth/10;
        P2=0xff; //(已改端口)
        P1=0x7f; //(已改端口)
        if(x==0)
        {
            P2=led[12]; //(已改端口)
            delay(1);
        }
        else
        {
        P2=led[x]; //(已改端口)
        delay(1);
        }      
// 数码管6显示月份第2位
        y=mouth%10;        
        P2=0xff; //(已改端口)
        P1=0xbf; //(已改端口)
        P2=led1[y]; //(已改端口)
        delay(1);
//读日期
        day=ds_read(0x07);         
//数码管7显示日期第1位
        x=day /10;
        P2=0xff; //(已改端口)
        P1=0xdf; //(已改端口)
        if(x==0)
        {
            P2=led[12]; //(已改端口)
            delay(1);
        }
        else
        {
        P2=led[x]; //(已改端口)
        delay(1);
        }
//数码管7显示日期第2位
        y=day % 10 ;
        P2=0xff; //(已改端口)
        P1=0xef; //(已改端口)
        P2=led1[y]; //(已改端口)
        delay(1);
//读年
        year=ds_read(0x09);      
// 数码管1显示年"2"
        P2=0xff; //(已改端口)
        P1=0xf7; //(已改端口)
        P2=led[2]; //(已改端口)
        delay(1);
//数码管2显示年"0"
        P2=0xff; //(已改端口)
        P1=0xfb; //(已改端口)
        P2=led1[10]; //(已改端口)
        delay(1);
//数码管3显示年百位
        x=year/10; //(已改端口)
        P2=0xff; //(已改端口)
        P1=0xfd; //(已改端口)
        P2=led[x]; //(已改端口)
        delay(1);
//数码管4显示年个位
        y=year%10;
        P2=0xff;    //(已改端口)   
        P1=0xfe; //(已改端口)
        P2=led[y]; //(已改端口)
        delay(1);  
      r--;
  }
}
void show_tempture_week()
{
uint m=80;
while(m)  ///显示温度、星期
{
keyscan();
//读星期
        week=ds_read(0x06);      
// 数码管8显示星期
        x=week%10;
        P2=0xff; //(已改端口)
        P1=0xfe; //(已改端口)
        P2=led[x]; //(已改端口)
        delay(10);
// 数码管7 去亮
        P2=0xff; //(已改端口)
        P1=0xfd; //(已改端口)
        P2=led[12]; //(已改端口)
        delay(1);
    m--;
  }
}


        void main()
{
//    time_init();
    Init_Com(); //温度串口初始化
    aa=0;
    while(1)
  {
    keyscan();
    show_time();//时间,日期显示
    show_day();   
    show_tempture_week();
    while(flag)
{
    if(aa=1)
    {show_time();keyscan();}
    else if(aa=2)
    {show_time();keyscan();}
    else;


}
}
}
警告;
Rebuild target 'Target 1'
assembling STARTUP.A51...
compiling wbl1.c...
wbl1.c(347): warning C276: constant in condition expression
wbl1.c(349): warning C276: constant in condition expression
wbl1.c(349): warning C294: unreachable code
linking...
Program Size: data=25.0 xdata=0 code=890
creating hex file from ".\Objects\wnl1"...
".\Objects\wnl1" - 0 Error(s), 3 Warning(s).
回复 支持 反对

使用道具 举报

发表于 2020-8-21 11:23:22 | 显示全部楼层
gxjhgxjh 发表于 2020-8-20 17:33
谢谢楼上的回复。本来手里有一些旧单片机的板子就想利用一下,通过一段时间的学习才了解到单片机的发展太快 ...

建议连74hc04和2803也一并拆除吧,我玩过许多的LED数码管也发了好多数码管时钟的帖子,有164、595驱动的以及最近用TM16**驱动的,都没有用到这两种东西,如果是驱动共阴极的就更加没必要了,就你在一楼的图片而言,如果不只是P2输出段码、P1输出位控,那么代码会变得非常简单的,首先画一个段码表如下图:
如果P0.0--P0.7依次连接abcdefg dp段,P1.0--P1.7连接led0---led7的位控,可以试试下边的代码,正常的话应该现象12-34-56,因为代码没有测试也可能显示错误,但找出问题就不难了,至于D12C**因为没用过就不讨论了。
  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. uchar code  Date[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xbf,0x00};//不点亮dp点的段码+黑屏码
  5. uchar dat[8];//显示数据缓存
  6. uchar hour=12,min=34,second=56;
  7. //====n毫秒延时函数=================
  8. void delay(uint n)   //12T/12MHz/n(mS)
  9. {
  10. uchar a,b,c;
  11. while(--n!=0)
  12. {
  13. for(c=1;c>0;c--)
  14. for(b=142;b>0;b--)
  15. for(a=2;a>0;a--);
  16. }
  17. }
  18. //====显示数据转换函数====
  19. void zhuan_h() //
  20. {
  21. dat[7]=hour%10;
  22. dat[6]=hour/10;
  23. dat[5]=0x40; //点亮g段   
  24. dat[4]=min%10;
  25. dat[3]=min/10;
  26. dat[2]=0x40; //点亮g段
  27. dat[1]=second%10;
  28. dat[0]=second/10;   
  29. }
  30. //====显示函数============
  31. void Display()
  32. {
  33. uchar i,a=0x01;
  34. zhuan_h();
  35. for(i=0;i<8;i++)
  36. {
  37. P0=Date[dat[i]];
  38. P1=~a;
  39. a=a<<i;
  40. delay(3);
  41. }
  42. }
  43. main()
  44. {
  45. while(1)
  46. {
  47. Display();
  48. }
  49. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-22 15:13:41 | 显示全部楼层
谢谢楼上的,还辛苦的写了测试代码。我整理好数码管电路板后测试一下。
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-8-12 07:54 , Processed in 0.187201 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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