久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2994|回復: 1
打印 上一主題 下一主題
收起左側

AT89C52+DS1302單片機萬年歷程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:270854 發表于 2018-1-7 09:02 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
參考程序,可以調節時間,設置鬧鐘,音樂鬧鈴
#include<reg52.h>
#include<INTRINS.H>
/************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define TIME (0X10000-50000)
#define FLAG 0XEF //鬧鐘標志
/************************************************************/
//引腳連接圖
sbit CLK=P1^2;
sbit RST=P1^4;
sbit DAT=P1^3;
sbit RS=P1^5;
sbit RW=P1^6;
sbit E=P1^7;
sbit P32=P3^2;
sbit KEY1 = P2^7;
sbit KEY2 = P2^6;
sbit KEY3 = P2^5;
sbit KEY4 = P2^4;
sbit ACC_7=ACC^7;
/************************************************************/
//全局變量及常量定義
uchar i=20,j;
uchar DataBuf[16] = {};//日期
uchar TimeBuf[16] = {};//時間
uchar alarm[2],time[3];
uchar code Day[]={31,28,31,30,31,30,31,31,30,31,30,31};//12個月的最大日期(非閏年)
//閏年月星期表
const unsigned char WeekTab[] = {
(3 << 5) + 31,///1月
(6 << 5) + 29,///2月
(0 << 5) + 31,///3月
(3 << 5) + 30,///4月
(5 << 5) + 31,//5月
(1 << 5) + 30,//6月
(3 << 5) + 31,//7月
(6 << 5) + 31,//8月
(1 << 5) + 30,//9月
(4 << 5) + 31,//10月
(0 << 5) + 30,//11月
(2 << 5) + 31 //12月
};
//音律表
uint code table1[]={64260,64400,64524,64580,64684,64777,
64820,64898,64968,65030,65058,65110,65157,65178,65217};
//發聲部分的延時時間
uchar code table2[]={0x82,1,0x81,0xf4,0xd4,0xb4,0xa4,
0x94,0xe2,1,0xe1,0xd4,0xb4,0xc4,0xb4,4,0};
//鬧鐘中用的全局變量
uchar th1,tl1;
/************************************************************/
//延時1ms函數
delay1ms(uchar time)
{
uchar i,j;
for(i=0;i<time;i++)
{
for(j=0;j<250;j++);
}
}
/************************************************************/
//LCD控制函數
Enable()
{
RS=0;
RW=0;
E=0;
delay1ms(3);
E=1;
}
/************************************************************/
//LCD1602寫入字符函數
LCD1602_WriteSChr(uchar i)
{
P0=i;
RS=1;
RW=0;
E=0;
delay1ms(2);
E=1;
}
/************************************************************/
//LCD1602寫入字符串函數
//入口函數
//uchar data *address : 寫入數據首地址
//ucharm:寫入字節數
LCD1602_WriteStr(uchar *address,uchar m)
{
uchar i,j;
for(i=0;i<m;i++,address++)
{
j=*address;
LCD1602_WriteSChr(j);
}
}
/************************************************************/
//LCD顯示
void LCDShow(void)
{
P0=0XC; //顯示器開、光標關
Enable();
//P0=0x80; //寫入顯示起始地址
//Enable();
//LCD1602_WriteStr(DataBuf,16); //寫入日期顯示緩存
P0=0xc1; //寫入顯示起始地址
Enable();
LCD1602_WriteStr(TimeBuf,16); //寫入時間顯示緩存
}
/************************************************************/
//DS1302寫入子程序
void DS1302_Write(uchar temp)
{
uchar i;
CLK=0; //將DS1320時鐘脈沖拉低
_nop_();//延時一指令周期
RST=1; //RST置高電平
_nop_();//延時一指令周期
for(i=0;i<8;i++) //循環8次
{
DAT=temp&0x01; //向DS1302寫入一字節數據
_nop_(); //延時一指令周期
CLK=1; //拉高時鐘脈沖
temp>>=1; //右移一位
CLK=0; //拉低時鐘脈沖
}
}
/************************************************************/
//DS1302讀取子程序
uchar DS1302_Read()
{
uchar i,j=0;
for(i=0;i<8;i++)//循環8次
{
j>>=1; //右移一位
_nop_(); //延時一指令周期
CLK=0; //拉低時鐘脈沖
_nop_(); //延時一指令周期
if(DAT) //判斷接收該位數據是否為1
j|=0x80;//該位置1
_nop_(); //延時一指令周期
CLK=1; //拉高時鐘脈沖
}
return(j); //返回數值
}
/************************************************************/
//部分顯示數據初始化
TimeStart()
{
TimeBuf[0]=TimeBuf[8]=TimeBuf[9]=TimeBuf[10]=0x20; //不顯示字符
TimeBuf[2]=TimeBuf[5]=':'; //時間分隔顯示
DS1302_Write(0xc1);
alarm[0]=DS1302_Read();
RST=0;
DS1302_Write(0xc3);
alarm[1]=DS1302_Read();
RST=0;
DS1302_Write(0xc5);
DataBuf[0]=DS1302_Read();
RST=0;
}
/************************************************************/
//讀取時間
ReadTime()
{
uchar i,m,n;
for(m=0,i=0,n=0x85;i<7;i+=3,n-=2,m++) //連續讀取時,分,秒
{
DS1302_Write(n); //寫入讀取寄存器指令
time[m]=DS1302_Read(); //讀取數據
RST=0; //將RST電平拉低,停止傳輸
TimeBuf[i]=time[m]/16+0x30; //將兩位數據的十位轉為字符格式
TimeBuf[i+1]=time[m]%16+0x30;//將兩位數據的個位轉為字符格式
}
}
/************************************************************/
//功能選擇超時定時器
time0() interrupt 1 using 1
{
i--;
if(i==0)
{
if(j!=0)
j--;
i=20;
}
TH0=TIME/256,TL0=TIME%256;
}
/************************************************************/
//產生鬧鈴音調
intime1() interrupt 3
{
TH1=th1,TL1=tl1;
P32=!P32;
}
/************************************************************/
//鬧鐘顯示
void AlarmShow(void)
{
uchar i,j,a,b,n;
ET1=1;
for(j=0;j<6;j++)
{
i=0;
while(1)
{
a=table2[i];
if(a==0)
break;
b=a&0xf;
a>>=4;
if(a==0)
{
TR1=0;
goto D1;
}
a=((--a)<<1)/2;
TH1=th1=table1[a]/256,TL1=tl1=table1[a]%256;
TR1=1;
D1: do
{
b--;
for(n=0;n<3;n++)
{
ReadTime();
LCDShow();
P2=0xff;
if(KEY4 == 1)
{
delay1ms(100);
if(KEY4 == 1)
{
TR1=0;
ET1=0;
P32 = 1;
return;
}
}
}
}while(b!=0);
i++;
}
TR1=0;
}
ET1=0;
}
/************************************************************/
//設置日期、時間
void SetTime(void)
{
uchar i=0xc2,year,month,day,n;
TimeBuf[6]=TimeBuf[7]=0x30;
DataBuf[14]=DataBuf[15]=0x20;
LCDShow();
while(1)
{
P0=0xe; //顯示器開、光標開
Enable();
P0=i; //定光標
Enable();
P2=0xff;
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
delay1ms(100); //延時0.1s去抖動
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
j=7;
if(KEY1 == 1)
{
i+=3; //更改設置項目
if(i==0x8e)
i=0xc2;
else if(i>0xc5)
i=0xc2;
}
else if(KEY2 == 1)
{
year=(DataBuf[4]&0xf)*10+(DataBuf[5]&0xf); //將字符格式的年份轉換為數值格式
month=(DataBuf[7]&0xf)*10+(DataBuf[8]&0xf); //將字符格式的月份轉換為數值格式
day=(DataBuf[10]&0xf)*10+(DataBuf[11]&0xf); //將字符格式的日數轉換為數值格式
if(i==0x85) //設置年份
{
year++;
if(year>99)
year=0;
if((year%4)!=0)
if(month==2&&day==29)
day=28;
}
else if(i==0x88) //設置月份
{
month++;
if(month>12)
month=1;
if(day>Day[month-1])
{
day=Day[month-1];
if(month==2&&(year%4)==0) //計算是否閏年
day=29;
}
}
else if(i==0x8b) //設置日期
{
day++;
if(day>Day[month-1])
{
if(month==2&&(year%4)==0) //計算是否閏年
{
if(day>29)
day=1;
}
if(month!=2)
day=1;
}
}
else if(i==0xc2) //設置小時
{
n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf);
n++;
if(n>23)
n=0;
TimeBuf[0]=n/10+0x30;
TimeBuf[1]=n%10+0x30;
}
else //設置分鐘
{
n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf);
n++;
if(n>59)
n=0;
TimeBuf[3]=n/10+0x30;
TimeBuf[4]=n%10+0x30;
}
DataBuf[4]=year/10+0x30; //將數值格式的日期轉換為字符形式
DataBuf[5]=year%10+0x30;
DataBuf[7]=month/10+0x30;
DataBuf[8]=month%10+0x30;
DataBuf[10]=day/10+0x30;
DataBuf[11]=day%10+0x30;
LCDShow();
}
else if(KEY3 == 1) //按保存退出鍵后,向DS1302寫入設置后的日期時間
{
DS1302_Write(0x8c);
DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf));
RST=0;
DS1302_Write(0x8a);
DS1302_Write(SetWeek());
RST=0;
for(i=7,n=0x88;i<11;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf));
RST=0;
}
for(i=0;i<7;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf));
RST=0;
}
TR0=0;
return;
}
else
{
TR0=0;
return;
}
}
}
if(j==0)
{
TR0=0;
return;
}
}
}
/************************************************************/
//設置鬧鐘
void SetAlarm(void)
{
uchar i,n;
for(i=1;i<16;i++)
{
DataBuf[i]=0x20;
}
TimeBuf[0]=alarm[0]/16+0x30;
TimeBuf[1]=(alarm[0]&0xf)+0x30;
TimeBuf[3]=alarm[1]/16+0x30;
TimeBuf[4]=(alarm[1]&0xf)+0x30;
TimeBuf[6]=TimeBuf[7]=0x30;
LCDShow();
i=0xc2;
while(1)
{
P0=0xe; //顯示器開、光標開
Enable();
P0=i; //定光標
Enable();
P2=0xff;
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
delay1ms(100); //延時0.1s去抖動
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
j=7;
if(KEY1 == 1)
{
i+=3;
if(i>0xc5)
i=0xc2;
}
else if(KEY2 == 1)
{
if(i==0xc2)
{
n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf);
n++;
if(n>23)
n=0;
TimeBuf[0]=n/10+0x30;
TimeBuf[1]=n%10+0x30;
}
else
{
n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf);
n++;
if(n>59)
n=0;
TimeBuf[3]=n/10+0x30;
TimeBuf[4]=n%10+0x30;
}
LCDShow();
}
else if(KEY3 == 1)
{
DS1302_Write(0xc0);
DS1302_Write((TimeBuf[0]&0xf)*16+(TimeBuf[1]&0xf));
RST=0;
DS1302_Write(0xc2);
DS1302_Write((TimeBuf[3]&0xf)*16+(TimeBuf[4]&0xf));
RST=0;
DataBuf[0]=FLAG;
DS1302_Write(0xc4);
DS1302_Write(DataBuf[0]);
RST=0;
TR0=0;
TimeStart();
return;
}
else
{
TR0=0;
TimeStart();
return;
}
}
}
if(j==0)
{
TR0=0;
TimeStart();
return;
}
}
}
/************************************************************/
//DS1302初始化程序
void DS1302_Init(void)
{
uchar i,n;
DS1302_Write(0x8c);
DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf));
RST=0;
DS1302_Write(0x8a);
DS1302_Write(SetWeek());
RST=0;
for(i=7,n=0x88;i<11;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf));
RST=0;
}
for(i=0;i<7;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf));
RST=0;
}
}
/************************************************************/
//主函數
main()
{
IE=0x82;
TMOD=0x11;
DS1302_Write(0x8E); //禁止寫保護
DS1302_Write(0);
RST=0;
P0=1; //清屏并光標復位
Enable();
P0=0x38; //設置顯示模式:8位2行5x7點陣
Enable();
P0=6; //文字不動,光標自動右移
Enable();
DS1302_Init();
TimeStart();
while(1)
{
ReadTime(); //讀取時間
LCDShow(); //顯示時間
if(DataBuf[0]!=0x20)
if(time[0]==alarm[0])
if(time[1]==alarm[1])
if(time[2]==0)
AlarmShow();
P2=0xff;
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1))
{
delay1ms(100); //延時0.1s去抖動
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1))
{
j=7;
TH0=TIME/256,TL0=TIME%256;
TR0=1;
if(KEY1 == 1)
{
SetTime();
}
else if(KEY2 == 1)
{
SetAlarm();
}
else if(KEY3 == 1)
{
TR0=0;
if(DataBuf[0]==FLAG)
DataBuf[0]=0x20;
else
DataBuf[0]=FLAG;
DS1302_Write(0xc4);
DS1302_Write(DataBuf[0]);
RST=0;
}
}
}
delay1ms(100);
}
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:272625 發表于 2018-1-24 04:51 | 只看該作者
程序有錯
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品久久久久久久不卡四虎 | 夜夜爽99久久国产综合精品女不卡 | 黄色在线免费观看视频网站 | 中文字幕一区二区三区乱码在线 | 日韩视频高清 | 欧美自拍视频 | 国产一区久久精品 | 9999久久 | 久久蜜桃av| 成人免费视频播放 | 日韩av一区二区在线观看 | 精品久久久久久 | 欧洲一级黄 | 激情国产 | 狠狠操狠狠干 | 久久久久99 | 在线视频久久 | 精品视频一区二区在线观看 | 日日摸夜夜添夜夜添特色大片 | 一级黄色毛片免费 | 91视视频在线观看入口直接观看 | 91色视频在线观看 | 成人伊人 | 亚洲午夜在线 | www.yw193.com| 免费美女网站 | 亚洲成人免费视频 | 久久av一区二区三区 | 人人玩人人添人人澡欧美 | 91视频亚洲| 免费一区二区三区 | 精品96久久久久久中文字幕无 | 日韩国产精品一区二区三区 | 婷婷去俺也去 | 在线视频成人 | 亚洲成人久久久 | 中文字幕在线观看www | 日本一区二区影视 | 91视频中文 | 欧美久久精品一级c片 | 国产日韩欧美一区二区 |