仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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写入和读取时分秒的地址命令---//
- //---秒分时日月周年 最低位读写位;-------//
- 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时钟初始化2013年1月1日星期二12点00分00秒。---//
- //---存储顺序是秒分时日月周年,存储格式是用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;
- /********************************************************************
- 延时函数
- *********************************************************************/
- void delay10ms(void) //延时程序
- {
- unsigned char i,j;
- for(i=20;i>0;i--)
- for(j=248;j>0;j--);
- }
- /*******************************************************************************
- * 函 数 名 : Ds1302Write
- * 函数功能 : 向DS1302命令(地址+数据)
- * 输 入 : 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;//数据从低位开始传送
- addr >>= 1;
- SCLK = 1;//数据在上升沿时,DS1302读取数据
- _nop_();
- SCLK = 0;
- _nop_();
- }
- for (n=0; n<8; n++)//写入8位数据
- {
- DSIO = dat & 0x01;
- dat >>= 1;
- SCLK = 1;//数据在上升沿时,DS1302读取数据
- _nop_();
- SCLK = 0;
- _nop_();
- }
-
- RST = 0;//传送数据结束
- _nop_();
- }
- /*******************************************************************************
- * 函 数 名 : Ds1302Read
- * 函数功能 : 读取一个地址的数据
- * 输 入 : 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;//数据从低位开始传送
- addr >>= 1;
- SCLK = 1;//数据在上升沿时,DS1302读取数据
- _nop_();
- SCLK = 0;//DS1302下降沿时,放置数据
- _nop_();
- }
- _nop_();
- for(n=0; n<8; n++)//读取8位数据
- {
- dat1 = DSIO;//从最低位开始接收
- dat = (dat>>1) | (dat1<<7);
- SCLK = 1;
- _nop_();
- SCLK = 0;//DS1302下降沿时,放置数据
- _nop_();
- }
- RST = 0;
- _nop_(); //以下为DS1302复位的稳定时间,必须的。
- SCLK = 1;
- _nop_();
- DSIO = 0;
- _nop_();
- DSIO = 1;
- _nop_();
- return dat;
- }
- /*******************************************************************************
- * 函 数 名 : Ds1302Init
- * 函数功能 : 初始化DS1302.
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Ds1302Init()
- {
- uchar n;
- Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能
- for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
- {
- Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
- }
- Ds1302Write(0x8E,0x80); //打开写保护功能
- }
- /*******************************************************************************
- * 函 数 名 : Ds1302ReadTime
- * 函数功能 : 读取时钟信息
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Ds1302ReadTime()
- {
- uchar n;
- for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
- {
- TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
- }
- }
- /********************************************************************
- 键盘函数
- *********************************************************************/
- uchar k=0;
- uchar mode=2;
- uchar time1;
- void Getch (void) //取键值函数
- {
- unsigned char X,Y,Z;
- P1=0x0f; //先对P3 置数 行扫描
- if(P1!=0x0f) //判断是否有键按下
- {
- delay10ms(); //延时,软件去干扰
- if(P1!=0x0f) //确认按键按下
- {
- X=P1; //保存行扫描时有键按下时状态
- P1=0xf0; //列扫描
- Y=P1; //保存列扫描时有键按下时状态
- Z=X|Y; //取出键值
- /*********************************************************************/
- switch ( Z ) //判断键值(那一个键按下)
- {
- case 0xee: k=0; break; //对键值赋值
- 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(); //写入设置的时间
- LCD_Initial();
- GotoXY(0,0);
- Print("Time: ");
- while(1)
- {
- Getch();
- sel_time();
- Ds1302ReadTime(); //读时间
- TimeToStr(time_buf);
- j_control();
- GotoXY(6,0);
- Print(time_buf);
- }
- }
复制代码
所有资料51hei提供下载:
家电控制.rar
(98.36 KB, 下载次数: 33)
|