闹钟定时 温度c文库.docx
《闹钟定时 温度c文库.docx》由会员分享,可在线阅读,更多相关《闹钟定时 温度c文库.docx(50页珍藏版)》请在冰豆网上搜索。
闹钟定时温度c文库
/********************************************************************
*文件名:
时钟DS1302LCD.c
*描述:
该文件实现用DS1302来实现日历和时钟功能,液晶1602上显示出来。
*创建人:
东流,2009年4月10日
*版本号:
2.0
Forpersonaluseonlyinstudyandresearch;notforcommercialuse
***********************************************************************/
#include
#include
Forpersonaluseonlyinstudyandresearch;notforcommercialuse
#defineucharunsignedchar//无符号字符0-255
#defineuintunsignedint//无符号整型0-65535
#defineCYCLE_1_00x698//1688us
#defineCYCLE_1_50x9E4//2532
#defineCYCLE_2_00xD30//3376us
#defineTH_CYCLE_1_0(CYCLE_1_0>>8)
#defineTH_CYCLE_1_5(CYCLE_1_5>>8)
#defineTH_CYCLE_2_0(CYCLE_2_0>>8)
//用于解码的变量
unsignedintSAA3010RecvCode=0;//保存解码数值(1个控制位5个地址位6个命令位)
unsignedcharSAA3010BitCount=0;//记录已经解码的位数
unsignedcharSAA3010State=0;//初始状态
sbitrelayout0=P1^0;
sbitrelayout1=P1^1;
sbitrelayout2=P1^2;
sbitrelayout3=P1^3;
sbitrelayout4=P1^4;
charcodeTab[16]="09ABCDEF";
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitP3_2=P3^2;
sbitP3_4=P3^4;
sbitT_CLK=P1^6;/*实时时钟时钟线引脚*/
sbitT_IO=P3^5;/*实时时钟数据线引脚*/
sbitT_RST=P1^7;/*实时时钟复位线引脚*/
sbitAdd_Key=P3^6;//加1键,S1
sbitDec_Key=P3^7;//减1键,S2
sbitOK_Key=P2^0;//确定键,S3
sbitBell_Out=P2^1;//闹钟管脚输出。
低电平有效
sbitDQ=P2^3;//ds1820data
//这三个引脚参考资料
sbitE=P2^7;//1602使能引脚
sbitRW=P2^6;//1602读写引脚
sbitRS=P2^5;//1602数据/命令选择引脚
bitflag,secs=0,mins=0,hours=0,years=0,mons=0,days=0,weeks=0;//闪烁标志位
bitBell_Swh,Hourb,Minb,Secb,Kgb;//闹钟调时闪烁标志位
bitflag_min=0,flag_sec=0;//整点报警标志位
unsignedcharid,id2,d,e,S_1302,H_1302,H_Bell,S_Bell;//id为第几个调整对象,
ucharsec,min,hour,day,month,year,week;
/************************************************************/
//函数声明
voiddelay();
voidDelay1(intnum);//延时函数
ucharbcdtodec(ucharbcd);
ucharConvert(ucharIn_Date);//形参主函数付的值
uchardectobcd(uchardec);
voidDisp(void);//显示和闪烁函数
voidenable(uchardel);
voidid_case1_key(void);//id为1时的下一级选择
voidL1602_char(ucharhang,ucharlie,charsign);
voidL1602_init(void);
voidL1602_string(ucharhang,ucharlie,uchar*p);
voidRun_DS1302(void);
ucharuc_RTOutputByte(void);
voidv_BurstR1302R(uchar*pReDa);
voidv_BurstR1302T(uchar*pSecDa);
voidv_BurstW1302R(uchar*pReDa);
voidv_BurstW1302T(uchar*pSecDa);
voidv_Get1302(ucharucCurtime[]);
voidv_RTInputByte(ucharucDa);
voidv_Set1302(uchar*pSecDa);
voidv_W1302(ucharucAddr,ucharucDa);
voidwrite(uchardel);
voidWrite_DS1302Init(void);
voidDelay2(unsignedintt);//
voidDisp2(void);//显示和闪烁函数
voidid_case2_key(void);//id2为1时的下一级选择
voidSet_Bell(unsignedcharsel,bitsel_1);//根据选择调整相应项目并写入
unsignedintReadTemperature(void);//读取温度
voidInit_DS18B20(void);//初始化ds1820
unsignedcharReadOneChar(void);//温度读一个字节
voidWriteOneChar(unsignedchardat);//温度写一个字节
voidDelayUs(unsignedcharus);//us延时
voidDelayMs(unsignedcharms);//Ms延时
/********************************************************************
*名称:
delay()
*功能:
延时,延时时间大概为140US。
*输入:
无
*输出:
无
***********************************************************************/
voiddelay()//void为函数类型,说明返回数值的类型,要返回就要有return,如不,则void
{
inti,j;
for(i=0;i<=10;i++)
for(j=0;j<=2;j++)
;
}
/******************************************************************************/
voidDelay1(intnum)//延时函数
{
while(num--);
}
/*****************************************************************/
voidDelay2(unsignedintt)//
{
unsignedinti,j;
for(i=0;i{
for(j=0;j<10;j++);
}
}
/******************************************************************/
voidDelayUs(unsignedcharus);//us延时
voidDelayMs(unsignedcharms);//Ms延时
/********************************************************************/
voidDelayUs(unsignedcharus)//us延时
{
unsignedcharuscnt;
uscnt=us>>1;/*Crystalfrequencyin12MHz*/
while(--uscnt);
}
/******************************************************************/
voidDelayMs(unsignedcharms)//Ms延时
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
/*******************************************************************/
voidSAA3010ProcessCommand(intremotecode)//红外处理命令
{
unsignedcharbuffer[3];
buffer[0]=0x80;
buffer[1]=(unsignedchar)((remotecode>>8)&0xFF);
buffer[2]=(unsignedchar)(remotecode&0xFF);
if(buffer[2]==0x04)relayout4=~relayout4;
if(buffer[2]==0x03)relayout3=~relayout3;
if(buffer[2]==0x02)relayout2=~relayout2;
if(buffer[2]==0x01)relayout1=~relayout1;
if(buffer[2]==0x0c)relayout0=~relayout0;
DelayMs(1000);
}
/***************************************************************/
voidSAA3010Init()//初始化中断及定时器
{
EA=1;
TMOD=0x10;//T1工作于方式1,即16位定时器
ET1=1;//关定时器0中断允许
TR1=1;//关闭定时器
TH1=0;
TL1=0;
//外部中断源INT0
EX1=1;//允许外部中断源INT1
PX1=1;//外部中断源为高优先级
IT1=1;//边缘触发
SAA3010BitCount=0;
SAA3010RecvCode=0;
SAA3010State=0;
}
/*****************************************************************/
voidSAA3010Timer1(void)interrupt3//定时器T1的中断处理函数
{
//出现了超时
if(SAA3010BitCount==13)
{
if(SAA3010State==1||//1,1
SAA3010State==2)//0,1
{
SAA3010BitCount++;
SAA3010RecvCode=SAA3010RecvCode<<1;
SAA3010RecvCode=SAA3010RecvCode+1;
}
}
//检查是否有合理数据
if(SAA3010BitCount==14)
{
//停止中断0
EX1=0;
//处理遥控命令
SAA3010ProcessCommand((~SAA3010RecvCode)&0x0FFF);
}
//重新初始化初始化
SAA3010BitCount=0;
SAA3010State=0;
//启用中断
EX1=1;
}
/***************************************************************/
voidSAA3010Int1(void)interrupt2//外部中断1的处理函数
{
//保存计数器的高位,作为判断周期长短的依据
unsignedcharHighTick=TH1;
//重置计数器
TH1=0;TL1=0;TR1=1;ET1=1;
//状态转移图
switch(SAA3010State)
{
case0:
//第一个起始位
SAA3010State=2;
SAA3010BitCount=1;
SAA3010RecvCode=0;
break;
case1:
//状态1
if(HighTick==TH_CYCLE_1_0)//S1->S1
{
SAA3010State=1;
SAA3010BitCount++;
SAA3010RecvCode=SAA3010RecvCode<<1;
SAA3010RecvCode=SAA3010RecvCode+1;
}
elseif(HighTick==TH_CYCLE_1_5)//S1->S2(1,1,0)
{
SAA3010State=2;
SAA3010BitCount=SAA3010BitCount+2;
SAA3010RecvCode=SAA3010RecvCode<<1;
SAA3010RecvCode=SAA3010RecvCode+1;
SAA3010RecvCode=SAA3010RecvCode<<1;
}
else//错误状态
{
SAA3010BitCount=0;
SAA3010State=0;
}
break;
case2:
//状态2
if(HighTick==TH_CYCLE_1_0)//S2->S2
{
SAA3010State=2;
SAA3010BitCount++;
SAA3010RecvCode=SAA3010RecvCode<<1;
}
elseif(HighTick==TH_CYCLE_1_5)//S2->S1
{
SAA3010State=1;
SAA3010BitCount++;
SAA3010RecvCode=SAA3010RecvCode<<1;
SAA3010RecvCode=SAA3010RecvCode+1;
}
elseif(HighTick==TH_CYCLE_2_0)//S2->S2
{
//0->1->0
SAA3010State=2;
SAA3010BitCount=SAA3010BitCount+2;
SAA3010RecvCode=SAA3010RecvCode<<1;
SAA3010RecvCode=SAA3010RecvCode+1;
SAA3010RecvCode=SAA3010RecvCode<<1;
}
else//错误状态
{
SAA3010BitCount=0;
SAA3010State=0;
}
break;
}
}
/***********************************************************/
voidBeep(void)//BELL蜂明器发声,整点报警
{
Bell_Out=0;
Delay1(6000);//50ms
Bell_Out=1;
Delay1(6000);//50ms
}
/*****************************************************************************/
voidBell_now(void)
{
Bell_Out=0;
Delay1(31250);//for250ms
Bell_Out=1;
Delay1(6350);//50ms
Bell_Out=0;
Delay1(18750);//150ms
Bell_Out=1;
Delay1(50000);//400ms
}
/******************************************************************************/
voidWriteOneChar(unsignedchardat)//温度写一个字节
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
Delay1(5);
DQ=1;
dat>>=1;
}
}
/******************************************************************************/
unsignedcharReadOneChar(void)//温度读一个字节
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
Delay1(4);
}
return(dat);
}
/****************************************************************/
unsignedintReadTemperature(void)//读取温度
{
unsignedcharTMPL=0;
unsignedcharTMPH=0;
unsignedinttemp=0;
floattt=0;
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器
TMPL=ReadOneChar();//读低8位
TMPH=ReadOneChar();//读高8位
temp=TMPH;
temp<<=8;
temp=temp|TMPL;
tt=TMPL*0.0625;
temp=TMPL/16+TMPH*16;
return(temp);
}
/********************************************************************
*名称:
Convert(ucharIn_Date)
*功能:
因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。
*输入:
1602资料上的值
*输出:
送到1602的值
***********************************************************************/
ucharConvert(ucharIn_Date)//形参主函数付的值
{
uchari,Out_Date=0,temp=0;
for(i=0;i<8;i++)
{
temp=(In_Date>>i)&0x01;
Out_Date|=(temp<<(7-i));
}
returnOut_Date;
}
/********************************************************************
*名称:
enable(uchardel)
*功能:
1602写命令函数
*输入:
输入的命令值
*输出:
无
***********************************************************************/
voidenable(uchardel)
{
P0=Convert(del);
RS=0;
RW=0;
E=0;
delay();
E=1;
delay();
}
/********************************************************************
*名称:
write(uchardel)
*功能:
1602写数据函数
*输入:
需要写入1602的数据
*输出:
无
***********************************************************************/
voidwrite(uchardel)
{
P0=Convert(del);
RS=1;
RW=0;
E=0;
delay();
E=1;
delay();
}
/*******************************************************************************/
voidInit_DS18