導航:首頁 > 操作系統 > ds130251單片機

ds130251單片機

發布時間:2022-06-17 11:22:52

A. 51單片機和ds1302之間使用什麼協議通信,是怎麼通信的

51和DS1302之間是串列通訊,具體通訊協議和時序,請參看附件的DataSheet文檔(英文)。

pdf" wealth="1" />

B. 基於51單片機的數字時鍾為什麼用DS1302

因為DS1302比較精準,而且價錢又便宜比DS12C887便宜好多,而且又可以接備用電源電池

C. 51單片機 DS1302時鍾程序求助

void DS1302_WriteData(uchar cmd , uchar dat)//寫數據指令,參數是命令和數據
{
uchar j,k=1;
RST=0;
SCLK=0;
RST=1;
for(j=0;j<=7;j++) //寫控制字
{
if(cmd&k) //取cmd的第j位,並寫到數據線上
DATA=1;
else
DATA=0;
SCLK=1; // 時鍾高
k<<=1;// 取第J位
SCLK=0; //SCLK低
}
k=1;// 從低位開始
for(j=0;j<=7;j++) //寫數據
{
if(dat&k)
DATA=1;
else
DATA=0;
SCLK=1;
k<<=1;
SCLK=0;
}
SCLK=1;
RST=0;
}

D. 51單片機中DS1302晶元的引腳配置原理是什麼

CE和SCLK是DS1302晶元的信號線,但也是與單片機的PIO口連接的;
因此初始化CE和SCLK,也就是初始化單片機的PIO口了;
在代碼中,你可以去看看 DS1302_CE、DS1302_SCLK 的定義就明白了;

E. 我用DS1302時鍾晶元用51單片機怎麼時間越走越快應該怎樣調整謝謝各位大神幫忙

DS1302時鍾的快慢與外接的晶振頻率有關,如果越走越快的話,可能是輸入的頻率發生了變化。

F. 51單片機 外接DS1302

一個是單片機外接晶體,提供單片機工作頻率用,多是4M-20M的頻率。
一個專門的時鍾晶元DS1302專用外接晶體,這種晶體都比較准確穩定,來減少時鍾誤差。。
DS1302專用晶體頻率是32.768kHz,無法和單片機晶體通用。

G. 51單片機控制DS1302,時間顯示在數碼管上。

1302.c

#include<DS1302.h>

#include<key.h>

ucharbit_ser[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

ucharseven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

/***********************時間顯示*****************/

voidtimer0_init(void) //T0初始化函數,用於時間的動態顯示

{

TMOD=0x21;

TL0=(65536-5000)%256;

TH0=(65536-5000)/256;

EA=1;

ET0=1;

TR0=1;

}

voidtimer0_isr(void)interrupt1 //T0中斷處理函數

{

charflag; //flag用於表示調整時閃爍的亮或滅

TR0=0;

TL0=(65536-5000)%256;

TH0=(65536-5000)/256;

TR0=1;

flag=x/100*0xff; //設置閃爍標志,如果x大於100則flag為0xff,小於100則為0x00

x++;

if(x>200)

x=0;

switch(i)

{

case0:

P2=bit_ser[0];

if(setflag==3) //根據setflag的值判斷當前位是否需要閃爍

P0=flag|seven_seg[dis_buffer[0]];

else

P0=seven_seg[dis_buffer[0]];

break;

case1:

P2=bit_ser[1];

if(setflag==3)

P0=flag|seven_seg[dis_buffer[1]];

else

P0=seven_seg[dis_buffer[1]];

break;

case2:

P2=bit_ser[2];

if(setflag==2)

P0=flag|seven_seg[dis_buffer[2]];

else

P0=seven_seg[dis_buffer[2]];

break;

case3:

P2=bit_ser[3];

if(setflag==2)

P0=flag|seven_seg[dis_buffer[3]];

else

P0=seven_seg[dis_buffer[3]];

break;

case4:

P2=bit_ser[4];

if(setflag==1)

P0=flag|seven_seg[dis_buffer[4]];

else

P0=seven_seg[dis_buffer[4]];

break;

case5:

P2=bit_ser[5];

if(setflag==1)

P0=flag|seven_seg[dis_buffer[5]];

else

P0=seven_seg[dis_buffer[5]];

break;

}

i++;

if(i>=6)

{

i=0;

if(j==10)

{

j=0;

if(setflag==0)

DS1302_GetTime(&Time); //如果setflag是0,就從1302中讀出時間,因為setflag不是0時,說明處於調整狀態,不需要讀時間

dis_buffer[5]=Time.Second%10; //把當前時間放入顯示緩沖區

dis_buffer[4]=Time.Second/10;

dis_buffer[3]=Time.Minute%10;

dis_buffer[2]=Time.Minute/10;

dis_buffer[1]=Time.Hour%10;

dis_buffer[0]=Time.Hour/10;

}

j++;

}

}

voidmain()

{

Initial_DS1302(Time);

timer0_init();

while(1)

{

set_down();

timer_down();

up_down();

down_down();

beepflag_down();

if(setflag==0&&Time.Hour==romhour&&Time.Minute==romminute&&Beepflag==1) //判斷蜂鳴器是否要響

Beep=!Beep;

}

}

//key.c

#include<reg51.h>

#defineucharunsignedchar

#defineuintunsignedint

uchari=0,j=0,x=0,setflag,flag_set,flag_timer;//setflag用來表示調整的位置,flag_set和flag_timer分別表示當前處於調整狀態還是定時狀態

SYSTEMTIMETime={0,20,15,3,30,6,10}; //系統時間的初始值2010年6月30日星期三,15時20分0秒

chardis_buffer[6]; //存放顯示數據的緩沖區

sbitBeep_flag=P3^2; //蜂鳴器的介面

sbitkey_timer=P3^4; //定時按鈕

sbitkey_set=P3^5; //調整按鈕

sbitkey_up=P3^6; //增加按鈕

sbitkey_down=P3^7; //減小按鈕

charromhour,romminute,romsec; //分別存放定時的時,分,秒

bitBeepflag; //標記鬧鍾是否開啟

//延時函數

voiddelays(ucharx)

{

while(x)x--;

}

//設置鍵的處理函數

voidset()

{

setflag++;

flag_set=1;

if(setflag>=4)

{

setflag=0;

flag_set=0;

Initial_DS1302(Time);

}

}

//定時間的處理函數

voidtimer()

{

setflag++;

flag_timer=1;

if(setflag==1)

{

Time.Hour=romhour;

Time.Minute=romminute;

Time.Second=romsec;

}

elseif(setflag>=4)

{

setflag=0;

flag_timer=0;

romhour=Time.Hour;

romminute=Time.Minute;

romsec=Time.Second;

}

}

//增加鍵的處理函數

voip()

{

switch(setflag)

{

case0:

break;

case1:

Time.Second++;

if(Time.Second>=60)

Time.Second=0;

break;

case2:

Time.Minute++;

if(Time.Minute>=60)

Time.Minute=0;

break;

case3:

Time.Hour++;

if(Time.Hour>=24)

Time.Hour=0;

break;

}

}

//減小鍵的處理函數

voiddown()

{

switch(setflag)

{

case0:

break;

case1:

Time.Second--;

if(Time.Second<0)

Time.Second=59;

break;

case2:

Time.Minute--;

if(Time.Minute<0)

Time.Minute=59;

break;

case3:

Time.Hour--;

if(Time.Hour<0)

Time.Hour=23;

break;

}

}

//設置鍵的掃描函數

voidset_down()

{

if(key_set==0&&flag_timer==0)

{

delays(100);

if(key_set==0)

{

set();

}

while(!key_set);

}

}

//定時鍵的掃描函數

voidtimer_down()

{

if(key_timer==0&&flag_set==0)

{

delays(100);

if(key_timer==0)

{

timer();

}

while(!key_timer);

}

}

//增加鍵的掃描函數

voip_down()

{

if(key_up==0&&setflag!=0)

{

delays(100);

if(key_up==0)

{

up();

while(!key_up);

}

}

}

//減少鍵的處理函數

voiddown_down()

{

if(key_down==0&&setflag!=0)

{

delays(100);

if(key_down==0)

{

down();

while(!key_down);

}

}

}

//定時開關的掃描處理函數

voidbeepflag_down()

{

if(Beep_flag==0)

{

delays(100);

{

Beepflag=!Beepflag;

while(!Beep_flag);

}

}

}

//ds1302.h

#ifndef_REAL_TIMER_DS1302

#define_REAL_TIMER_DS1302

#include<REG51.h>

sbitDS1302_CLK=P1^1;//實時時鍾時鍾線引腳

sbitDS1302_IO=P1^2;//實時時鍾數據線引腳

sbitDS1302_RST=P1^3;//實時時鍾復位線引腳

sbitACC0=ACC^0;

sbitACC7=ACC^7;

sbitBeep=P2^7;

typedefstruct__SYSTEMTIME__

{ charSecond;

charMinute;

charHour;

charWeek;

charDay;

charMonth;

charYear;

}SYSTEMTIME; //定義的時間類型

#defineAM(X) X

#definePM(X) (X+12) //轉成24小時制

#defineDS1302_SECOND 0x80//秒寄存器

#defineDS1302_MINUTE 0x82//分寄存器

#defineDS1302_HOUR 0x84

#defineDS1302_WEEK 0x8A

#defineDS1302_DAY 0x86

#defineDS1302_MONTH 0x88

#defineDS1302_YEAR 0x8C

#defineDS1302_RAM(X) (0xC0+(X)*2) //用於計算DS1302_RAM地址的宏

voidDS1302InputByte(unsignedchard) //實時時鍾寫入一位元組(內部函數)

{unsignedchari;

ACC=d;

for(i=8;i>0;i--)

{ DS1302_IO=ACC0; //相當於匯編中的RRC

DS1302_CLK=1;

DS1302_CLK=0;//發一個高跳變到低的脈沖

ACC=ACC>>1;

}

}

unsignedcharDS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數)

{ unsignedchari;

for(i=8;i>0;i--)

{ ACC=ACC>>1; //相當於匯編中的RRC

ACC7=DS1302_IO;

DS1302_CLK=1;

DS1302_CLK=0;//發一個高跳變到低的脈沖

}

return(ACC);

}

voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:DS1302地址,ucData:要寫的數據

{ DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;

DS1302InputByte(ucAddr); //地址,命令

DS1302InputByte(ucDa); //寫1Byte數據

DS1302_CLK=1;

DS1302_RST=0;//RST0->1->0,CLK0->1

}

unsignedcharRead1302(unsignedcharucAddr) //讀取DS1302某地址的數據

{ unsignedcharucData;

DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;//enable

DS1302InputByte(ucAddr|0x01);//地址,命令

ucData=DS1302OutputByte();//讀1Byte數據

DS1302_CLK=1;//RST0->1->0,CLK0->1

DS1302_RST=0;

return(ucData);

}

voidDS1302_SetProtect(bitflag)//是否防寫

{ if(flag)

Write1302(0x8E,0x80);//WP=1,不能寫入

else

Write1302(0x8E,0x00);//WP=0,可以寫入

}

voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//設置時間函數

{ DS1302_SetProtect(0);

Write1302(Address,((Value/10)<<4|(Value%10)));//高4位為十位,低4位為個位

DS1302_SetProtect(1);

}

//獲取時間函數,從DS1302內讀取時間然後存入Time內

voidDS1302_GetTime(SYSTEMTIME*Time)

{ unsignedcharReadValue;

ReadValue=Read1302(DS1302_SECOND);

Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//轉換成10進制的秒

ReadValue=Read1302(DS1302_MINUTE);

Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_HOUR);

Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_DAY);

Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_WEEK);

Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_MONTH);

Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_YEAR);

Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

}

//利用STime初始化DS1302

voidInitial_DS1302(SYSTEMTIMESTime)

{ unsignedcharSecond=Read1302(DS1302_SECOND);

if(Second&0x80) DS1302_SetTime(DS1302_SECOND,0);//如果第七為1(表明沒有啟動),則啟動時鍾

DS1302_SetTime(DS1302_SECOND,STime.Second); //設定起始時間

DS1302_SetTime(DS1302_MINUTE,STime.Minute);

DS1302_SetTime(DS1302_HOUR,STime.Hour);

DS1302_SetTime(DS1302_DAY,STime.Day);

DS1302_SetTime(DS1302_MONTH,STime.Month);

DS1302_SetTime(DS1302_YEAR,STime.Year);

DS1302_SetTime(DS1302_WEEK,STime.Week);

}

#endif

H. 基於51單片機的數字時鍾為什麼用DS1302

你使用這樣的電路可以,前提是不掉電的情況下,而且精確度有待商榷,如果使用DS1302,內置時間寄存器,並可對時間進行校正,同時,如果對其加電池,那麼時間不會停止,一直走動,否則,按您的電路,你一關電,所有的時間你得重新設置。希望您明白我的意思。

I. 51單片機DS1302程序

void v_RTInputByte(uchar ucDa)
{
uchar i;
ACC = ucDa;
for(i=8; i>0; i--)
{
T_IO = ACC0; //相當於匯編中的 RRC
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
*
* 名稱: uchar uc_RTOutputByte
* 說明:
* 功能: 從DS1302讀取1Byte數據
* 調用:
* 輸入:
* 返回值: ACC
***********************************************************************/
uchar uc_RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相當於匯編中的 RRC
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
*
* 名稱: v_W1302
* 說明: 先寫地址,後寫命令/數據
* 功能: 往DS1302寫入數據
* 調用: v_RTInputByte()
* 輸入: ucAddr: DS1302地址, ucDa: 要寫的數據
* 返回值: 無
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); //地址,命令
v_RTInputByte(ucDa); //寫1Byte數據
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名稱: uc_R1302
* 說明: 先寫地址,後讀命令/數據
* 功能: 讀取DS1302某地址的數據
* 調用: v_RTInputByte() , uc_RTOutputByte()
* 輸入: ucAddr: DS1302地址
* 返回值: ucDa :讀取的數據
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); //地址,命令
ucDa = uc_RTOutputByte(); //讀1Byte數據
T_CLK = 1;
T_RST =0;
return(ucDa);
}
/********************************************************************
*
* 名稱: v_BurstW1302T
* 說明: 先寫地址,後寫數據(時鍾多位元組方式)
* 功能: 往DS1302寫入時鍾數據(多位元組方式)
* 調用: v_RTInputByte()
* 輸入: pSecDa: 時鍾數據地址 格式為: 秒 分 時 日 月 星期 年 控制
* 8Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B 1B
* 返回值: 無
***********************************************************************/
void v_BurstW1302T(uchar *pSecDa)
{
uchar i;
v_W1302(0x8e,0x00); //控制命令,WP=0,寫操作?
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbe); //0xbe:時鍾多位元組寫命令
for (i=8;i>0;i--) //8Byte = 7Byte 時鍾數據 + 1Byte 控制
{
v_RTInputByte(*pSecDa); //寫1Byte數據
pSecDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名稱: v_BurstR1302T
* 說明: 先寫地址,後讀命令/數據(時鍾多位元組方式)
* 功能: 讀取DS1302時鍾數據
* 調用: v_RTInputByte() , uc_RTOutputByte()
* 輸入: pSecDa: 時鍾數據地址 格式為: 秒 分 時 日 月 星期 年
* 7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
* 返回值: ucDa :讀取的數據
***********************************************************************/
void v_BurstR1302T(uchar *pSecDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbf); //0xbf:時鍾多位元組讀命令
for (i=8; i>0; i--)
{
*pSecDa = uc_RTOutputByte(); //讀1Byte數據
pSecDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名稱: v_BurstW1302R
* 說明: 先寫地址,後寫數據(寄存器多位元組方式)
* 功能: 往DS1302寄存器數寫入數據(多位元組方式)
* 調用: v_RTInputByte()
* 輸入: pReDa: 寄存器數據地址
* 返回值: 無
***********************************************************************/
void v_BurstW1302R(uchar *pReDa)
{
uchar i;
v_W1302(0x8e,0x00); //控制命令,WP=0,寫操作?
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xfe); //0xbe:時鍾多位元組寫命令
for (i=31;i>0;i--) //31Byte 寄存器數據
{
v_RTInputByte(*pReDa); //寫1Byte數據
pReDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名稱: uc_BurstR1302R
* 說明: 先寫地址,後讀命令/數據(寄存器多位元組方式)
* 功能: 讀取DS1302寄存器數據
* 調用: v_RTInputByte() , uc_RTOutputByte()
* 輸入: pReDa: 寄存器數據地址
* 返回值: 無
***********************************************************************/
void v_BurstR1302R(uchar *pReDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xff); //0xbf:時鍾多位元組讀命令
for (i=31; i>0; i--) //31Byte 寄存器數據
{
*pReDa = uc_RTOutputByte(); //讀1Byte數據
pReDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名稱: v_Set1302
* 說明:
* 功能: 設置初始時間
* 調用: v_W1302()
* 輸入: pSecDa: 初始時間地址。初始時間格式為: 秒 分 時 日 月 星期 年
* 7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 無
***********************************************************************/
void v_Set1302(uchar *pSecDa)
{
uchar i;
uchar ucAddr = 0x80;
v_W1302(0x8e,0x00); //控制命令,WP=0,寫操作?
for(i =7;i>0;i--)
{
v_W1302(ucAddr,*pSecDa); //秒 分 時 日 月 星期 年

pSecDa++;
ucAddr +=2;
}
v_W1302(0x8e,0x80); //控制命令,WP=1,防寫?
}
/********************************************************************
*
* 名稱: v_Get1302
* 說明:
* 功能: 讀取DS1302當前時間
* 調用: uc_R1302()
* 輸入: ucCurtime: 保存當前時間地址。當前時間格式為: 秒 分 時 日 月 星期 年
* 7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 無
***********************************************************************/
void v_Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
for (i=0;i<7;i++)
{
ucCurtime[i] = uc_R1302(ucAddr); //格式為: 秒 分 時 日 月 星期 年
ucAddr += 2;
}
}

J. 求助用51單片機加DS1302編寫定時器程序的問題

親,DS1302是實時時鍾晶元,定時器可以直接用單片機的內部定時器寫就可以了,沒必要用DS1302了,用它做個時鍾那還可以。DIY電子時鍾,我做過教程,有問題可以聯系。

閱讀全文

與ds130251單片機相關的資料

熱點內容
robinhood加密交易條件 瀏覽:310
衛生間解壓方法 瀏覽:450
u盤如何做加密文件放照片 瀏覽:327
文件夾自己加了exe 瀏覽:256
小豬cms直播系統源碼 瀏覽:876
山東廣電雲伺服器 瀏覽:350
javadate與mysqldate 瀏覽:242
javalong比較 瀏覽:9
加密大師看不見加密文件 瀏覽:305
想做一個業余程序員 瀏覽:791
python選出行 瀏覽:247
cat命令windows 瀏覽:908
python算術游戲 瀏覽:530
常微分方程第二版pdf 瀏覽:23
phpJava學多久 瀏覽:722
php博客畢業設計 瀏覽:794
資料庫編程pdf 瀏覽:905
靜態文件伺服器騰訊雲 瀏覽:848
怎麼讓安卓手機運行蘋果軟體 瀏覽:116
共同好友的演算法 瀏覽:574