找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2132|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)+8位數(shù)碼管顯示時(shí)鐘程序 無(wú)法讀取ds1302時(shí)間

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
本人初學(xué)單片機(jī),想用8位數(shù)碼管和ds1302做個(gè)簡(jiǎn)單的時(shí)鐘,折騰了很久,死活讀取不了ds1302的時(shí)間,時(shí)分秒都一直顯示0,請(qǐng)各位高手不吝賜教,謝謝!

單片機(jī)源程序如下:
/*******************************************************************************
*  標(biāo)題:  8位數(shù)碼管顯示時(shí)鐘                                                   *
*                                                                                                                                                                                                *
*                                                                                    *
********************************************************************************/
#include<reg51.h>
#include <intrins.h>
#define uchar unsigned char

sbit SCK=P3^6;        //時(shí)鐘
sbit SDA=P3^4;        //數(shù)據(jù)
sbit RST = P3^5;// DS1302復(fù)位

void main (void);                                        // 主函數(shù)
void LED4_Display (void);                        // LED顯示
void LED_OUT(uchar X);                                // LED單字節(jié)串行移位函數(shù)

unsigned char code LED_0F[];                // LED字模表

sbit DIO = P1^0;                                //串行數(shù)據(jù)輸入
sbit RCLK  = P1^1;                                //時(shí)鐘脈沖信號(hào)——上升沿有效
sbit SCLK = P1^2;                                //打入信號(hào)————上升沿有效

//-----------------------------------------------------------------------------
// 全局變量

unsigned char LED[8] = {0,0,12,15,5,3,8};        //用于LED的8位顯示緩存
bit ReadRTC_Flag;//定義讀DS1302標(biāo)志

unsigned char l_tmpdate[7]= {0,0,12,15,5,3,8}; //秒分時(shí)日月周年08-05-15 12:00:00
unsigned char l_tmpdisplay[8];

code unsigned char write_rtc_address[7]= {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分時(shí)日月周年 最低位讀寫(xiě)位
code unsigned char read_rtc_address[7]= {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
//碼表
unsigned char code LED_0F[] =
{   // 0         1          2           3        4         5          6           7        8         9          A           b        C    d          E    F    -
    0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf
};
code unsigned char table[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
//共陽(yáng)數(shù)碼管

/******************************************************************/
/*                    函數(shù)聲明                                    */
/******************************************************************/
void Write_Ds1302_byte(unsigned char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );
void Read_RTC(void);//read RTC
void Set_RTC(void); //set RTC
void InitTIMER0(void);//inital timer0
/******************************************************************/
/*                   主函數(shù)                                       */
/******************************************************************/
void main(void)
{
    InitTIMER0();          //初始化定時(shí)器0
    //Set_RTC();             //寫(xiě)入時(shí)鐘值,如果使用備用電池時(shí)候,不需要沒(méi)每次上電寫(xiě)入,此程序應(yīng)該屏蔽

    while(1)
    {
        if(ReadRTC_Flag)
        {
            ReadRTC_Flag=0;
            Read_RTC();

            LED[0]=l_tmpdate[2]/16;                        //數(shù)據(jù)的轉(zhuǎn)換,因我們采用數(shù)碼管0~9的顯示,將數(shù)據(jù)分開(kāi)
            LED[1]=l_tmpdate[2]&0x0f;
            LED[2]=16;                                                    //加入"-"
            LED[3]=l_tmpdate[1]/16;
            LED[4]=l_tmpdate[1]&0x0f;
            LED[5]=16;
            LED[6]=l_tmpdate[0]/16;
            LED[7]=l_tmpdate[0]&0x0f;

        }
    }
}
/******************************************************************/
/*                   定時(shí)器0初始化                                */
/******************************************************************/
void InitTIMER0(void)
{
    TMOD|=0x01;//定時(shí)器設(shè)置 16位
    TH0=0xef;//初始化值
    TL0=0xf0;
    ET0=1;
    TR0=1;
    EA=1;
}


/******************************************************************/
/*                   寫(xiě)一個(gè)字節(jié)                                   */
/******************************************************************/
void Write_Ds1302_Byte(unsigned  char temp)
{
    unsigned char i;
    for (i=0; i<8; i++)             //循環(huán)8次 寫(xiě)入數(shù)據(jù)
    {
        SCK=0;
        SDA=temp&0x01;     //每次傳輸?shù)妥止?jié)
        temp>>=1;                  //右移一位
        SCK=1;
    }
}
/******************************************************************/
/*                  寫(xiě)入DS1302                                    */
/******************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )
{
    RST=0;
    _nop_();
    SCK=0;
    _nop_();
    RST=1;
    _nop_();                    //啟動(dòng)
    Write_Ds1302_Byte(address);        //發(fā)送地址
    Write_Ds1302_Byte(dat);                //發(fā)送數(shù)據(jù)
    RST=0;                              //恢復(fù)
}
/******************************************************************/
/*                   讀出DS1302數(shù)據(jù)                               */
/******************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
    unsigned char i,temp=0x00;
    RST=0;
    _nop_();
    _nop_();
    SCK=0;
    _nop_();
    _nop_();
    RST=1;
    _nop_();
    _nop_();
    Write_Ds1302_Byte(address);
    for (i=0; i<8; i++)                 //循環(huán)8次 讀取數(shù)據(jù)
    {
        if(SDA)
            temp|=0x80;                        //每次傳輸?shù)妥止?jié)
        SCK=0;
        temp>>=1;                        //右移一位
        _nop_();
        _nop_();
        _nop_();
        SCK=1;
    }
    RST=0;
    _nop_();                          //以下為DS1302復(fù)位的穩(wěn)定時(shí)間
    _nop_();
    RST=0;
    SCK=0;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SCK=1;
    _nop_();
    _nop_();
    SDA=0;
    _nop_();
    _nop_();
    SDA=1;
    _nop_();
    _nop_();
    return (temp);                        //返回
}
/******************************************************************/
/*                   讀時(shí)鐘數(shù)據(jù)                                   */
/******************************************************************/
void Read_RTC(void)                //讀取 日歷
{
    unsigned char i,*p;
    p=read_rtc_address;             //地址傳遞
    for(i=0; i<7; i++)                  //分7次讀取 秒分時(shí)日月周年
    {
        l_tmpdate[ i]=Read_Ds1302(*p);
        p++;
    }
}
/******************************************************************/
/*                  設(shè)定時(shí)鐘數(shù)據(jù)                                  */
/******************************************************************/
void Set_RTC(void)                    //設(shè)定 日歷
{
    unsigned char i,*p,tmp;
    for(i=0; i<7; i++) {    //BCD處理
        tmp=l_tmpdate[ i]/10;
        l_tmpdate[ i]=l_tmpdate[ i]%10;
        l_tmpdate[ i]=l_tmpdate[ i]+tmp*16;
    }
    Write_Ds1302(0x8E,0X00);

    p=write_rtc_address;        //傳地址
    for(i=0; i<7; i++)                //7次寫(xiě)入 秒分時(shí)日月周年
    {
        Write_Ds1302(*p,l_tmpdate[ i]);
        p++;
    }
    Write_Ds1302(0x8E,0x80);
}
/******************************************************************/
/*                   定時(shí)器中斷函數(shù)                               */
/******************************************************************/
void tim(void) interrupt 1 using 1
//中斷,用于數(shù)碼管掃描
{

    static unsigned char i,num;
    uchar code *led_table;          // 查表指針
        
    TH0=0xf5;
    TL0=0xe0;
    //uchar i;
    //顯示第1位
    LED4_Display();
    i++;
    if(i==8)
    {
        i=0;
        num++;
        if(10==num)       //隔段時(shí)間讀取1302的數(shù)據(jù)。時(shí)間間隔可以調(diào)整
        {
            ReadRTC_Flag=1; //使用標(biāo)志位判斷
            num=0;
        }
    }
}

void LED4_Display (void)
{
    uchar code *led_table;          // 查表指針
    uchar i;
    //顯示第1位
    led_table = LED_0F + LED[0];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x01);

    RCLK = 0;
    RCLK = 1;
    //顯示第2位
    led_table = LED_0F + LED[1];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x02);

    RCLK = 0;
    RCLK = 1;
    //顯示第3位
    led_table = LED_0F + LED[2];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x04);

    RCLK = 0;
    RCLK = 1;
    //顯示第4位
    led_table = LED_0F + LED[3];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x08);

    RCLK = 0;
    RCLK = 1;
    //顯示第5位
    led_table = LED_0F + LED[4];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x10);

    RCLK = 0;
    RCLK = 1;
    //顯示第6位
    led_table = LED_0F + LED[5];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x20);

    RCLK = 0;
    RCLK = 1;
    //顯示第7位
    led_table = LED_0F + LED[6];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x40);

    RCLK = 0;
    RCLK = 1;
    //顯示第8位
    led_table = LED_0F + LED[7];
    i = *led_table;

    LED_OUT(i);
    LED_OUT(0x80);

    RCLK = 0;
    RCLK = 1;
}

void LED_OUT(uchar X)
{
    uchar i;
    for(i=8; i>=1; i--)
    {
        if (X&0x80) DIO=1;
        else DIO=0;
        X<<=1;
        SCLK = 0;
        SCLK = 1;
    }
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:155507 發(fā)表于 2020-6-15 09:55 | 只看該作者
你這個(gè)程序沒(méi)錯(cuò),估計(jì)其他地方錯(cuò)了,硬件搭建有錯(cuò)漏。

沒(méi)有原理圖、沒(méi)有實(shí)物,誰(shuí)能知道怎么來(lái)找問(wèn)題
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表