PIC16F877驅動DS1302晶片

2021-01-17 電子產品世界

下面是原理圖

本文引用地址:

http://www.eepw.com.cn/article/201611/317661.htm

下面是程序頭文件

#ifndef DS1302_H
#define DS1302_H

#include "main.h"

#define Time_24_Hour0x00//24時制控制
#define Time_Start0x00//開始走時
#define Time_Stop0x80//停止走時

#define DS1302_SECOND0x80//DS1302各寄存器操作命令定義
#define DS1302_MINUTE0x82
#define DS1302_HOUR0x84
#define DS1302_WEEK0x8A
#define DS1302_DAY0x86
#define DS1302_MONTH0x88
#define DS1302_YEAR0x8C
#define DS1302_WRITE0x8E
#define DS1302_POWER0x90

#define BCD2DEC(X)(((X&0x70)>>4)*10 + (X&0x0F))//用於將BCD碼轉成十進位的宏
#define DEC2BCD(X)((X/10)<<4 | (X%10))//用於將十進位轉成BCD


#define RST RC0
#define DATA RC1
#define DS_CLK RC2
#define RST_DIR TRISC0
#define DATA_DIR TRISC1
#define SCLK_DIR TRISC2

typedef struct __SYSTEMTIME__//定義的時間類型結構體,全部數為十進位
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[11];
unsigned char TimeString[9];
}systemetime;

void init_ds1302() ;
void writebyte(uchar data) ;
uchar readbyte() ;
void ds_writedata(uchar add,uchar data) ;
uchar ds_readdata(uchar add) ;
void get_time(systemetime *Time) ;
void set_time(systemetime *Time) ;
void data2str(systemetime *Time) ;
void time2str(systemetime *Time) ;
#endif
子程序

#include "ds1302.h"
void init_ds1302()
{
RST_DIR=0 ;
DATA_DIR=0 ;
SCLK_DIR=0 ;

ds_writedata(DS1302_WRITE,0x00);//關閉防寫
ds_writedata(DS1302_SECOND,Time_Stop);//停止計時
ds_writedata(DS1302_HOUR,Time_24_Hour);//24時制
//ds_writedata(DS1302_POWER,0xA6);//單二極體,4K電阻充電
ds_writedata(DS1302_WRITE,0x80);//打開防寫
}

void writebyte(uchar data)
{
uchar i;
DATA_DIR=0 ;
for(i=0;i<8;i++)
{
if(data&0x01)
DATA=1 ;
else
DATA=0 ;
DS_CLK=1 ;
DS_CLK=0 ;
data=data>>1 ;
}
}
uchar readbyte()
{
uchar i,temp ;
DATA_DIR=1 ;
for(i=0 ;i<8;i++)
{
temp=temp>>1 ;
if(DATA)
temp=temp|0x80 ;
DS_CLK=1 ;
DS_CLK=0 ;
}
DATA_DIR=0 ;
return temp ;
}


void ds_writedata(uchar add,uchar data)
{
RST=0 ;
DS_CLK=0 ;
RST=1 ;
writebyte(add) ;
writebyte(data) ;
DS_CLK=1 ;
RST=0 ;

}
uchar ds_readdata(uchar add)
{
uchar temp ;
RST=0 ;
DS_CLK=0 ;
RST=1 ;
writebyte(add|0x01) ;
temp=readbyte() ;
DS_CLK=1 ;
RST=0 ;
}
void get_time(systemetime *Time)
{
unsigned char ReadValue;
ReadValue = ds_readdata(DS1302_SECOND);
Time->Second = BCD2DEC(ReadValue&0x7F);
ReadValue = ds_readdata(DS1302_MINUTE);
Time->Minute = BCD2DEC(ReadValue);
ReadValue = ds_readdata(DS1302_HOUR);
Time->Hour = BCD2DEC(ReadValue&0x7F);
ReadValue = ds_readdata(DS1302_DAY);
Time->Day = BCD2DEC(ReadValue);
ReadValue = ds_readdata(DS1302_WEEK);
Time->Week = BCD2DEC(ReadValue);
ReadValue = ds_readdata(DS1302_MONTH);
Time->Month = BCD2DEC(ReadValue);
ReadValue = ds_readdata(DS1302_YEAR);
Time->Year = BCD2DEC(ReadValue);
}
void set_time(systemetime *Time)
{
uchar temp ;
ds_writedata(DS1302_WRITE,0x00);//關閉防寫
temp=DEC2BCD(Time->Year) ;
ds_writedata(DS1302_YEAR,temp);
temp=DEC2BCD(Time->Month) ;
ds_writedata(DS1302_MONTH,temp);
temp=DEC2BCD(Time->Week) ;
ds_writedata(DS1302_WEEK,temp);
temp=DEC2BCD(Time->Day) ;
ds_writedata(DS1302_DAY,temp);
temp=DEC2BCD(Time->Hour)|Time_24_Hour ;
ds_writedata(DS1302_HOUR,temp);
temp=DEC2BCD(Time->Minute) ;
ds_writedata(DS1302_MINUTE,temp);
temp=DEC2BCD(Time->Second)|Time_Start ;
ds_writedata(DS1302_SECOND,temp);

ds_writedata(DS1302_WRITE,0x80);//打開防寫
}

void data2str(systemetime *Time)
{
//Year
Time->DateString[0] = 2;
Time->DateString[1] = 0;
Time->DateString[2] = Time->Year/10 + 0;
Time->DateString[3] = Time->Year%10 + 0;

Time->DateString[4] = /;
//Month
Time->DateString[5] = Time->Month/10 + 0;
Time->DateString[6] = Time->Month%10 + 0;
Time->DateString[7] = /;
//Day
Time->DateString[8] = Time->Day/10 + 0;
Time->DateString[9] = Time->Day%10 + 0;
Time->DateString[10] = /0; //字符串末尾加 /0 ,判斷結束字符
}
void time2str(systemetime *Time)
{
//Hout
Time->TimeString[0] = Time->Hour/10 + 0;
Time->TimeString[1] = Time->Hour%10 + 0;

Time->TimeString[2] = :;
//Minute
Time->TimeString[3] = Time->Minute/10 + 0;
Time->TimeString[4] = Time->Minute%10 + 0;

Time->TimeString[5] = :;
//Second
Time->TimeString[6] = Time->Second/10 + 0;
Time->TimeString[7] = Time->Second%10 + 0;
//
Time->DateString[8] = /0;
}
下面是測試程序

#include "main.h"
#include "ds1302.h"
void init_all()
{
init_ds1302() ;
}
void interrupt main_int()
{
;
}
systemetime tm ;
void main()
{
init_all() ;
tm.Day=19;
tm.Hour=13 ;
tm.Minute=4 ;
tm.Month=8 ;
tm.Year=9 ;
tm.Week=1 ;
set_time(&tm) ;
while(1)
{
get_time(&tm) ;
time2str(&tm) ;
data2str(&tm) ;
}
}

相關焦點

  • PIC16F877A DS1302晶片驅動
    本文引用地址:http://www.eepw.com.cn/article/201808/384806.htm本文大體介紹了PIC16F877A DS1302晶片驅動#includetypedefsck_l;//低電平時數據線可變if(dat0x01)io_h;elseio_l;sck_h;dat>>=1;}}uchar BCDtoDex(uchar dat)//BCD碼轉十進位{uchar i;i=dat/16
  • ATMEGA16四線驅動LCD顯示時間-DS1302
    _sec_add0x80//秒數據地址#define ds1302_min_add0x82//分數據地址#define ds1302_hr_add_WriteByte(ds1302_month_add,0x12); //月 DS1302_WriteByte(ds1302_day_add,0x04); //星期 DS1302_WriteByte(ds1302_date_add,
  • 淺談單片機c語言模塊化編程-附ds1302時鐘晶片驅動程序
    最終確定在ds1302_write_byte中。發現了一個很奇特的事情。錯誤是因為fou循環,我用for(i=0;i<8;i++)替換成為for(i=8;i>0;i--)解決了問題。extern可以置於變量或者函數前,以表示變量或者函數的定義在別的文件中,提示編譯器遇到此變量和函數時在其他模塊中尋找其定義。
  • PIC16F877A TIMER1計數操作
    /**********************Title:PIC16F877A TIMER1計數操作Author:hnrainDate:2010
  • DS1302時鐘晶片顯示時間C51程序
    /*程序效果:通過DS1302晶片顯示時間,本程序主要是要理解     DS1302晶片的協議,這樣便於編寫程序。     當然時間顯示也可以用單片機的定時器來控制,比起延時     子函數來說較精準。
  • 基於PIC16F877單片機的簡易測速計設計方案
    本文將基於PIC16F877 單片機的捕捉功能來完成脈衝計數,利用軟體編程實現相關物理關係的轉換,最終得出齒輪線速度,並顯示在數碼管上。  1 測速計原理  1.1 CCP1 捕捉功能  PIC16F877 單片機中有兩個CCP 模塊,其構造基本相同,分別記為CCP1 和CCP2.每個CCP 模塊可以任意配置為捕捉(Capture)、比較(Compare) 和脈寬調製(PWM)3 個功能模式之一。
  • SPI時鐘晶片DS1302的應用
    RST是復位/片選線,通過把RST輸入驅動置高電平來啟動所有的數據傳送。RST輸入有兩種功能:首先,RST接通控制邏輯,允許地址/命令序列送入移位寄存器;其次,RST提供終止單字節或多字節數據的傳送手段。當RST為高電平時,所有的數據傳送被初始化,允許對DS1302進行操作。如果在傳送過程中RST置為低電平,則會終止此次數據傳送,I/O引腳變為高阻態。
  • 關於PIC16F877A串口發送任意字符串的問題
    TRMT);TRMT = 0 ; //必須寫,不然有可能產生錯誤數據發送}//向串口發送一個字符串void send_string_com(uchar *str){uint16 k= 0 ;do{send_char_com(*(str + k));k++;
  • ds1302是什麼,ds1302引腳圖和寄存器詳解
    打開APP ds1302是什麼,ds1302引腳圖和寄存器詳解 發表於 2017-10-18 17:37:05   DS1302
  • ds1302引腳圖,ds1302引腳圖功能詳解
    打開APP ds1302引腳圖,ds1302引腳圖功能詳解 發表於 2017-10-19 15:39:22   DS1302是時鐘晶片
  • ds1302晶振不起振_ds1302晶振電路圖
    打開APP ds1302晶振不起振_ds1302晶振電路圖 發表於 2017-08-26 18:31:28   實時時鐘電路DS1302
  • ds1302帶鬧鐘功能的單片機控制的時鐘程序
    };uchar date1[7];uchar naozhong[7]={35,32,16,27,2,7,11};ucharflag,flag1,flag2;uchar code table0[]=" - - ";uchar code table1[]=" : : ";void lcd_com(uchar);void lcd_date(uchar
  • ds1302讀取數據問題分析及解決
    打開APP ds1302讀取數據問題分析及解決 發表於 2017-11-19 16:54:25   DS1302是由美國DALLAS
  • 用ds1302製作一個精密的電子時鐘
    題目:用ds1302製作一個精密的電子時鐘感想:我看視頻的時候講的是DS12CR887這塊晶片,兩塊畢竟是不一樣的,所以,我只是看了他講怎樣看時序,之後的就沒再看了。我就拿著自己下載列印的DS1302數據手冊,研習,研習,再研習。還查了書上的,網上的,源程序。
  • pic16f877a的電平變化中斷(interrupt on change)使用誤區
    如下面的例子:/*這是一個用INT中斷和電平變化中斷計光電編碼器(碼盤)的讀數*/voidinterrupt on_change(){if(INTF){f_r++;INTF=0;}if(RBIF&&RB4) //高電平計數{RB4=~RB4;//先讀取或寫入PORTB鎖存器的值
  • stm32與pic單片機比較_哪個好
    單片機特點   1、具有低工作電壓、低功耗、驅動能力強等特點。   2、當置位1時為輸入狀態,且不管該腳呈高電平或低電平,對外均呈高阻狀態;置位0時為輸出狀態,不管該腳為何種電平,均呈低阻狀態,有相當的驅動能力,低電平吸入電流達25mA,高電平輸出電流可達20mA。相對於51系列而言,這是一個很大的優點   3、它可以直接驅動數碼管顯示且外電路簡單。它的A/D為10位,能滿足精度要求。具有在線調試及編程(ISP)功能。
  • 單片機驅動DS1302時間DS18B20溫度12864液晶顯示完整程序設計
    程序說明:這是一個用51單片機驅動DS1302時間模塊+DS18B20溫度傳感器模塊+12864液晶顯示完整程序設計實例,有四個鍵盤KEY0 到KEY3,key0是修改時間的 首先是秒到分到時到年到月到日到星期 key1是加1 key2是減一 在修改時間狀態再按一下key3的時候就出去並修改時間日期,在平時狀態按著key3再按著key2 就會打開lcd 的燈 單單是只按key3那就是把燈關了
  • 實時時鐘晶片DS1302
    DS1302是一種三線制的串行時鐘晶片,即CE(片選),SCLK(時鐘),I/O(雙向數據)。同時SCLK 在RST 驅動至邏輯1 狀態時必須為邏輯0。2.數據輸入是在SCLK的上升沿,數據輸出是在SCLK的下降沿。3.傳輸方式:低位先傳輸。4.時鐘運行:秒寄存器的最高位(BIT7)是作為時鐘控制位,當為邏輯1時,時鐘停止,為0時鐘運行。
  • PIC16F877A.H頭文件詳細注釋
    /**Header file for the Microchip*PIC 16F873A chip*PIC 16F874A chip*PIC 16F876A chip*PIC 16F877A chip*Midrange Microcontroller*/本文引用地址:http://www.eepw.com.cn/article/
  • DS1302時鐘模塊的使用
    ds1302.h庫文件已經上傳,有需要的自行下載。注意ds1302.h要與zhy.h配合使用。接下來我詳細講解一下,ds1302.h庫文件的使用方法。uchar time_buf[8] = {0x20,0x10,0x06,0x01,0x23,0x59,0x55,0x02};//2010年6月1號23點59分55秒星期二注意,time_buf數組中只能為BCD碼,也就是只能為十進位,不能出現十六進位或者其它進位字符ds1302_init()函數是用來給DS1302進行初始化設置的