下面的C语言程序单片机STC89C51控制继电器2秒吸合,2秒断开,程序使用KEILL3开发。
#include<reg52.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
unsigned char code digit[10]={"0123456789"}; //定义字符数组显示数字
//2013年9月26日,修正DS1302 干扰P1口LED灯问题
sbit SCLK=P1^7; //位定义1302芯片的接口,时钟输出端口定义在P1.7引脚
sbit DATA=P2^7; //位定义1302芯片的接口,数据输出端定义在P2.7引脚
sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.2引脚
sbit cs88=P2^2;
sbit DU = P2^0;
sbit WE = P2^1;
#define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B
#define OP_WRITE 0xa0 // 器件地址以及写入操作,0xa1即为1010 0000B
sbit SDA=P1^2; //将串行数据总线SDA位定义在为P1.2引脚 HL-1 接在P2.0
sbit SCL=P1^7; //将串行时钟总线SCL位定义在为P1.7引脚 HL-1 接在P2.1
//sbit SDA=P3^4; //将串行数据总线SDA位定义在为P1.2引脚 HL-1 接在P2.0
//sbit SCL=P3^3; //将串行时钟总线SCL位定义在为P1.7引脚 HL-1 接在P2.1
void Delay_ms(unsigned int uiMs); //ms延时函数,12M晶振有效
sbit sw = P1^4; //引脚定义
// sbit sw = P2^3; //引脚定义
unsigned char scan_key();
void proc_key(unsigned char key_v);
void delayms(unsigned char ms);
unsigned char key_s,key_v;
sbit K1 = P3^6;
sbit K2 = P3^5;
unsigned char scan_key()
{
unsigned char key_s;
key_s = 0x00;
key_s |= K2;
key_s <<= 1;
key_s |= K1;
// key_s = 0x00;
// key_s |= K2;
// key_s = 0x00;
// key_s |= K1;
return key_s;
}
/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++);
}
void cmg88()//关数码管,点阵函数
{
DU=1;
P0=0X00;
DU=0;
}
void delayms(unsigned char ms)
// 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:x
***************************************************/
void Write1302(unsigned char dat)
{
unsigned char i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后
delaynus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
/*****************************************************
函数功能:根据命令字,向1302写一个字节数据
入口参数:Cmd,储存命令字;dat,储存待写的数据
***************************************************/
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于高电平状态
RST=0; //禁止数据传递
}
/*****************************************************
函数功能:从1302读一个字节数据
入口参数:x
***************************************************/
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{ dat>>=1;
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
/*****************************************************
函数功能:根据命令字,从1302读取一个字节数据
入口参数:Cmd
***************************************************/
unsigned char ReadSet1302(unsigned char Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
void Init_DS1302(void)
{
unsigned char flag;
flag= ReadSet1302(0x81);
if(flag&0x80) { //判断时钟芯片是否关闭
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
}
//如果不想每次都初始化时间,也就是掉电后还想让时钟继续走时的话 就用上面的语句
/*--------------------这是每次都初始化的语句-----------------*/
/*
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
*/
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
sbit RS=P1^0; //寄存器选择位,将RS位定义为P1.0引脚
sbit RW=P1^1; //读写选择位,将RW位定义为P1.1引脚
sbit E=P2^5; //使能信号位,将E位定义为P2.5引脚
sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/*****************************************************
函数功能:判断液晶模块的忙碌状态
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
bit BusyTest(void)
{
bit result;
RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1; //E=1,才允许读写
_nop_(); //空操作
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
result=BF; //将忙碌标志电平赋给result
E=0; //将E恢复低电平
return result;
}
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void WriteInstruction (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_(); //空操作两个机器周期,给硬件反应时间
P0=dictate; //将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
P0=y; //将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LcdInitiate(void)
{
delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x38);
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x38); //连续三次,确保初始化成功
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x06); //显示模式设置:光标右移,字符不移
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除
delaynms(5); //延时5ms ,给硬件一点反应时间
}
/**************************************************************
以下是1302数据的显示程序
**************************************************************/
/*****************************************************
函数功能:显示秒
入口参数:x
***************************************************/
void DisplaySecond(unsigned char x)
{
unsigned char i,j; //j,k分别储存十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x49); //写显示地址,将在第2行第7列开始显示
WriteData(digit); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示分钟
入口参数:x
***************************************************/
void DisplayMinute(unsigned char x)
{
unsigned char i,j; //j,k十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x46); //写显示地址,将在第2行第7列开始显示
WriteData(digit); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示小时
入口参数:x
***************************************************/
void DisplayHour(unsigned char x)
{
unsigned char i,j; //j,k十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x43); //写显示地址,将在第2行第7列开始显示
WriteData(digit); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示日
入口参数:x
***************************************************/
void DisplayDay(unsigned char x)
{
unsigned char i,j; //j,k十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x0c); //写显示地址,将在第2行第7列开始显示
WriteData(digit); //将十位数字的字符常量写入LCD
WriteData(digit[j]); //将个位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示月
入口参数:x
***************************************************/
void DisplayMonth(unsigned char x)
{
unsigned char i,j; //j,k分别储存十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x09); //写显示地址,将在第2行第7列开始显示
WriteData(digit); //将十位位数字的字符常量写入LCD
WriteData(digit[j]); //将个位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示年
入口参数:x
***************************************************/
void DisplayYear(unsigned char x)
{
unsigned char i,j; //j,k分别储存十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x06); //写显示地址,将在第2行第7列开始显示
WriteData(digit); //将十位位数字的字符常量写入LCD
WriteData(digit[j]); //将个位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:延时1ms
***************************************************/
//void delay1ms()
//{
// unsigned char i,j;
// for(i=0;i<10;i++)
// for(j=0;j<33;j++)
// ;
// }
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
// void delaynms(unsigned char n)
// {
// unsigned char i;
// for(i=0;i<n;i++)
// delay1ms();
// }
/***************************************************
函数功能:开始数据传送
***************************************************/
void start()
// 开始位
{
SDA = 1; //SDA初始化为高电平“1”
SCL = 1; //开始数据传送时,要求SCL为高电平“1”
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA = 0; //SDA的下降沿被认为是开始信号
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
}
/***************************************************
函数功能:结束数据传送
***************************************************/
void stop()
// 停止位
{
SDA = 0; //SDA初始化为低电平“0” _n
SCL = 1; //结束数据传送时,要求SCL为高电平“1”
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA = 1; //SDA的上升沿被认为是结束信号
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA=0;
SCL=0;
}
/***************************************************
函数功能:从AT24Cxx读取数据
出口参数:x
***************************************************/
unsigned char ReadData()
// 从AT24Cxx移入数据到MCU
{
unsigned char i;
unsigned char x; //储存从AT24Cxx中读出的数据
for(i = 0; i < 8; i++)
{
SCL = 1; //SCL置为高电平
x<<=1; //将x中的各二进位向左移一位
x|=(unsigned char)SDA; //将SDA上的数据通过按位“或“运算存入x中
SCL = 0; //在SCL的下降沿读出数据
}
return(x); //将读取的数据返回
}
/***************************************************
函数功能:向AT24Cxx的当前地址写入数据
入口参数:y (储存待写入的数据)
***************************************************/
//在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0
bit WriteCurrent(unsigned char y)
{
unsigned char i;
bit ack_bit; //储存应答位
for(i = 0; i < 8; i++) // 循环移入8个位
{
SDA = (bit)(y&0x80); //通过按位“与”运算将最高位数据送到S
//因为传送时高位在前,低位在后
_nop_(); //等待一个机器周期
SCL = 1; //在SCL的上升沿将数据写入AT24Cxx
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 0; //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
y <<= 1; //将y中的各二进位向左移一位
}
SDA = 1; // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
//以让SDA线转由接收设备(AT24Cxx)控制
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 1; //根据上述规定,SCL应为高电平
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
//若送高电平,表示没有接收到,传送异常
SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
return ack_bit; // 返回AT24Cxx应答位
}
/***************************************************
函数功能:向AT24Cxx中的指定地址写入数据
入口参数:add (储存指定的地址);dat(储存待写入的数据)
***************************************************/
void WriteSet(unsigned char add, unsigned char dat)
// 在指定地址addr处写入数据WriteCurrent
{
start(); //开始数据传递
WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据
WriteCurrent(add); //写入指定地址
WriteCurrent(dat); //向当前地址(上面指定的地址)写入数据
stop(); //停止数据传递
delaynms(4); //1个字节的写入周期为1ms, 最好延时1ms以上
}
/***************************************************
函数功能:从AT24Cxx中的当前地址读取数据
出口参数:x (储存读出的数据)
***************************************************/
unsigned char ReadCurrent()
{
unsigned char x;
start(); //开始数据传递
WriteCurrent(OP_READ); //选择要操作的AT24Cxx芯片,并告知要读其数据
x=ReadData(); //将读取的数据存入x
stop(); //停止数据传递
return x; //返回读取的数据
}
/***************************************************
函数功能:从AT24Cxx中的指定地址读取数据
入口参数:set_addr
出口参数:x
***************************************************/
unsigned char ReadSet(unsigned char set_addr)
// 在指定地址读取
{
start(); //开始数据传递
WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据
WriteCurrent(set_addr); //写入指定地址
return(ReadCurrent()); //从指定地址读出数据并返回
}
void proc_key(unsigned char key_v)
{
unsigned char second,minute,hour,day,month,year; //分别储存秒、分、小时,日,月,年
unsigned char Readvalue; //储存从1302读取的数据
unsigned char Readvalue1,Readvalue2; //储存从1302读取的数据
unsigned char minute1,minute2,shuju,shuju1,shuju2; //储存从1302读取的数据
unsigned int i;
if((key_v & 0x01) == 0)
{
// P0 = _cror_(P0,1);
anjian:
for(i=0;i<6;i++)// 设置继电器吸合时间为4s
{
Readvalue = ReadSet1302(0x81); //从秒寄存器读数据
// WriteSet(0x01,Readvalue); //写入显示代码到AT24C02
second=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F);//将读出数据转化
DisplaySecond(second); //显示秒
Readvalue = ReadSet1302(0x83); //从分寄存器读
minute=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayMinute(minute); //显示分
Readvalue = ReadSet1302(0x85); //从时寄存器读
hour=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayHour(hour); //显示小时
Readvalue = ReadSet1302(0x87); //从日寄存器读
day=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayDay(day); //显示日
Readvalue = ReadSet1302(0x89); //从月寄存器读
month=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayMonth(month); //显示月
Readvalue = ReadSet1302(0x8d); //从年寄存器读
year=((Readvalue&0xf0)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayYear(year); //显示年
Readvalue1 = ReadSet1302(0x81); //从分寄存器读
minute1=((Readvalue1&0x70)>>4)*10 + (Readvalue1&0x0F); //将读出数据转化
WriteSet(0x01,minute1); //写入显示代码到AT24C02
// WriteSet(0x01,Readvalue1); //写入显示代码到AT24C02
// Delay_ms(120);
}
Readvalue2 = ReadSet1302(0x81); //从分寄存器读
minute2=((Readvalue2&0x70)>>4)*10 + (Readvalue2&0x0F); //将读出数据转化
WriteSet(0x02,minute2); //写入显示代码到AT24C02
// WriteSet(0x02,Readvalue2); //写入显示代码到AT24C02
// Delay_ms(120);
shuju = ReadSet(0x01); //从AT24C02移出数据送到P1口显示
shuju1 = ReadSet(0x02); //从AT24C02移出数据送到P1口显示
shuju2=ReadSet(0x01)-ReadSet(0x02);
//shuju2=shuju1-shuju;
//if(shuju2=0x02)
// shuju2=3;
if(shuju2<6)
// if(shuju2=2)
{
sw = 0;
// Delay_ms(100);
}
else
{
sw = 1;
// Delay_ms(100);
}
for(i=0;i<6;i++)
{
Readvalue = ReadSet1302(0x81); //从秒寄存器读数据
// WriteSet(0x01,Readvalue); //写入显示代码到AT24C02
second=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F);//将读出数据转化
DisplaySecond(second); //显示秒
Readvalue = ReadSet1302(0x83); //从分寄存器读
minute=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayMinute(minute); //显示分
Readvalue = ReadSet1302(0x85); //从时寄存器读
hour=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayHour(hour); //显示小时
Readvalue = ReadSet1302(0x87); //从日寄存器读
day=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayDay(day); //显示日
Readvalue = ReadSet1302(0x89); //从月寄存器读
month=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayMonth(month); //显示月
Readvalue = ReadSet1302(0x8d); //从年寄存器读
year=((Readvalue&0xf0)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayYear(year); //显示年
Readvalue1 = ReadSet1302(0x81); //从分寄存器读
minute1=((Readvalue1&0x70)>>4)*10 + (Readvalue1&0x0F); //将读出数据转化
WriteSet(0x01,minute1); //写入显示代码到AT24C02
// WriteSet(0x01,Readvalue1); //写入显示代码到AT24C02
// Delay_ms(120);
}
Readvalue2 = ReadSet1302(0x81); //从分寄存器读
minute2=((Readvalue2&0x70)>>4)*10 + (Readvalue2&0x0F); //将读出数据转化
WriteSet(0x02,minute2); //写入显示代码到AT24C02
// WriteSet(0x02,Readvalue2); //写入显示代码到AT24C02
// Delay_ms(120);
shuju = ReadSet(0x01); //从AT24C02移出数据送到P1口显示
shuju1 = ReadSet(0x02); //从AT24C02移出数据送到P1口显示
shuju2=ReadSet(0x01)-ReadSet(0x02);
// shuju2=shuju1-shuju;
// if(shuju2=0x02)
// shuju2=3;
if(shuju2<6)
// if(shuju2=2)
{
sw = 1;
// Delay_ms(100);
}
else
{
sw = 0;
// Delay_ms(100);
}
}
else if((key_v & 0x02) == 0)
{
// P0 = _crol_(P0, 1);
Readvalue = ReadSet1302(0x81); //从秒寄存器读数据
// WriteSet(0x01,Readvalue); //写入显示代码到AT24C02
second=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F);//将读出数据转化
DisplaySecond(second); //显示秒
Readvalue = ReadSet1302(0x83); //从分寄存器读
minute=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayMinute(minute); //显示分
Readvalue = ReadSet1302(0x85); //从时寄存器读
hour=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayHour(hour); //显示小时
Readvalue = ReadSet1302(0x87); //从日寄存器读
day=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayDay(day); //显示日
Readvalue = ReadSet1302(0x89); //从月寄存器读
month=((Readvalue&0x70)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayMonth(month); //显示月
Readvalue = ReadSet1302(0x8d); //从年寄存器读
year=((Readvalue&0xf0)>>4)*10 + (Readvalue&0x0F); //将读出数据转化
DisplayYear(year); //显示年
Readvalue1 = ReadSet1302(0x81); //从分寄存器读
minute1=((Readvalue1&0x70)>>4)*10 + (Readvalue1&0x0F); //将读出数据转化
sw = 1;
}
goto anjian;
}
/*****************************************************
函数功能:主函数
***************************************************/
void main(void)
{
// next:
cmg88();
LcdInitiate(); //将液晶初始化
WriteAddress(0x01); //写Date的显示地址,将在第1行第2列开始显示
WriteData('D'); //将字符常量写入LCD
WriteData('a'); //将字符常量写入LCD
WriteData('t'); //将字符常量写入LCD
WriteData('e'); //将字符常量写入LCD
WriteData(':'); //将字符常量写入LCD
WriteAddress(0x08); //写年月分隔符的显示地址, 显示在第1行第9列
WriteData('-'); //将字符常量写入LCD
WriteAddress(0x0b); //写月日分隔符的显示地址, 显示在第1行第12列
WriteData('-'); //将字符常量写入LCD
WriteAddress(0x45); //写小时与分钟分隔符的显示地址, 显示在第2行第6列
WriteData(':'); //将字符常量写入LCD
WriteAddress(0x48); //写分钟与秒分隔符的显示地址, 显示在第2行第9列
WriteData(':'); //将字符常量写入LCD
Init_DS1302(); //将1302初始化
SDA = 1; // SDA=1,SCL=1,使主从设备处于空闲状态
SCL = 1;
key_v = 0x03;
while(1)
{
key_s = scan_key();
if(key_s != key_v)
{
delayms(10);
key_s = scan_key();
if(key_s != key_v)
{
key_v = key_s;
proc_key(key_v);
}
}
}
}
void Delay_ms(unsigned int uiMs) //ms延时函数
{
unsigned int i;
for(;uiMs > 0;uiMs--)
{
for(i = 1498;i > 0;i--);
}
}