|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機(jī)源程序如下:
- #include "reg52.h"
- #include "lcd1602.h"
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- //繼電器控制io
- sbit j1= P3^0;
- sbit j2= P3^1;
- sbit j3= P3^2;
- //---ds1302 IO---//
- sbit DSIO=P3^5;
- sbit RST=P3^3;
- sbit SCLK=P3^4;
- //---DS1302寫入和讀取時(shí)分秒的地址命令---//
- //---秒分時(shí)日月周年 最低位讀寫位;-------//
- uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
- uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
- //---DS1302時(shí)鐘初始化2013年1月1日星期二12點(diǎn)00分00秒。---//
- //---存儲(chǔ)順序是秒分時(shí)日月周年,存儲(chǔ)格式是用BCD碼---//
- uchar TIME[7] = {0x49, 0x49, 0x05, 0x01, 0x01, 0x02, 0x13};
- unsigned table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- unsigned char number=0;
- /********************************************************************
- 延時(shí)函數(shù)
- *********************************************************************/
- void delay10ms(void) //延時(shí)程序
- {
- unsigned char i,j;
- for(i=20;i>0;i--)
- for(j=248;j>0;j--);
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302Write
- * 函數(shù)功能 : 向DS1302命令(地址+數(shù)據(jù))
- * 輸 入 : addr,dat
- * 輸 出 : 無
- *******************************************************************************/
- void Ds1302Write(uchar addr, uchar dat)
- {
- uchar n;
- RST = 0;
- _nop_();
- SCLK = 0;//先將SCLK置低電平。
- _nop_();
- RST = 1; //然后將RST(CE)置高電平。
- _nop_();
- for (n=0; n<8; n++)//開始傳送八位地址命令
- {
- DSIO = addr & 0x01;//數(shù)據(jù)從低位開始傳送
- addr >>= 1;
- SCLK = 1;//數(shù)據(jù)在上升沿時(shí),DS1302讀取數(shù)據(jù)
- _nop_();
- SCLK = 0;
- _nop_();
- }
- for (n=0; n<8; n++)//寫入8位數(shù)據(jù)
- {
- DSIO = dat & 0x01;
- dat >>= 1;
- SCLK = 1;//數(shù)據(jù)在上升沿時(shí),DS1302讀取數(shù)據(jù)
- _nop_();
- SCLK = 0;
- _nop_();
- }
-
- RST = 0;//傳送數(shù)據(jù)結(jié)束
- _nop_();
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302Read
- * 函數(shù)功能 : 讀取一個(gè)地址的數(shù)據(jù)
- * 輸 入 : addr
- * 輸 出 : dat
- *******************************************************************************/
- uchar Ds1302Read(uchar addr)
- {
- uchar n,dat,dat1;
- RST = 0;
- _nop_();
- SCLK = 0;//先將SCLK置低電平。
- _nop_();
- RST = 1;//然后將RST(CE)置高電平。
- _nop_();
- for(n=0; n<8; n++)//開始傳送八位地址命令
- {
- DSIO = addr & 0x01;//數(shù)據(jù)從低位開始傳送
- addr >>= 1;
- SCLK = 1;//數(shù)據(jù)在上升沿時(shí),DS1302讀取數(shù)據(jù)
- _nop_();
- SCLK = 0;//DS1302下降沿時(shí),放置數(shù)據(jù)
- _nop_();
- }
- _nop_();
- for(n=0; n<8; n++)//讀取8位數(shù)據(jù)
- {
- dat1 = DSIO;//從最低位開始接收
- dat = (dat>>1) | (dat1<<7);
- SCLK = 1;
- _nop_();
- SCLK = 0;//DS1302下降沿時(shí),放置數(shù)據(jù)
- _nop_();
- }
- RST = 0;
- _nop_(); //以下為DS1302復(fù)位的穩(wěn)定時(shí)間,必須的。
- SCLK = 1;
- _nop_();
- DSIO = 0;
- _nop_();
- DSIO = 1;
- _nop_();
- return dat;
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302Init
- * 函數(shù)功能 : 初始化DS1302.
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Ds1302Init()
- {
- uchar n;
- Ds1302Write(0x8E,0X00); //禁止寫保護(hù),就是關(guān)閉寫保護(hù)功能
- for (n=0; n<7; n++)//寫入7個(gè)字節(jié)的時(shí)鐘信號(hào):分秒時(shí)日月周年
- {
- Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
- }
- Ds1302Write(0x8E,0x80); //打開寫保護(hù)功能
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302ReadTime
- * 函數(shù)功能 : 讀取時(shí)鐘信息
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Ds1302ReadTime()
- {
- uchar n;
- for (n=0; n<7; n++)//讀取7個(gè)字節(jié)的時(shí)鐘信號(hào):分秒時(shí)日月周年
- {
- TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
- }
- }
- /********************************************************************
- 鍵盤函數(shù)
- *********************************************************************/
- uchar k=0;
- uchar mode=2;
- uchar time1;
- void Getch (void) //取鍵值函數(shù)
- {
- unsigned char X,Y,Z;
- P1=0x0f; //先對(duì)P3 置數(shù) 行掃描
- if(P1!=0x0f) //判斷是否有鍵按下
- {
- delay10ms(); //延時(shí),軟件去干擾
- if(P1!=0x0f) //確認(rèn)按鍵按下
- {
- X=P1; //保存行掃描時(shí)有鍵按下時(shí)狀態(tài)
- P1=0xf0; //列掃描
- Y=P1; //保存列掃描時(shí)有鍵按下時(shí)狀態(tài)
- Z=X|Y; //取出鍵值
- /*********************************************************************/
- switch ( Z ) //判斷鍵值(那一個(gè)鍵按下)
- {
- case 0xee: k=0; break; //對(duì)鍵值賦值
- case 0xed: k=1; break;
- case 0xeb: k=2; break;
- case 0xe7: k=3; break;
- case 0xde: k=4; break;
- case 0xdd: k=5; break;
- case 0xdb: k=6; break;
- case 0xd7: k=7; break;
- case 0xbe: k=8; break;
- case 0xbd: k=9; break;
- case 0xbb: k=10;break;
- case 0xb7: k=11;break;
- case 0x7e: k=12;break;
- case 0x7d: k=13;break;
- case 0x7b: k=14;break;
- case 0x77: k=15;break;
- }
- while(P1!=0xf0); //等待按鍵放開
- }
- }
- }
- uchar j1_time[2]={0x05,0x50};
- uchar j2_time_on[2]={0x05,0x51};
- uchar j2_time_off[2]={0x05,0x52};
- uchar j3_time[2]={0x05,0x52};
- void sel_time(void) //選擇模式
- {
- uchar buff[9];
- static uchar temp[4];
- static uchar num=0;
- if(k==12) {
- time1=1;
- GotoXY(0,1);
- Print(" ");
- GotoXY(0,1);
- Print("1: "); }
- if(k==13) {
- time1=2;
- GotoXY(0,1);
- Print(" ");
- GotoXY(0,1);
- Print("2: "); }
- if(k==14) {
- time1=3;
- GotoXY(0,1);
- Print(" ");
- GotoXY(0,1);
- Print("3: "); }
- if(k==15) {
- time1=4;
- GotoXY(0,1);
- Print(" ");
- GotoXY(0,1);
- Print("4: "); }
- if(time1==1)
- {
- if(k<10)
- {
- temp[num]=k;
- num++;
- if(num>=4)
- {
-
- j1_time[0]=temp[0]*16+temp[1];
- j1_time[1]=temp[2]*16+temp[3];
- GotoXY(4,1);
- buff[0]=j1_time[0]/16 + '0';
- buff[1]=j1_time[0]%16 + '0';
- buff[2]=j1_time[1]/16 + '0';
- buff[3]=j1_time[1]%16 + '0';
- buff[4]='\0';
- Print(buff);
- num=0;
- time1=0;
- }
- k=22;
- }
- }
- if(time1==2)
- {
- if(k<10)
- {
- temp[num]=k;
- num++;
- if(num>=4)
- {
- j2_time_on[0]=temp[0]*16+temp[1];
- j2_time_on[1]=temp[2]*16+temp[3];
- GotoXY(4,1);
- buff[0]=j2_time_on[0]/16 + '0';
- buff[1]=j2_time_on[0]%16 + '0';
- buff[2]=j2_time_on[1]/16 + '0';
- buff[3]=j2_time_on[1]%16 + '0';
- buff[4]='\0';
- Print(buff);
- num=0;
- time1=0;
- }
- }
- k=22;
- }
- if(time1==3)
- {
- if(k<10)
- {
- temp[num]=k;
- num++;
- if(num>=4)
- {
- j2_time_off[0]=temp[0]*16+temp[1];
- j2_time_off[1]=temp[2]*16+temp[3];
- GotoXY(4,1);
- buff[0]=j2_time_off[0]/16 + '0';
- buff[1]=j2_time_off[0]%16 + '0';
- buff[2]=j2_time_off[1]/16 + '0';
- buff[3]=j2_time_off[1]%16 + '0';
- buff[4]='\0';
- Print(buff);
- num=0;
- time1=0;
- }
- k=22;
- }
- }
- if(time1==4)
- {
- if(k<10)
- {
- temp[num]=k;
- num++;
- if(num>=4)
- {
- j3_time[0]=temp[0]*16+temp[1];
- j3_time[1]=temp[2]*16+temp[3];
- GotoXY(4,1);
- buff[0]=j3_time[0]/16 + '0';
- buff[1]=j3_time[0]%16 + '0';
- buff[2]=j3_time[1]/16 + '0';
- buff[3]=j3_time[1]%16 + '0';
- buff[4]='\0';
- Print(buff);
- num=0;
- time1=0;
- }
- }
- k=22;
- }
- }
- void j_control(void) //控制繼電器
- {
- if((j1_time[0] == TIME[2])&&(j1_time[1] == TIME[1]))
- {
- j1=0;
- }
- if((j2_time_on[0] == TIME[2])&&(j2_time_on[1] == TIME[1]))
- {
- j2=0;
- }
- if((j2_time_off[0] == TIME[2])&&(j2_time_off[1] == TIME[1]))
- {
- j2=1;
- }
- if((j3_time[0] == TIME[2])&&(j3_time[1] == TIME[1]))
- {
- j3=0;
- }
- }
- void TimeToStr(unsigned char *buf)
- {
- buf[0] = TIME[2]/16 + '0';
- buf[1] = TIME[2]%16 + '0';
- buf[2] = ':';
- buf[3] = TIME[1]/16 + '0';
- buf[4] = TIME[1]%16 + '0';
- buf[5] = ':';
- buf[6] = TIME[0]/16 + '0';
- buf[7] = TIME[0]%16 + '0';
- buf[8] = '\0';
- }
- void main(void)
- {
- unsigned char time_buf[9];
- Ds1302Init(); //寫入設(shè)置的時(shí)間
- LCD_Initial();
- GotoXY(0,0);
- Print("Time: ");
- while(1)
- {
- Getch();
- sel_time();
- Ds1302ReadTime(); //讀時(shí)間
- TimeToStr(time_buf);
- j_control();
- GotoXY(6,0);
- Print(time_buf);
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
家電控制.rar
(98.36 KB, 下載次數(shù): 33)
2020-6-5 13:20 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|