單片機(jī)·實(shí)時(shí)時(shí)鐘DS1302
DS1302的在實(shí)時(shí)顯示時(shí)間中的應(yīng)用。它可以對(duì)年、月、日、周、時(shí)、分、秒進(jìn)行計(jì)時(shí),且具有閏年補(bǔ)償?shù)榷喾N功能。
Vcc2:電源
Vcc1:后備電源,斷電后可以繼續(xù)工作
GND:電源地
X1,X2:振蕩源,外接32.768kHz晶振
RST:片選信號(hào)
SCLK:讀寫控制字節(jié)
I/O:串行數(shù)據(jù)輸入輸出
2. DS1302的控制字節(jié)
bit7:必須是1,否則不能寫入數(shù)據(jù) (可以類比LCD1602檢測(cè)忙閑)
bit6:0,存儲(chǔ)時(shí)鐘數(shù)據(jù);1,存儲(chǔ)RAM數(shù)據(jù)
bit1-5:指示操作單元的地址
bit0:0,表示寫;1,表示讀
控制字節(jié)從低位開始輸出
下面附一張英文表,感覺比中文的全面一點(diǎn),就是難看
3.數(shù)據(jù)流(可參照時(shí)序)
1)RST=1時(shí),DS1302才可被寫入數(shù)據(jù),才可被操作;RST=0時(shí),DS1302會(huì)終止數(shù)據(jù)傳輸,變?yōu)楦咦锠顟B(tài);
2)SCK上升沿讀地址,SCK下降沿讀數(shù)據(jù);
3)控制字節(jié)輸入后下一個(gè)SCLK時(shí)鐘的上升沿時(shí),數(shù)據(jù)被寫入DS1302,從低位開始。
二、實(shí)驗(yàn)
程序1:用DS1302實(shí)現(xiàn)時(shí)鐘計(jì)時(shí)
main.h
# ifndef _MAIN_H_
# define _MAIN_H_
# include
# include
sbit SCK = P3^5 ;
sbit SDA = P3^4 ;
sbit RST = P1^7 ;
typedef unsigned char uint8 ;
typedef unsigned int uint16 ;
uint8 time[7]={50,59,23,15,8,7,10} ;
# define ds1302_w_addr 0x80
# define ds1302_r_addr 0x81
# endif
main.c
# include "main.h"
void delay(uint16 n)
{
while(n--) ;
}
void reset_ds1302(void)
{
RST = 0 ;
SCK = 0 ;
RST = 1 ;
}
void write_ds1302_byte(uint8 dat)
{
uint8 i ;
for(i=0; i<8; i++)
{
SDA = dat&0x01 ;
dat>>=1 ;
SCK = 1 ;
SCK = 0 ;
}
}
uint8 read_ds1302_byte(void)
{
uint8 i,dat=0 ;
for(i=0; i<8; i++)
{
dat>>=1 ;
if(SDA)
dat |= 0x80 ;
SCK = 1 ; //這里注意SCK = 1 ,SCK = 0必須連寫,不然會(huì)導(dǎo)致輸出出錯(cuò),不知原因
SCK = 0 ;
}
return dat ;
}
void clear_ds1302_wp(void)
{
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(0x8E) ;
write_ds1302_byte(0) ;
SDA = 0 ;
RST = 0 ;
}
void set_ds1302_wp(void)
{
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(0x8E) ;
write_ds1302_byte(0x80) ;
SDA = 0 ;
RST = 0 ;
}
void write_ds1302(uint8 addr, uint8 dat)
{
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(addr) ;
write_ds1302_byte(dat) ;
SDA = 0 ;
RST = 0 ;
}
uint8 read_ds1302(uint8 addr)
{
uint8 temp=0 ;
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(addr) ;
temp = read_ds1302_byte() ;
SDA = 0 ;
RST = 0 ;
return temp ;
}
void set_time(uint8 *timedata)
{
uint8 i, tmp ;
for(i=0; i<7; i++)
{
tmp = timedata[i]/10 ; //轉(zhuǎn)為BCD碼,這里注意對(duì)于DS1302數(shù)據(jù)的讀取,必
timedata[i] = timedata[i] % 10 ; // 須轉(zhuǎn)換成BCD的格式
timedata[i] = tmp*16 + timedata[i] ;
}
clear_ds1302_wp() ;
tmp = ds1302_w_addr ;
for(i=0; i<7; i++)
{
write_ds1302(tmp,timedata[i]) ;
tmp+=2 ;
}
set_ds1302_wp() ;
}
void read_time(uint8 *timedata)
{
uint8 i, tmp ;
tmp = ds1302_r_addr ; //寫地址,讀數(shù)據(jù)
for(i=0; i<7; i++)
{
timedata[i] = read_ds1302(tmp) ;
tmp+=2 ;
}
}
void uart_init()
{
SCON = 0x50 ;
TMOD = 0x21 ; //這里我原本設(shè)置了timer0的方式2,但是無效;
TH1 = 0xFD ; //可能我個(gè)人的單片機(jī)出了點(diǎn)問題,改成timer1就可以了
TL1 = 0xFD ;
TR1 = 1 ;
}
void UART_send_byte(uint8 byte)
{
SBUF = byte ;
while(!TI) ;
TI = 0 ;
}
void UART_send_dat(uint8 dat)
{
UART_send_byte(dat/16 + 0) ;
UART_send_byte(dat + 0) ;
}
void main(void)
{
uart_init() ;
set_time(&time) ;
while(1)
{
read_time(&time) ; //指針的概念,這里必須使用&time,因?yàn)橹羔槻荒茏黾臃?/div>
//可以傳輸?shù)刂?timedata,讓timedata【i】去運(yùn)算
UART_send_dat(time[6]) ;
UART_send_byte(-) ;
UART_send_dat(time[4]) ;
UART_send_byte(-) ;
UART_send_dat(time[3]) ;
UART_send_byte( ) ;
UART_send_dat(time[2]) ;
UART_send_byte(:) ;
UART_send_dat(time[1]) ;
UART_send_byte(:) ;
UART_send_dat(time[0]) ;
UART_send_byte() ;
UART_send_byte() ;
delay(10000) ;
}
關(guān)鍵詞:
單片機(jī)實(shí)時(shí)時(shí)鐘DS130
相關(guān)推薦
技術(shù)專區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線
- 開關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論