欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
驅動DS1302時鐘芯片通過數碼管顯示時間,時間可調
[打印本頁]
作者:
daming
時間:
2014-12-29 17:57
標題:
驅動DS1302時鐘芯片通過數碼管顯示時間,時間可調
/****************************************************************/
/******名字:DS1302**********************************************/
/******功能:驅動DS1302時鐘芯片通過數碼管顯示時間,時間可調******/
/******作者:WPM*************************************************/
/******修改日期:2010年7月21日***********************************/
/****************************************************************/
/*這是本人在外編寫的第一個程序,目的只有一個,就是方便以后直接調用,
我要徹底改變我以往編寫程序的風格,為自己這份新工作做準備*/
#include <reg52.h>//頭文件
#include <intrins.h>
#define uchar unsigned char//宏定義
#define uint unsigned int
sbit DS1302_SCL2=P1^3; //DS1302_SCL2定義為P1口的第3位腳,連接DS1302SCL和ADC0831SCL腳
sbit DS1302_SDA2=P1^4; //DS1302_SDA2定義為P1口的第4位腳,連接DS1302SCL和ADC0831SDA腳
sbit DS1302_RST = P1^5; // DS1302片選腳
sbit DS1302_SPK=P3^4; //定義蜂鳴器的引腳
uchar DS1302_tmpdate[8]={0x00,0x06,0x03,0x18,0x0c,0x07,0x06,0};//秒分時日月星期年
uchar DS1302_tmpdisplay[8]={0x40,0x40,0x40,0x40,0x40,0x40,0x40,0}; //顯示“-”
code uchar write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//寫秒分時日月星期年的地址
code uchar DS1302_Read_RTC_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //讀取秒分時日月星期年的地址
code uchar DS1302_table[]= //共陰數碼管 0-9 '-' '熄滅‘表
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x40,0x00};
uchar code DS1302_key_tab[]=
{0xed,0x7e,0x7d,0x7b,
0xbe,0xbd,0xbb,0xde,
0xdd,0xdb,0x77,0xb7,
0xee,0xd7,0xeb,0xe7};
//========================此數組為鍵盤編碼,
//本人采用類式類似電話按鍵的編碼方式,方便以后設計
// 1 2 3 a 0x01 0x02 0x03 0x0a
// 4 5 6 b 對應16進制碼: 0x04 0x05 0x06 0x0b
// 7 8 9 e 0x07 0x08 0x09 0x0e
// * 0 # f 0x0c 0x00 0x0e 0x0f
//打個比方,如果你按下0鍵,P0口讀到數據為0xed
//如果你按下2鍵,P0口讀到數據為0x7d,按下9鍵為0xdb,
//我們將讀到的P0口數據經過查表法就能得到相應的16進制碼
//鍵盤的讀取,我們采用分時掃描
void DS1302_delay();//延時子函數,5個空指令
void DS1302_display(uchar *lp,uchar lc);//數字的顯示函數;lp為指向數組的地址,lc為顯示的個數
void Write_Ds1302_byte(uchar temp);
void Write_Ds1302( uchar address,uchar dat );
uchar Read_Ds1302 ( uchar address );
void DS1302_Read_RTC();//read RTC
void DS1302_Set_RTC();//set RTC
void Ds1302Play(uchar tmp);
void Ds1302Menu();
uchar DS1302_keyold,DS1302_key=0xff,DS1302_keytmp=0;
/***************************************************/
/******名字:main***********************************/
/******功能:通過調用其它子函數,達到對應的功能*****/
/******作者:WPM************************************/
/******修改日期:2010年7月21日**********************/
/***************************************************/
void main() //入口函數
{
DS1302_RST=0;
DS1302_Set_RTC();
EA=1; //開啟總中斷
EX0=1; //開啟外部中斷 0
IT0=1; // 設置成 下降沿觸發方式
while(1)
{
Ds1302Menu();
}
}
/*************************************************/
/******名字:DS1302_display***********************/
/******功能:八個數碼管顯示的數值*****************/
/******作者:WPM**********************************/
/******修改日期:2010年7月21日********************/
/*************************************************/
void DS1302_display(uchar *lp,uchar lc)//顯示
{
uchar i; //定義變量
P2=0; //端口2為輸出
P1=P1&0xF8; //將P1口的前3位輸出0,對應138譯門輸入腳,全0為第一位數碼管
for(i=0;i<lc;i++) //循環顯示
{
P2=DS1302_table[lp[i]]; //查表法得到要顯示數字的數碼段
DS1302_delay(); //延時
P2=0; //清0端口,準備顯示下位
if(i==7) //檢測顯示完8位否,完成直接退出,不讓P1口再加1,否則進位影響到第四位數據
break;
P1++; //下一位數碼管
}
}
/*************************************************/
/******名字:DS1302_delay*************************/
/******功能:起到一個延時的作用,用于掃描數碼管***/
/******作者:WPM**********************************/
/******修改日期:2010年7月21日********************/
/*************************************************/
void DS1302_delay()
{
uchar i=10;
while(i)
i--;
}
/*************************************************/
/******名字:Write_DS1302_Byte********************/
/******功能:向DS1302芯片寫入一個字節的數據********/
/******作者:WPM**********************************/
/******修改日期:2010年7月21日********************/
/************************************************/
void Write_Ds1302_Byte(uchar temp)
{
uchar i;
for (i=0;i<8;i++) //循環8次 寫入數據
{
DS1302_SCL2=0; //給一個上升沿脈沖,即可寫入一個位
DS1302_SDA2=temp&0x01; //每次傳輸低字節
temp>>=1; //右移一位
DS1302_SCL2=1;
}
}
/*********************************************/
/*********************************************/
/******名字:Write_DS1302*********************/
/******功能:向DS1302芯片寫入數據**************/
/******作者:WPM******************************/
/******修改日期:2010年7月21日****************/
/*********************************************/
void Write_Ds1302( uchar address,uchar dat )
{
DS1302_RST=0;
_nop_();
DS1302_SCL2=0;
_nop_();
DS1302_RST=1;
_nop_(); //啟動
Write_Ds1302_Byte(address); //發送地址
Write_Ds1302_Byte(dat); //發送數據
DS1302_RST=0; //恢復
}
/***********************************************/
/***********************************************/
/******名字:Read_DS1302************************/
/******功能:讀取DS1302一個字節的數據************/
/******作者:WPM********************************/
/******修改日期:2010年7月21日******************/
/***********************************************/
uchar Read_Ds1302 ( uchar address )
{
uchar i,temp=0x00;
DS1302_RST=0;
_nop_();
DS1302_SCL2=0;
_nop_();
DS1302_RST=1;
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++) //循環8次 讀取數據
{
DS1302_SCL2=1;
_nop_();
if(DS1302_SDA2)
temp|=0x80; //每次傳輸低字節
DS1302_SCL2=0;
temp>>=1; //右移一位
}
DS1302_RST=0;
_nop_();
DS1302_SCL2=1;
DS1302_SDA2=0;
return (temp); //返回
}
/*********************************************/
/*********************************************/
/******名字:Write_DS1302*********************/
/******功能:向DS1302芯片讀取日歷**************/
/******作者:WPM******************************/
/******修改日期:2010年7月21日****************/
/*********************************************/
void DS1302_Read_RTC() //讀取 日歷
{
uchar i,*p;
p=DS1302_Read_RTC_address; //地址傳遞
for(i=0;i<7;i++) //分7次讀取 年月日時分秒星期
{
DS1302_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/**********************************************/
/**********************************************/
/******名字:Write_DS1302**********************/
/******功能: 設置DS1302芯片的日歷值************/
/******作者:WPM*******************************/
/******修改日期:2010年7月21日*****************/
/**********************************************/
void DS1302_Set_RTC() //設定 日歷
{
uchar i,*p,tmp; //DS1302的數據是以十進制存儲的,要轉化為十六進制顯示
for(i=0;i<7;i++)
{
tmp=DS1302_tmpdate[i]/10;
DS1302_tmpdate[i]=DS1302_tmpdate[i]%10;
DS1302_tmpdate[i]=DS1302_tmpdate[i]+tmp*16;
}
Write_Ds1302(0x8E,0X00);//允許寫入數據
p=write_rtc_address; //傳地址
for(i=0;i<7;i++) //7次寫入 年月日時分秒星期
{
Write_Ds1302(*p,DS1302_tmpdate[i]);
p++;
}
Write_Ds1302(0x8E,0x80);//禁止寫入數據
}
/**********************************************/
/**********************************************/
/******名字:ReadKey***************************/
/******功能:鍵盤掃描子函數,讀取按下的按鍵值***/
/******作者:WPM*******************************/
/******修改日期:2010年7月21日*****************/
/**********************************************/
void ReadKey() //鍵盤掃描函數,讀取鍵盤值
{
uchar i,j,key;
j=0xfe;//賦初值
key=0xff;//判斷按鍵是否按下的標志
for (i=0;i<4;i++) //掃描鍵盤,判斷是否有按鍵按下
{
P0=j; //把J的值賦給P0口,用于下面判斷是否有按鍵按下
if ((P0&0xf0)!=0xf0) //判斷是否有按鍵按下
{
key=P0; //有按鍵按下,讀取P0口的值,賦給KRY,保存該值
break; //跳出,結束
}
j=_crol_(j,1); //左循環
}
if (key==0xff) //沒有按鍵,有抖動等
{
DS1302_keytmp=0xff;
P0=0xf0;
EX0=1; //打開外部中斷
DS1302_SPK=1; //關閉蜂鳴器
return; //返回
}
DS1302_SPK=0; //驅動蜂鳴器
if(DS1302_keytmp==key) //按鍵按下了,但沒有松手
{
TH0=0X2E;//給定時器賦初值
TL0=0;
TR0=1;//啟動定時器
return; //返回
}
TH0=0X2E;//給定時器賦初值
TL0=0;
TR0=1;//啟動定時器
DS1302_keytmp=key;//把讀取的值賦給l-keytmp
for(i=0;i<17;i++)
{
if (key==DS1302_key_tab[i]) //通過對比代碼,判斷是那個按鍵按下
{
DS1302_key=i;//保存對比好的值,用于顯示??
break; //跳出,結束
}
}
}
/*****************************************************************/
/***************************************************** ***********/
/******名字:Key_Scan*********************************************/
/******功能:外部中斷0,用于有按鍵按下時,掃描鍵盤,讀取鍵盤值*****/
/******作者:WPM**************************************************/
/******修改日期:2010年7月21日************************************/
/*****************************************************************/
void Key_Scan() interrupt 0 //外部中斷 0 的優先級最高
{
TMOD&=0XF1;//定時器工作在方式1,既TMOD=0x01
TH0=0X00;//定時時間為:(65536-65536)/晶振頻率/12
TL0=0X00;
ET0=1; //開分控
TR0=1; //啟動定時器
}
/*****************************************************************/
/***************************************************** ***********/
/******名字:Timer0_isr*******************************************/
/******功能:定時器0,用于每隔一段時間掃描鍵盤*********************/
/******作者:WPM**************************************************/
/******修改日期:2010年7月21日************************************/
/*****************************************************************/
void Timer0_isr() interrupt 1 //定時器0中斷
{
TR0=0; //關閉定時器
ReadKey(); //讀取鍵盤掃描值
}
/**************************************************/
/**************************************************/
/******名字:DS1302Menu****************************/
/******功能:修改時鐘的時間*************************/
/******作者:WPM***********************************/
/******修改日期:2010年7月21日*********************/
/**************************************************/
void Ds1302Menu()//時鐘讀取,可修改,按A、B鍵更改顯示時間還是日
//期,再按#鍵可對其做修改
{
uchar i,tmp,temp,oldtimer=0;
tmp=0;
while (1)
{
DS1302_Read_RTC();
if(tmp==0) //用于區別是否按下了B鍵
{
DS1302_tmpdisplay[0]=DS1302_tmpdate[2]/16; //十六進制轉化為十進制顯示,顯示時
DS1302_tmpdisplay[1]=DS1302_tmpdate[2]&0x0f; //顯示個位
DS1302_tmpdisplay[2]=10; //顯示‘-’
DS1302_tmpdisplay[3]=DS1302_tmpdate[1]/16; //顯示分的十位
DS1302_tmpdisplay[4]=DS1302_tmpdate[1]&0x0f;//顯示分的個位
DS1302_tmpdisplay[5]=10; //顯示‘-’
DS1302_tmpdisplay[6]=DS1302_tmpdate[0]/16; //顯示秒的十位
DS1302_tmpdisplay[7]=DS1302_tmpdate[0]&0x0f;//顯示秒的個位
}
if((tmp==0)&&(oldtimer!=DS1302_tmpdate[0])) //tmp作為標志位,與秒作比較,
//判斷數據是否修改,修改時分秒
{
oldtimer=DS1302_tmpdate[0]; //暫存該值,用于比較
DS1302_tmpdisplay[0]=DS1302_tmpdate[2]/16; //十六進制轉化為十進制顯示,顯示時
DS1302_tmpdisplay[1]=DS1302_tmpdate[2]&0x0f; //顯示個位
DS1302_tmpdisplay[2]=10; //顯示‘-’
DS1302_tmpdisplay[3]=DS1302_tmpdate[1]/16; //顯示分的十位
DS1302_tmpdisplay[4]=DS1302_tmpdate[1]&0x0f;//顯示分的個位
DS1302_tmpdisplay[5]=10; //顯示‘-’
DS1302_tmpdisplay[6]=DS1302_tmpdate[0]/16; //顯示秒的十位
DS1302_tmpdisplay[7]=DS1302_tmpdate[0]&0x0f;//顯示秒的個位
}
if((tmp==1)&&(oldtimer!=DS1302_tmpdate[3]))//tmp作為標志位,與日作比較
//判斷數據是否修改,修改年月日
{
oldtimer=DS1302_tmpdate[3];//暫存該值,用于比較
DS1302_tmpdisplay[0]=DS1302_tmpdate[6]/16; //改為十進制顯示,顯示年的十位
DS1302_tmpdisplay[1]=DS1302_tmpdate[6]&0x0f;//顯示年的個位,
DS1302_tmpdisplay[2]=10; //顯示‘-’
DS1302_tmpdisplay[3]=DS1302_tmpdate[4]/16;//顯示月的十位
DS1302_tmpdisplay[4]=DS1302_tmpdate[4]&0x0f;//顯示月的個位
DS1302_tmpdisplay[5]=10; //顯示‘-’
DS1302_tmpdisplay[6]=DS1302_tmpdate[3]/16; //顯示日的十位
DS1302_tmpdisplay[7]=DS1302_tmpdate[3]&0x0f; //顯示日的個位
}
DS1302_display(DS1302_tmpdisplay,8);//顯示時分秒,年月日
DS1302_display(DS1302_tmpdisplay,8); //增加亮度
DS1302_display(DS1302_tmpdisplay,8);
DS1302_display(DS1302_tmpdisplay,8);
ReadKey(); //讀取按下的按鍵值
if(DS1302_key==0x0c)
{
DS1302_key=0xff;//退出鍵按下了,結果退出
break;
}
if(DS1302_key==0x0e) //確定鍵按下了
{
DS1302_key=0xff;
for(i=0;i<7;i++) //保存當前的時間,用于作比較,判斷是否修改了時間
{
temp=DS1302_tmpdate[i]/16; //數據處理,在前程序講過,時鐘I
//C它是以十進制對數據存儲,所以要將它轉為十進制
DS1302_tmpdate[i]=DS1302_tmpdate[i]%16;
DS1302_tmpdate[i]=temp*10+DS1302_tmpdate[i];
}
while(1)
{
if(DS1302_key==0x0c)
{
DS1302_key=0xff;
break;
}
if(DS1302_key==0x0e)
{ //按#鍵對修改的數據進行寫入時鐘IC1302
DS1302_key=0xff;
DS1302_Set_RTC();
break;
}
switch(DS1302_key)
{
case 0x01: //按1鍵對小時,或年的加1
DS1302_key=0xff;
if(tmp==0)
{
if(DS1302_tmpdate[2]<23)
DS1302_tmpdate[2]++;
}
else
{
if(DS1302_tmpdate[6]<99)
DS1302_tmpdate[6]++;
}
break;
case 0x02: //按2鍵對分鐘,或月的加1
DS1302_key=0xff;
if(tmp==0)
{
if(DS1302_tmpdate[1]<59) //對分進行修改,判斷分是否小于59
DS1302_tmpdate[1]++; //是,則加1
}
else //其他情況對月進行修改
{
if(DS1302_tmpdate[4]<12)
DS1302_tmpdate[4]++;
}
break;
case 0x03: //按3鍵對秒,或日的加1
DS1302_key=0xff;
if(tmp==0)
{
if(DS1302_tmpdate[0]<59)
DS1302_tmpdate[0]++;
}
else
{
if(DS1302_tmpdate[3]<31)
DS1302_tmpdate[3]++;
}
break;
case 0x04: //按4鍵對小時,或年的減1
DS1302_key=0xff;
if(tmp==0)
{
if(DS1302_tmpdate[2]>0)
DS1302_tmpdate[2]--;
}
else
{
if(DS1302_tmpdate[6]>0)
DS1302_tmpdate[6]--;
}
break;
case 0x05: //按5鍵對分鐘,或月的減1
DS1302_key=0xff;
if(tmp==0)
{
if(DS1302_tmpdate[1]>0)
DS1302_tmpdate[1]--;
}
else
{
if(DS1302_tmpdate[4]>0)
DS1302_tmpdate[4]--;
}
break;
case 0x06: //按6鍵對秒,或日的減1
DS1302_key=0xff;
if(tmp==0)
{
if(DS1302_tmpdate[0]>0)
DS1302_tmpdate[0]--;
}
else
{
if(DS1302_tmpdate[3]>0)
DS1302_tmpdate[3]--;
}
break;
}
Ds1302Play(tmp);
}
}
if(DS1302_key==0x0a) //判斷是否按鍵A按下
{
DS1302_key=0xff;
tmp=0; //置標志位
}
if(DS1302_key==0x0b)
{
DS1302_key=0xff;
tmp=1;
}
}
}
/**************************************************/
/**************************************************/
/******名字:DS1302Play****************************/
/******功能:用于判斷顯示時分秒還是年月日***********/
/******作者:WPM***********************************/
/******修改日期:2010年7月21日*********************/
/**************************************************/
void Ds1302Play(uchar tmp)
{
if(tmp==0) //用于顯示時分秒
{
DS1302_tmpdisplay[0]=DS1302_tmpdate[2]/10;
DS1302_tmpdisplay[1]=DS1302_tmpdate[2]%10;
DS1302_tmpdisplay[2]=10;
DS1302_tmpdisplay[3]=DS1302_tmpdate[1]/10;
DS1302_tmpdisplay[4]=DS1302_tmpdate[1]%10;
DS1302_tmpdisplay[5]=10;
DS1302_tmpdisplay[6]=DS1302_tmpdate[0]/10;
DS1302_tmpdisplay[7]=DS1302_tmpdate[0]%10;
}
else //其他情況顯示日月年
{
DS1302_tmpdisplay[0]=DS1302_tmpdate[6]/10;
DS1302_tmpdisplay[1]=DS1302_tmpdate[6]%10;
DS1302_tmpdisplay[2]=10;
DS1302_tmpdisplay[3]=DS1302_tmpdate[4]/10;
DS1302_tmpdisplay[4]=DS1302_tmpdate[4]%10;
DS1302_tmpdisplay[5]=10;
DS1302_tmpdisplay[6]=DS1302_tmpdate[3]/10;
DS1302_tmpdisplay[7]=DS1302_tmpdate[3]%10;
}
DS1302_display(DS1302_tmpdisplay,8);
}
復制代碼
作者:
rs7cai
時間:
2017-5-15 20:45
樓主有電路圖提供?
謝謝分享!
作者:
danielone2018
時間:
2018-11-3 21:06
謝謝樓主分享,學習中
作者:
Lenv
時間:
2019-2-17 18:08
樓主我想請教下,我用DS1302的burst模式,我一開始初始DS1302,23,55,55,然后用burst模式去讀,我是用數碼管顯示,顯示一開始會顯示23,55,55,然后立馬變成00,00,00,時鐘顯示的那兩個數碼管會不斷跳動,
作者:
aefeefqfeq
時間:
2019-7-25 03:01
根本運行不了啊
作者:
aefeefqfeq
時間:
2019-7-25 03:01
蜂鳴器一直在響
作者:
yzcs
時間:
2019-12-10 11:32
有沒有接線圖呀
作者:
撒大蘇打安德森
時間:
2019-12-10 14:50
很不錯,謝謝分享。
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1