欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
哪位大神能幫忙看一下,下面單片機DS1302程序是什么問題?
[打印本頁]
作者:
用戶21111412
時間:
2021-5-24 15:27
標題:
哪位大神能幫忙看一下,下面單片機DS1302程序是什么問題?
使用DS1302做一個可調(diào)時間的萬年歷,現(xiàn)在按鍵設定時間后,無法將時間保存到DS1302中。按鍵功能是:KEY0長按:進入/保存設定,KEY0在設定界面短按,改變選中,KEY1在設定界面短按加1,長按返回實時顯示界面,不保存設定時間。
單片機源程序如下:
/******************************************************
內(nèi)容:
硬件連接:
_RD與單片機P2.6引腳連接
_WR與單片機P2.5引腳連接
_EN與單片機P2.7引腳連接
8位并行數(shù)據(jù)口與單片機P0組I/O口連接
**************************************************************/
#include "reg52.h"
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
sbit _RD=P2^6; //LCD1602數(shù)據(jù)/命令選擇端位定義
sbit _WR=P2^5; //LCD1602讀/寫選擇端位定義
sbit _EN=P2^7; //LCD1602使能信號端位定義
sbit _SCL=P3^6; //DS1302串行時鐘口位定義
sbit _SDA=P3^4; //DS1302數(shù)據(jù)輸入/輸出口位定義
sbit _RST=P3^5; //DS1302復位口
sbit DQ=P3^7; //DS18B20總線口位定義
sbit KEY0=P1^0;
sbit KEY1=P1^1;
uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
uchar time0[8]={20,21,5,19,3,20,51,35}; //存放年、月、日、周,時、分、秒初始值
uchar time1[8]; //存放DS1302讀取的年、月、日、周,時、分、秒值
uchar time2[8]; //用于存放臨時設定的時間值
uchar time3[8]; //用于存放顯示的值
uint temperature=0; //溫度
uchar flag0=0,flag1=0; //flag0為設定標志,為0時,顯示實時時間,為1時,顯示設定的值,flag1為溫度零下標志,為0表示正,為1表示負
uchar num=0; //用于顯示實時溫度和設定時間
//--------------------------------------DS1302驅動------------------------------------------
uchar read_byte0(uchar addr) //DS1302讀數(shù)據(jù)
{
uchar i,dat;
_RST=1; //把RST拉高時,SCL必須為低電平
addr=addr|0x01; //功能未知
for(i=0;i<8;i++) //寫地址
{
_SDA=(bit)(addr&0x01);
_nop_();
_SCL=1; //上升沿,寫入地址數(shù)據(jù)
_nop_();
_SCL=0;
addr>>=1;
}
for(i=0;i<8;i++) //讀數(shù)據(jù)
{
dat>>=1;
if(_SDA==1)
dat|=0x80;
_SCL=1;
_SCL=0;
}
_RST=0;
_SCL=1; //要加上,不然程序會異常
_SDA=0; //要加上,不然程序會異常
_SDA=1;
return dat;
}
/****************************************************************************************************
函數(shù)功能:DS1302寫一個字節(jié)
入口參數(shù):地址,命令
說明:
時間:
****************************************************************************************************/
void write_byte0(uchar addr,uchar com) //DS1302寫數(shù)據(jù)
{
uchar i;
_RST=1; //把RST拉高時,SCL必須為低電平
addr=addr&0xfe; //最低位置零
for(i=0;i<8;i++) //寫地址
{
_SDA=(bit)(addr&0x01);
_nop_();
_SCL=1; //上升沿,寫入地址數(shù)據(jù)
_nop_();
_SCL=0;
addr>>=1;
}
for(i=0;i<8;i++) //讀數(shù)據(jù)
{
_SDA=(bit)(com&0x01);
_nop_();
_SCL=1; //上升沿,寫入地址數(shù)據(jù)
_nop_();
_SCL=0;
com>>=1;
}
_RST=0;
}
/*******************************************************************************
函數(shù)功能:十進制轉BCD碼
入口參數(shù):
說明:
時間:
****************************************************************************************************/
uchar Dec_Bcd(uchar dec) //十進制轉BCD碼
{
uchar bcd,tmp;
tmp=dec/10;
dec=dec%10;
bcd=dec+tmp*16;
return bcd;
}
/****************************************************************************************************
函數(shù)功能:BCD碼轉十進制
入口參數(shù):
說明:
時間:
****************************************************************************************************/
uchar Bcd_Dec(uchar bcd)
{
uchar dec,tmp;
tmp=bcd/16;
bcd=bcd%16;
dec=bcd+tmp*10;
return dec;
}
/****************************************************************************************************
函數(shù)功能:向DS1302寫入時鐘數(shù)據(jù)
入口參數(shù):地址
說明:
時間:
****************************************************************************************************/
void DS1302_Write_Time(void)
{
write_byte0(0x8e,0x00); //關閉寫保護
write_byte0(0x80,0x80); //暫停
write_byte0(0x90,0xa9); //涓流放電
write_byte0(0x8c,Dec_Bcd(time0[1])); //寫入年
write_byte0(0x88,Dec_Bcd(time0[2])); //寫入月
write_byte0(0x86,Dec_Bcd(time0[3])); //寫入日
write_byte0(0x8a,Dec_Bcd(time0[4])); //寫入星期
write_byte0(0x84,Dec_Bcd(time0[5])); //寫入時
write_byte0(0x82,Dec_Bcd(time0[6])); //寫入分
write_byte0(0x80,Dec_Bcd(time0[7])); //寫入秒
write_byte0(0x8e,0x80); //打開寫保護
}
/****************************************************************************************************
函數(shù)功能:從DS1302讀出時鐘數(shù)據(jù)
入口參數(shù):
說明:
時間:
****************************************************************************************************/
void DS1302_Read_Time(void)
{
uchar i;
time1[0]=time0[0];
time1[1]=read_byte0(0x8c); //年
time1[2]=read_byte0(0x88); //月
time1[3]=read_byte0(0x86); //日
time1[4]=read_byte0(0x8a); //星期
time1[5]=read_byte0(0x84); //時
time1[6]=read_byte0(0x82); //分
time1[7]=read_byte0(0x80); //秒
for(i=1;i<8;i++)
{
time1[i]=Bcd_Dec(time1[i]);
}
}
/****************************************************************************************************
函數(shù)功能:DS1302初始化
入口參數(shù):無
說明:
時間:
****************************************************************************************************/
void DS1302_Init()
{
_RST=0;
_SCL=0;
write_byte0(0x80,0x00);
}
//------------------------------------------液晶驅動略-------------------------------------------------
/****************************************************************************************************
函數(shù)功能:按鍵處理函數(shù)
入口參數(shù):無
說明:
時間:
****************************************************************************************************/
void Scan()
{
uchar i;
static uint temp0=0,temp1=0;
static uchar pass0=0,pass1=0;
if(KEY0==0)
temp0++;
if(temp0>2&&temp0<80&&KEY0==1) //設置界面短按切換焦點
{
if(num>0&&num<10)
num++;
else if(num>=10)
num=1;
}
if(temp0>=80&&pass0==0) //長按進入設定界面或設定界面保存設定數(shù)據(jù)
{
pass0=1;
switch(num)
{
case 0:
num=1;
for(i=1;i<8;i++) //將顯示的當前數(shù)據(jù)送入臨時數(shù)據(jù)中
{
time2[i]=time1[i];
}
break;
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:
num=0;
for(i=1;i<8;i++)
{
time0[i]=time2[i];
}
DS1302_Write_Time();
break;
}
}
if(KEY0==1)
{
pass0=0;
temp0=0;
}
if(KEY1==0)
temp1++;
if(temp1>2&&temp1<80&&KEY1==1) //設定界面點擊焦點加1
{
switch(num)
{
case 0: //無焦點
break;
case 1: //年十位加1
if(time2[1]<90)
time2[1]=time2[1]+10;
else
time2[1]=time2[1]%10;
break;
case 2: //設定年個位
if(time2[1]%10<9)
time2[1]++;
else
time2[1]=time2[1]/10;
break;
case 3: //設定月
if(time2[2]<12)
time2[2]++;
else
time2[2]=1;
break;
case 4: //設定日
if(time2[2]==1||time2[2]==3||time2[2]==5||time2[2]==7||time2[2]==8||time2[2]==10||time2[2]==12) //31天的月份
{
if(time2[3]<31)
time2[3]++;
else
time2[3]=1;
}
else if(time2[2]==4||time2[2]==6||time2[2]==9||time2[2]==11) //30天的月份
{
if(time2[3]<30)
time2[3]++;
else
time2[3]=1;
}
else if(time2[2]==2) //2月份平年28天閏年29天
{
if((((time2[0]*100+time2[1])%4==0)&&((time2[0]*100+time2[1])%100!=0))||((time2[0]*100+time2[1])%400==0)) //閏年2月有29天
{
if(time2[3]<29)
time2[3]++;
else
time2[3]=1;
}
else //平年2月有28天
{
if(time2[3]<28)
time2[3]++;
else
time2[3]=1;
}
}
break;
case 5: //設定星期
if(time2[4]<7)
time2[4]++;
else
time2[4]=1;
break;
case 6: //設定時
if(time2[5]<23)
time2[5]++;
else
time2[5]=0;
break;
case 7: //設定分十位
if(time2[6]<50)
time2[6]=time2[6]+10;
else
time2[6]=time2[6]%10;
break;
case 8: //設定分個位
if(time2[6]%10<9)
time2[6]++;
else
time2[6]=time2[6]/10;
break;
case 9: //設定秒十位
if(time2[7]<50)
time2[7]=time2[7]+10;
else
time2[7]=time2[7]%10;
break;
case 10: //設定秒個位
if(time2[7]%10<9)
time2[7]++;
else
time2[7]=time2[7]/10;
break;
}
}
if(temp1>=80&&pass1==0)
{
pass1=1;
if(num!=0)
num=0;
}
if(KEY1==1)
{
pass1=0;
temp1=0;
}
}
void display0(uchar row,uchar line,uchar signal) //row為行位參數(shù),line為列為參數(shù)
{
static uchar a=0;
if(row==1)
a=0x80;
if(row==2)
a=0xc0;
a=a+line-1;
Wcmd(a);
Wdat(signal);
}
void display1()
{
uchar year0,year1,year2,year3,month0,month1,day0,day1;
uchar hours0,hours1,minutes0,minutes1,seconds0,seconds1;
uchar temperature0,temperature1,temperature2,temperature3;
uint j;
uchar i;
j++;
Read_Temp();
DS1302_Read_Time();
switch(num)
{
case 0:
for(i=1;i<8;i++)
time3[i]=time1[i];
break;
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:
for(i=1;i<8;i++)
time3[i]=time2[i];
break;
}
year0=time0[0]/10;
year1=time0[0]%10; //分離出年的十位和個位
year2=time3[1]/10;
year3=time3[1]%10; //分離出年的十位和個位
month0=time3[2]/10;
month1=time3[2]%10; //分離出月的十位和個位
day0=time3[3]/10;
day1=time3[3]%10; //分離出日的十位和個位
hours0=time3[5]/10;
hours1=time3[5]%10; //分離出時的十位和個位
minutes0=time3[6]/10;
minutes1=time3[6]%10; //分離出分的十位和個位
seconds0=time3[7]/10;
seconds1=time3[7]%10; //分離出秒的十位和個位
temperature0=temperature/1000; //分離出溫度百位
temperature1=temperature%1000/100; //分離出溫度十位
temperature2=temperature%100/10; //分離出溫度個位
temperature3=temperature%10; //分離出溫度十分位
display0(1,1,table[year0]);
display0(1,2,table[year1]);
switch(num)
{
case 0: //實時顯示
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 1: //設定年十位
if(j<20) //年十位閃爍
display0(1,3,table[year2]);
else if(j>=20&&j<40)
display0(1,3,0x20);
else
j=0;
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 2: //設定年個位
display0(1,3,table[year2]); //年十位
if(j<20) //年個位閃爍
display0(1,4,table[year3]);
else if(j>=20&&j<40)
display0(1,4,0x20);
else
j=0;
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 3: //設定月
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
if(j<20) //月閃爍
{
display0(1,6,table[month0]);
display0(1,7,table[month1]); //月個位
}
else if(j>=20&&j<40)
{
display0(1,6,0x20);
display0(1,7,0x20);
}
else
j=0;
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 4: //設定日
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
if(j<20)
{
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
}
else if(j>=20&&j<40)
{
display0(1,9,0x20);
display0(1,10,0x20);
}
else
j=0;
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 5: //設定星期
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
if(j<20)
display0(1,12,table[time3[4]]); //星期
else if(j>=20&&j<40)
display0(1,12,0x20);
else
j=0;
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 6: //設定小時
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
if(j<20)
{
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
}
else if(j>=20&&j<40)
{
display0(2,1,0x20);
display0(2,2,0x20);
}
else
j=0;
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 7: //設定分十位
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
if(j<20)
display0(2,4,table[minutes0]); //分十位
else if(j>=20&&j<40)
display0(2,4,0x20);
else
j=0;
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 8: //設定分個位
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
if(j<20)
display0(2,5,table[minutes1]); //分個位
else if(j>=20&&j<40)
display0(2,5,0x20);
else
j=0;
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
display0(2,8,table[seconds1]); //秒個位
break;
case 9: //設定秒十位
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
if(j<20)
display0(2,7,table[seconds0]); //秒十位
else if(j>=20&&j<40)
display0(2,7,0x20);
else
j=0;
display0(2,8,table[seconds1]); //秒個位
break;
case 10: //設定秒個位
display0(1,3,table[year2]); //年十位
display0(1,4,table[year3]); //年個位
display0(1,5,'-');
display0(1,6,table[month0]); //月十位
display0(1,7,table[month1]); //月個位
display0(1,8,'-');
display0(1,9,table[day0]); //日十位
display0(1,10,table[day1]); //日個位
display0(1,12,table[time3[4]]); //星期
display0(2,1,table[hours0]); //時十位
display0(2,2,table[hours1]); //時個位
display0(2,3,':');
display0(2,4,table[minutes0]); //分十位
display0(2,5,table[minutes1]); //分個位
display0(2,6,':');
display0(2,7,table[seconds0]); //秒十位
if(j<20)
display0(2,8,table[seconds1]); //秒個位
else if(j>=20&&j<40)
display0(2,8,0x20);
else
j=0;
break;
}
if(flag1==0)
{
if(temperature>=1000)
{
display0(2,10,table[temperature0]); //溫度百位
display0(2,11,table[temperature1]); //溫度十位
display0(2,12,table[temperature2]); //溫度個位
display0(2,13,'.');
display0(2,14,table[temperature3]); //溫度十分位
}
else if(temperature>=100&&temperature<1000)
{
display0(2,11,table[temperature1]); //溫度十位
display0(2,12,table[temperature2]); //溫度個位
display0(2,13,'.');
display0(2,14,table[temperature3]); //溫度十分位
}
else
{
display0(2,12,table[temperature2]); //溫度個位
display0(2,13,'.');
display0(2,14,table[temperature3]); //溫度十分位
}
}
else
{
if(temperature>=100)
{
display0(2,10,'-'); //溫度百位
display0(2,11,table[temperature1]); //溫度十位
display0(2,12,table[temperature2]); //溫度個位
display0(2,13,'.');
display0(2,14,table[temperature3]); //溫度十分位
}
else
{
display0(2,11,'-'); //溫度十位
display0(2,12,table[temperature2]); //溫度個位
display0(2,13,'.');
display0(2,14,table[temperature3]); //溫度十分位
}
}
display0(2,15,0xdf);
display0(2,16,'C');
}
main()
{
Lcd_Init();
DS1302_Init();
DS1302_Write_Time();
display0(1,1,0x20);
while(1)
{
Scan();
display1();
delayms(5);
}
}
復制代碼
作者:
名字不是重點
時間:
2021-5-25 10:00
找不到合適的板支來測試你的代碼,
走時顯示正常說明1302讀寫正常,問題可能發(fā)生在按鍵處理,邏輯上你要畫個流程圖來
作者:
man1234567
時間:
2021-5-26 09:27
本壇內(nèi)搜索一個1302的參考就可以,700多行代碼還沒有圖呵呵
作者:
人人學會單片機
時間:
2021-7-6 20:36
STC8單片機+DS1302+DS18B20+74HC595的LED16x32點陣溫度萬年歷源代碼分享
http://m.raoushi.com/bbs/dpj-200968-1.html
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1