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

QQ登錄

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

搜索
查看: 4329|回復(fù): 10
收起左側(cè)

關(guān)于單片機(jī)驅(qū)動(dòng)DS1307與數(shù)碼管顯示程序問(wèn)題

[復(fù)制鏈接]
ID:709561 發(fā)表于 2020-9-24 17:15 | 顯示全部樓層 |閱讀模式
50黑幣
最近師傅交給實(shí)時(shí)時(shí)鐘學(xué)習(xí),不講解不提示總之自己搞定,IIC協(xié)議早期學(xué)過(guò),可是DS1307實(shí)在是頭疼得很,不知是什么原因無(wú)法在數(shù)碼管顯示正確的時(shí)間,資料也查了很多還是沒(méi)有頭緒,已陷入死胡同無(wú)法走出,已經(jīng)第3天了還是束手無(wú)策,實(shí)屬無(wú)奈,望各位大師給予幫助不勝感激!!
P0數(shù)碼管顯示,74HC595控制數(shù)碼管位碼。年,月,日,時(shí),分,秒,星期。

單片機(jī)源程序如下:
#include <reg52.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit sda=P2^0;//;模擬I2C 數(shù)據(jù)傳送位
sbit scl=P2^1;//;模擬I2C 時(shí)鐘控制狀態(tài)標(biāo)志
sbit SER  = P1^2;    //數(shù)據(jù)輸入
sbit SCK  = P1^0;    //串行移位時(shí)鐘
sbit RCK  = P1^1;    //鎖存器時(shí)鐘
sbit tiao=P1^3;  //調(diào)節(jié)鍵
sbit jia =P1^4;  //按鍵+
sbit jian=P1^5;  //按鍵-
uchar Hours,Minutes,Seconds,Year,Month,Date,Weeks;

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar data dis_buf[]={0,0,0xbf,0,0,0xbf,0,0};//顯示緩存

void hc595(uchar Data)//74HC595的數(shù)據(jù)串入并出子程序
{
        uchar i;            
        for(i=0;i<8;i++)        //由高位到低位發(fā)送一個(gè)字節(jié)
        {
                Data<<=1;                //左移一位,最高位溢出到位寄存器CY
                SER=CY;                        //從位寄存器的進(jìn)位標(biāo)志位CY讀取
                SCK = 0;                        //串行移位
                SCK = 1;
        }
   RCK = 0;                         //鎖存
   RCK = 1;
}

uchar Decimal_to_BCD(uchar temp)//十進(jìn)制轉(zhuǎn)換成BCD碼
{
uchar a,b,c;
        a=temp;
        b=0;
        while(a>=10)
                {
                        a=a-10;
                        b=b+16;
                        c=a+b;
                        temp=c;
                }         
        return temp;
}
uchar BCD_to_Decimal(uchar temp)//BCD碼轉(zhuǎn)換成十進(jìn)制
{
        uchar a,b,c;
        a=temp;
        b=0;
        while(a>=16)
                {
                        a=a-16;
                        b=b+10;
                        c=a+b;
                        temp=c;
                }         
        return temp;
}
void delay_5us()//5us延時(shí)
{
        _nop_();
        _nop_();
        _nop_();
}
void star_1307()//開(kāi)始
{
        sda=1;
        delay_5us();//5us延時(shí)
        scl=1;
        delay_5us();//5us延時(shí)
        sda=0;
        delay_5us();//5us延時(shí)
}
void stop_1307()//停止
{
        sda=0;
        delay_5us();//5us延時(shí)
        scl=1;
        delay_5us();//5us延時(shí)
        sda=1;
        delay_5us();//5us延時(shí)
}
void ack_1307()//應(yīng)答
{
uchar z=0;
        while((sda==1)&&(z<50))z++;//條件判斷, sda=1,則沒(méi)有應(yīng)答。如果沒(méi)有應(yīng)答則延時(shí):z<50,z++;后返回
        scl=0;
        delay_5us();//5us延時(shí)
}
void write_1307(uchar slave_write_address,uchar byte_address,uchar data_data)//寫一個(gè)數(shù)據(jù)
{
uchar temp,temp1,i,ii;
        star_1307();                                //開(kāi)始
        for(ii=0;ii<3;ii++)//根據(jù) 24CXX文檔資料,和時(shí)序圖,按順序送:器件寫地址,字節(jié)地址,數(shù)據(jù)
        {
                if(ii==0)
                {
                        temp=slave_write_address;//送 器件寫地址
                        temp1=slave_write_address;
                }
                else if(ii==1)
                {
                        temp=byte_address;//送 字節(jié)地址
                        temp1=byte_address;
                }
                else if(ii==2)
                {
                        temp=data_data;//送 數(shù)據(jù)
                        temp1=data_data;
                }
                for(i=0;i<8;i++)
                {
                        scl=0;
                        delay_5us();//5us延時(shí)
                        temp=temp1;
                        temp=temp&0x80;//相 與 后,把不相關(guān)的位清零
                        if(temp==0x80)//根據(jù)前面 相 與 后,判斷 temp是否等于0x80,是則該位為 1                        
                                sda=1;
                        else
                                sda=0;
                        
                        delay_5us();//5us延時(shí)
                        scl=1;
                        delay_5us();//5us延時(shí)
                        scl=0;
                        delay_5us();//5us延時(shí)
                        temp1=temp1<<1;//向左移出1位
                        
                }
                sda=1;
                delay_5us();//5us延時(shí)
                scl=1;
                delay_5us();//5us延時(shí)
                ack_1307();
        }
        stop_1307();//停止
}
uchar read_1307(uchar slave_write_address,uchar byte_address,uchar slave_read_address)  //讀一個(gè)數(shù)據(jù)
{
uchar temp,temp1,i,ii,x,data_data;
        star_1307();         //開(kāi)始
        for(ii=0;ii<3;ii++)  //根據(jù) 24CXX文檔資料,和時(shí)序圖,按順序送:器件寫地址,字節(jié)地址,器件讀地址
        {
                if(ii==0)
                        {
                        temp=slave_write_address;  //送 器件寫地址
                        temp1=slave_write_address;
                        }
                else if(ii==1)
                        {
                        temp=byte_address;        //送 字節(jié)地址
                        temp1=byte_address;
                        }
                else if(ii==2)
                        {
                        star_1307();              //開(kāi)始
                        temp=slave_read_address;  //送 器件讀地址
                        temp1=slave_read_address;
                        }
                for(i=0;i<8;i++)              //開(kāi)始讀數(shù)據(jù)
                        {
                                scl=0;
                                delay_5us();          //5us延時(shí)
                                temp=temp1;
                                temp=temp&0x80;       // 相 與 后,把不相關(guān)的位清零
                                if(temp==0x80)        //根據(jù)前面 相 與 后,判斷 temp是否等于0x80,是則該位為 1
                                
                                sda=1;
                                else
                                sda=0;
                                
                                delay_5us();          //5us延時(shí)
                                scl=1;
                                delay_5us();          //5us延時(shí)
                                scl=0;
                                delay_5us();          //5us延時(shí)
                                temp1=temp1<<1;       //向左移出1位
                        }
                sda=1;
                delay_5us();                 //5us延時(shí)
                scl=1;
                delay_5us();                 //5us延時(shí)
                ack_1307();                  //應(yīng)答
        }
        for(x=0;x<8;x++)
        {
                data_data=data_data<<1;     //向左移入1位
                sda=1;
                delay_5us();                //5us延時(shí)
                scl=0;
                delay_5us();                //5us延時(shí)
                scl=1;
                delay_5us();                //5us延時(shí)
                if(sda==1)                  //判斷 數(shù)據(jù)線是否是高電平
                data_data|=0x01;            //把讀到的數(shù)據(jù) 或 0X01
        }
        ack_1307();                     //應(yīng)答
        stop_1307();                    //停止
        return data_data;               //返回讀到的數(shù)據(jù)
}
void init_1307()                    //初始化
{
        Hours=23;
        Minutes=14;
        Seconds=11;
        Year=17;   
        Month=11;
        Date=24;
        Weeks=5;        
        Seconds=Decimal_to_BCD(Seconds);  //十進(jìn)制轉(zhuǎn)換成BCD碼
        Minutes=Decimal_to_BCD(Minutes);  //十進(jìn)制轉(zhuǎn)換成BCD碼
        Hours=Decimal_to_BCD(Hours);      //十進(jìn)制轉(zhuǎn)換成BCD碼
        Date=Decimal_to_BCD(Date);        //十進(jìn)制轉(zhuǎn)換成BCD碼
        Year=Decimal_to_BCD(Year);        //十進(jìn)制轉(zhuǎn)換成BCD碼
        Month=Decimal_to_BCD(Month);      //十進(jìn)制轉(zhuǎn)換成BCD碼

        write_1307(0xd0,0x00,Seconds);    //寫入秒
        write_1307(0xd0,0x01,Minutes);    //寫入分
        write_1307(0xd0,0x02,Hours);      //寫入時(shí)
        write_1307(0xd0,0x03,Weeks);      //寫入星期
        write_1307(0xd0,0x04,Date);       //寫入日期
        write_1307(0xd0,0x05,Month);      //寫入月         
        write_1307(0xd0,0x06,Year);       //寫入年
}
void read_time_1307()
{
        Seconds=read_1307(0xd0,0x00,0xd1);          //讀秒
        Seconds=BCD_to_Decimal(Seconds);     //BCD碼轉(zhuǎn)換成十進(jìn)制
        Minutes=read_1307(0xd0,0x01,0xd1);          //讀分
        Minutes=BCD_to_Decimal(Minutes);     //BCD碼轉(zhuǎn)換成十進(jìn)制         
        Hours=read_1307(0xd0,0x02,0xd1);          //讀時(shí)
        Hours=BCD_to_Decimal(Hours);         //BCD碼轉(zhuǎn)換成十進(jìn)制

        Year=read_1307(0xd0,0x06,0xd1);          //讀年
        Year=BCD_to_Decimal(Year);           //BCD碼轉(zhuǎn)換成十進(jìn)制
        Date=read_1307(0xd0,0x04,0xd1);          //讀日
        Date=BCD_to_Decimal(Date);           //BCD碼轉(zhuǎn)換成十進(jìn)制
        Month=read_1307(0xd0,0x05,0xd1);     //讀月
        Month=BCD_to_Decimal(Month);         //BCD碼轉(zhuǎn)換成十進(jìn)制
        Weeks=read_1307(0xd0,0x03,0xd1);         //讀周
}



回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2020-9-25 10:26 | 顯示全部樓層
問(wèn)題描述不是很清楚,通常寫程序或調(diào)試程序是這樣的,首先用某固定值去調(diào)好數(shù)碼管,因?yàn)槭侨藱C(jī)交互的界面,調(diào)好數(shù)碼管顯示無(wú)誤后才去調(diào)要顯示的內(nèi)容,也就是分步設(shè)計(jì)或調(diào)試。
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2020-9-25 10:28 | 顯示全部樓層
也就是功能要一塊一塊的完成,已經(jīng)完成了的功能就不用去考慮有問(wèn)題出現(xiàn)。
回復(fù)

使用道具 舉報(bào)

ID:709561 發(fā)表于 2020-9-25 11:14 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-9-25 10:26
問(wèn)題描述不是很清楚,通常寫程序或調(diào)試程序是這樣的,首先用某固定值去調(diào)好數(shù)碼管,因?yàn)槭侨藱C(jī)交互的界面, ...

是的,就是調(diào)試的時(shí)候數(shù)碼管不是沒(méi)有顯示就是亂碼,還是DS1307與數(shù)碼管程序銜接的問(wèn)題是自己沒(méi)有辦法解決,理解的不夠透徹,才導(dǎo)致問(wèn)題產(chǎn)生無(wú)法解決,是否有文獻(xiàn)或參考類給予借鑒,不勝感激。。
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2020-9-25 11:29 | 顯示全部樓層
DS1307我自己沒(méi)用過(guò),擺渡資料看也不是很理解什么叫做閏年補(bǔ)償,這個(gè)閏年補(bǔ)償是指陰歷?看資料也沒(méi)提到陰歷,若是指陽(yáng)歷陽(yáng)歷閏年是固定的沒(méi)什么好補(bǔ)償?shù),不是很了解這塊芯片。我說(shuō)過(guò)了先用固定值去調(diào)試數(shù)碼管,完成數(shù)碼管功能塊后再去調(diào)試讀取。DS1307電路圖擺渡有,需要我?guī)湍闼阉鳎?/td>
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2020-9-25 11:43 | 顯示全部樓層
其實(shí)我認(rèn)為蛋騙雞只要提供標(biāo)準(zhǔn)的秒信號(hào)就可以了,目前蛋騙雞使用中斷作為計(jì)時(shí)器會(huì)受影響,因此,要外部芯片;
我的思路是蛋騙雞可設(shè)計(jì)一功能提供一不受任何影響的秒信號(hào)存儲(chǔ)空間,調(diào)用時(shí)就是讀取秒數(shù)據(jù),可預(yù)制秒內(nèi)容,其他的分,時(shí),星期,日,月,年都可寫程序?qū)崿F(xiàn)。
回復(fù)

使用道具 舉報(bào)

ID:96682 發(fā)表于 2020-9-25 15:27 來(lái)自手機(jī) | 顯示全部樓層
陽(yáng)歷的閏年只是多天,農(nóng)歷就不同了幾年會(huì)多一個(gè)閏月。樓主說(shuō)的亂碼是否用錯(cuò)數(shù)碼管?。
回復(fù)

使用道具 舉報(bào)

ID:709561 發(fā)表于 2020-9-25 16:00 | 顯示全部樓層
wc86110 發(fā)表于 2020-9-25 15:27
陽(yáng)歷的閏年只是多天,農(nóng)歷就不同了幾年會(huì)多一個(gè)閏月。樓主說(shuō)的亂碼是否用錯(cuò)數(shù)碼管?。

數(shù)碼管是對(duì)的我確定沒(méi)有使用錯(cuò)誤,就是提取DS1307的時(shí)間年月日就是無(wú)法顯示正確
回復(fù)

使用道具 舉報(bào)

ID:709561 發(fā)表于 2020-9-25 16:02 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-9-25 10:28
也就是功能要一塊一塊的完成,已經(jīng)完成了的功能就不用去考慮有問(wèn)題出現(xiàn)。

是的,就是調(diào)試到數(shù)碼管與DS1307銜接的程序,無(wú)論如何改寫都無(wú)法顯示正確???
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2020-9-25 16:13 | 顯示全部樓層
那就先測(cè)試讀芯片一個(gè)值測(cè)試通訊是否正確。
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2020-9-26 09:26 | 顯示全部樓層
這是在本壇找的帖子,是一個(gè)DS1307.H文件,經(jīng)移植仿真測(cè)試原作者的源碼寫得很好。只要添加按鍵和顯示函數(shù)就能成為一個(gè)萬(wàn)年歷。鏈接http://www.torrancerestoration.com/bbs/dpj-152422-1.html
無(wú)標(biāo)題.jpg
測(cè)試程序 仿真.zip (153.83 KB, 下載次數(shù): 26)





回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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