微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求教1302数码管显示的问题

求教1302数码管显示的问题

时间:10-02 整理:3721RD 点击:
时钟是可以走的,但为什么数码管会闪?延时问题还是1302时序问题?请教。:handshake
#include<reg52.h>
sbit ds1302_clk=P3^4;
sbit ds1302_io=P3^6;
sbit ds1302_rst=P3^5;
sbit LATCH1=P2^6;
sbit LATCH2=P2^7;
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code WeiMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char data1[8];       
unsigned char second,minute,hour;
unsigned char time[]={0x12,0x30,0x00};
void delay(unsigned char i)     //延时子程序  
{
  unsigned char j;
  while((i--)!=0)
  {
    for(j=123;j>0;j--);
  }
}
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++);
}

void display(void)//数码管显示子函数;
{        unsigned char j;
        data1[0]=hour/16;
        data1[1]=hour%16;
        data1[3]=minute/16;
        data1[4]=minute%16;
        data1[6]=second/16;
        data1[7]=second%16;
for(j=0;j<8;j++)
{
if(j==2||j==5)
{LATCH1=1;
P0=0xbf;
LATCH1=0;
P0=0x00;
LATCH2=1;
P0=WeiMa[j];
LATCH2=0;
}
else
{LATCH1=1;
P0=tab[data1[j]];
LATCH1=0;
P0=0x00;
LATCH2=1;
P0=WeiMa[j];
LATCH2=0;
}
delay(1);
}       
}
   
void Write1302(unsigned char dat)
{
  unsigned char i;
  ds1302_clk=0;            //拉低SCLK,为脉冲上升沿写入数据做好准备
  delaynus(2);       //稍微等待,使硬件做好准备
  for(i=0;i<8;i++)      //连续写8个二进制位数据
    {
            ds1302_io=dat&0x01;    //取出dat的第0位数据写入1302
                delaynus(2);       //稍微等待,使硬件做好准备
                 ds1302_clk=1;           //上升沿写入数据
                 delaynus(2);      //稍微等待,使硬件做好准备
                 ds1302_clk=0;           //重新拉低SCLK,形成脉冲
                 dat>>=1;          //将dat的各数据位右移1位,准备写入下一个数据位
          }
       
}
unsigned char Read1302(void)
{
   unsigned char i,dat;
        delaynus(2);       //稍微等待,使硬件做好准备
        for(i=0;i<8;i++)   //连续读8个二进制位数据
         {
           dat>>=1;       //将dat的各数据位右移1位,因为先读出的是字节的最低位
                if(ds1302_io==1)    //如果读出的数据是1
                 dat|=0x80;    //将1取出,写在dat的最高位
                 ds1302_clk=1;       //将SCLK置于高电平,为下降沿读出
                 delaynus(2);  //稍微等待
                 ds1302_clk=0;       //拉低SCLK,形成脉冲下降沿
                 delaynus(2);  //稍微等待
          }         
  return dat;        //将读出的数据返回
}
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
    ds1302_rst=0;           //禁止数据传递
    ds1302_clk=0;          //确保写数居前SCLK被拉低
        ds1302_rst=1;           //启动数据传输
        delaynus(2);     //稍微等待,使硬件做好准备
        Write1302(Cmd);  //写入命令字
        Write1302(dat);  //写数据
        ds1302_clk=1;          //将时钟电平置于已知状态
        ds1302_rst=0;           //禁止数据传递
}


unsigned char ReadSet1302(unsigned char Cmd)
{
  unsigned char dat;
  ds1302_rst=0;                 //拉低RST
  ds1302_clk=0;                //确保写数居前SCLK被拉低
  ds1302_rst=1;                 //启动数据传输
  Write1302(Cmd);       //写入命令字
  dat=Read1302();       //读出数据
  ds1302_clk=1;              //将时钟电平置于已知状态
  ds1302_rst=0;               //禁止数据传递
  return dat;          //将读出的数据返回
}
void Init_DS1302(void)
{
        WriteSet1302(0x8e,0x00);
        WriteSet1302(0x84,time[0]);
        WriteSet1302(0x82,time[1]);
        WriteSet1302(0x80,time[2]);
        WriteSet1302(0x8e,0x80);
}

void read_time()
{
        hour=ReadSet1302(0x85);
        minute=ReadSet1302(0x83);
        second=ReadSet1302(0x81);
}
void main(void)
{
        Init_DS1302();
    while(1)
        {
                read_time();
                display();
                       
        }       
}

主函数里的延时时间过长了,可以适当减小些试试

回复 feiren45 的帖子
请教:可主函数就调用了初始化、读时间和显示三个子程序啊   还是不太明白 麻烦您再讲清楚些   谢谢

void main(void)
{
        Init_DS1302();
    while(1)
        {
                read_time();
                display();
               delay(oxf0i);
                        
        }        
}

回复 agj032 的帖子
弱弱的问一句:“delay(oxf0i);”什么意思 请指教

不知你的主频是多少.1.力求读时间函数( read_time();)控制在40ms以内,2.显示函数display();后面加一个延时(delay(oxf0i);),延时时间最好为960ms.oxf0i为你自己定长度.

回复 agj032 的帖子
主频12MHZ    好象不行啊。

你在读时间时也调用一下显示看看

#include<reg52.h>
#define DS1302_W_ADDR 0x80
#define DS1302_R_ADDR 0x81
#define uchar unsigned char
uchar s,f,m;
uchar time[7]={55,47,23,16,1,1,13};
uchar code a[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar code b[]={0xbF,0x86,0xdB,0xcF,0xe6,0xeD,0xfD,0x87,0xfF,0xeF};
void delay(int z)  //延迟
{
        int x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void delay1()
{ ;; }
void write_ds1302_byte(uchar dat)
{
        int i;
        WR=0;
        for(i=8;i>0;i--)
        {
                RD=dat&0x01;
                WR=1;
                dat>>=1;
                WR=0;
        }
}
uchar read_ds1302_byte()
{
        uchar i,dat=0;
        WR=0;
        for(i=8;i>0;i--)
        {
                WR=1;
                dat>>=1;
                if(RD)
                        dat|=0x80;
                WR=0;
        }
        return dat;
}
void reset_ds1302()
{
        T1=0;
        WR=0;
        T1=1;
}
void clear_ds1302_WP(void)
{
        reset_ds1302();
        T1=1;
        write_ds1302_byte(0x8E);
        write_ds1302_byte(0x00);
        WR=1;
        T1=0;
}
void set_ds1302_WP()
{
        reset_ds1302();
        T1=1;
        write_ds1302_byte(0x8E);
        write_ds1302_byte(0x80);
        WR=1;
        T1=0;
}
void write_ds1302(uchar addr,uchar dat)
{
        reset_ds1302();
        T1=1;
        write_ds1302_byte(addr);
        write_ds1302_byte(dat);
        WR=1;
        T1=0;
}
void set_time(uchar *timedata)
{
        uchar i,tmp;
        for(i=0;i<7;i++)
        {
                tmp=timedata[i]/10;
                timedata[i]=timedata[i]%10;
                timedata[i]=timedata[i]+tmp*16;
        }                           
        clear_ds1302_WP();          
        tmp=DS1302_W_ADDR;
        for(i=0;i<7;i++)
        {
                write_ds1302(tmp,timedata[i]);
                tmp+=2;
        }
        set_ds1302_WP();
}

uchar read_ds1302(uchar addr)
{
        uchar  temp=0;
        reset_ds1302();
        T1=1;
        write_ds1302_byte(addr);
        temp=read_ds1302_byte();
        WR=1;
        T1=0;
        return temp;
}
void read_time(uchar *timedata)
{
        uchar i,tmp;
        tmp=DS1302_R_ADDR;
        for(i=3;i>0;i--)
        {
                timedata[i]=read_ds1302(tmp);
                tmp+=2;
        }
}
void main()
{
        set_time(&time);
        while(1)
        {
                reset_ds1302();
                read_time(&time);
                P2=0x02;
                P0=a[time[3]/16];
                delay(5);
                P2=0x01;
                P0=a[time[3]%16];
                delay(5);
                P2=0x08;
                P0=a[time[2]/16];
                delay(5);
                P2=0x04;
                P0=a[time[2]%16];
                delay(5);
                P2=0x20;
                P0=a[time[1]/16];
                delay(5);
                P2=0x10;
                P0=a[time[1]%16];
                delay(5);
        }       
}
这是我的程序,我的已经可以读出时钟在走,但用数码管显示时在闪烁,有时候读取不到实时的时间来显示,经常有全显零的现象

上一篇:数码管驱动
下一篇:关于12864液晶

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top