18B20测温 1302时钟程序.docx
《18B20测温 1302时钟程序.docx》由会员分享,可在线阅读,更多相关《18B20测温 1302时钟程序.docx(28页珍藏版)》请在冰豆网上搜索。
18B20测温1302时钟程序
#include//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include
#defineKeyPortP3//定义按键端口
#defineDataPortP0//1602端口
#defineds1302_sec_add0x80//秒数据地址
#defineds1302_min_add0x82//分数据地址
#defineds1302_hr_add0x84//时数据地址
#defineds1302_date_add0x86//日数据地址
#defineds1302_month_add0x88//月数据地址
#defineds1302_day_add0x8a//星期数据地址
#defineds1302_year_add0x8c//年数据地址
#defineds1302_control_add0x8e//控制数据地址
#defineds1302_charger_add0x90
#defineds1302_clkburst_add0xbe
bitReadTempFlag;//1820定义读时间标志
sbitDQ=P1^3;//18B20信号端
sbitbz=P1^2;//喇叭
sbitled1=P1^0;
sbitled2=P1^1;
sbitSCK=P1^4;//DS1302控制端
sbitSDA=P1^5;
sbitRST=P1^6;
sbitRS=P2^4;//1602控制端定义端口
sbitRW=P2^5;
sbitEN=P2^6;//使能信号
bitReadTimeFlags;//1302定义读时间标志
bitSetFlag;//更新时间标志位
voidInit_Timer0(void);//定时器初始化
voidInit_Timer1(void);//定时器初始化
unsignedcharKeyScan(void);//键盘扫描
#defineRS_CLRRS=0
#defineRS_SETRS=1
#defineRW_CLRRW=0
#defineRW_SETRW=1
#defineEN_CLREN=0
#defineEN_SETEN=1
//复位脚
#defineRST_CLRRST=0//电平置低
#defineRST_SETRST=1//电平置高
//双向数据
#defineIO_CLRSDA=0//电平置低
#defineIO_SETSDA=1//电平置高
#defineIO_RSDA//电平读取
//时钟信号
#defineSCK_CLRSCK=0//时钟信号
#defineSCK_SETSCK=1//电平置高
unsignedchartime_buf2[16];
unsignedchartime_buf[8]={20,10,6,5,12,55,00,6};//空年月日时分秒周
unsignedchartime_buf1[8];//空年月日时分秒周
voidDelayUs2x(unsignedchart)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
voidDelayMs(unsignedchart)
{
while(t--)//大致延时1mS
{
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bitLCD_Check_Busy(void)
{
DataPort=0xFF;
RS_CLR;
RW_SET;
EN_CLR;
EN_SET;
return(bit)(DataPort&0x80);//第一括号是强制转换为Bit类型,第二个是返回端口的信息
return0;
}
/*------------------------------------------------
写入命令函数
---------------------------------------------*/
voidLCD_Write_Com(unsignedcharcom)
{
while(LCD_Check_Busy());//忙则等待
RS_CLR;
RW_CLR;
DataPort=com;
EN_SET;
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
voidLCD_Write_Data(unsignedcharData)
{
while(LCD_Check_Busy());//忙则等待
RS_SET;
RW_CLR;
EN_SET;
DataPort=Data;
EN_CLR;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
voidLCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
voidLCD_Write_String(unsignedcharx,unsignedchary,unsignedchar*s)
{
if(y==0)
{
LCD_Write_Com(0x80+x);//表示第一行
}
else
{
LCD_Write_Com(0xC0+x);//表示第二行
}
while(*s)
{
LCD_Write_Data(*s);
s++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
voidLCD_Write_Char(unsignedcharx,unsignedchary,unsignedcharData)
{
if(y==0)
{
LCD_Write_Com(0x80+x);
}
else
{
LCD_Write_Com(0xC0+x);
}
LCD_Write_Data(Data);
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
voidLCD_Init(void)
{
LCD_Write_Com(0x38);/*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08);/*显示关闭*/
LCD_Write_Com(0x01);/*显示清屏*/
LCD_Write_Com(0x06);/*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C);/*显示开及光标设置*/
}
/*------------------------------------------------
向DS1302写入一字节数据
------------------------------------------------*/
voidDs1302_Write_Byte(unsignedcharaddr,unsignedchard)
{
unsignedchari;
RST_SET;
//写入目标地址:
addr
addr=addr&0xFE;//最低位置零
for(i=0;i<8;i++)
{
if(addr&0x01)
{
IO_SET;
}
else
{
IO_CLR;
}
SCK_SET;
SCK_CLR;
addr=addr>>1;
}
//写入数据:
d
for(i=0;i<8;i++)
{
if(d&0x01)
{
IO_SET;
}
else
{
IO_CLR;
}
SCK_SET;
SCK_CLR;
d=d>>1;
}
RST_CLR;//停止DS1302总线
}
/*------------------------------------------------
从DS1302读出一字节数据
------------------------------------------------*/
unsignedcharDs1302_Read_Byte(unsignedcharaddr)
{
unsignedchari;
unsignedchartemps;
RST_SET;
//写入目标地址:
addr
addr=addr|0x01;//最低位置高
for(i=0;i<8;i++)
{
if(addr&0x01)
{
IO_SET;
}
else
{
IO_CLR;
}
SCK_SET;
SCK_CLR;
addr=addr>>1;
}
//输出数据:
temps
for(i=0;i<8;i++)
{
temps=temps>>1;
if(IO_R)
{
temps|=0x80;
}
else
{
temps&=0x7F;
}
SCK_SET;
SCK_CLR;
}
RST_CLR;//停止DS1302总线
returntemps;
}
/*------------------------------------------------
向DS1302写入时钟数据
------------------------------------------------*/
voidDs1302_Write_Time(void)
{
unsignedchari,tmps;
for(i=0;i<8;i++)
{//BCD处理
tmps=time_buf1[i]/10;
time_buf[i]=time_buf1[i]%10;
time_buf[i]=time_buf[i]+tmps*16;
}
Ds1302_Write_Byte(ds1302_control_add,0x00);//关闭写保护
Ds1302_Write_Byte(ds1302_sec_add,0x80);//暂停
Ds1302_Write_Byte(ds1302_year_add,time_buf[1]);//年
Ds1302_Write_Byte(ds1302_month_add,time_buf[2]);//月
Ds1302_Write_Byte(ds1302_date_add,time_buf[3]);//日
Ds1302_Write_Byte(ds1302_day_add,time_buf[7]);//周
Ds1302_Write_Byte(ds1302_hr_add,time_buf[4]);//时
Ds1302_Write_Byte(ds1302_min_add,time_buf[5]);//分
Ds1302_Write_Byte(ds1302_sec_add,time_buf[6]);//秒
Ds1302_Write_Byte(ds1302_control_add,0x80);//打开写保护
}
/*------------------------------------------------
从DS1302读出时钟数据
------------------------------------------------*/
voidDs1302_Read_Time(void)
{
unsignedchari,tmps;
time_buf[1]=Ds1302_Read_Byte(ds1302_year_add);//年
time_buf[2]=Ds1302_Read_Byte(ds1302_month_add);//月
time_buf[3]=Ds1302_Read_Byte(ds1302_date_add);//日
time_buf[4]=Ds1302_Read_Byte(ds1302_hr_add);//时
time_buf[5]=Ds1302_Read_Byte(ds1302_min_add);//分
time_buf[6]=Ds1302_Read_Byte(ds1302_sec_add);//秒
time_buf[7]=Ds1302_Read_Byte(ds1302_day_add);//周
for(i=0;i<8;i++)
{//BCD处理
tmps=time_buf[i]/16;
time_buf1[i]=time_buf[i]%16;
time_buf1[i]=time_buf1[i]+tmps*10;
}
}
/*------------------------------------------------
DS1302初始化
------------------------------------------------*/
voidDs1302_Init(void)
{
RST_CLR;//RST脚置低
SCK_CLR;//SCK脚置低
Ds1302_Write_Byte(ds1302_sec_add,0x00);
}
/*------------------------------------------------
18b20初始化
------------------------------------------------*/
bitInit_DS18B20(void)
{
bitdat=0;
DQ=1;//DQ复位
DelayUs2x(5);//稍做延时
DQ=0;//单片机将DQ拉低
DelayUs2x(200);//精确延时大于480us小于960us
DelayUs2x(200);
DQ=1;//拉高总线
DelayUs2x(50);//15~60us后接收60-240us的存在脉冲
dat=DQ;//如果x=0则初始化成功,x=1则初始化失败
DelayUs2x(25);//稍作延时返回
returndat;
}
/*------------------------------------------------
读取一个字节
------------------------------------------------*/
unsignedcharReadOneChar(void)
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
DelayUs2x(25);
}
return(dat);
}
/*------------------------------------------------
写入一个字节
------------------------------------------------*/
voidWriteOneChar(unsignedchardat)
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
DelayUs2x(25);
DQ=1;
dat>>=1;
}
DelayUs2x(25);
}
/*------------------------------------------------
读取温度
------------------------------------------------*/
unsignedintReadTemperature(void)
{
unsignedchara=0;
unsignedintb=0;
unsignedintt=0;
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
DelayMs(10);
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
a=ReadOneChar();//低位
b=ReadOneChar();//高位
b<<=8;
t=a+b;
return(t);
}
/*------------------------------------------------
主函数
------------------------------------------------*/
voidmain(void)
{
inttemp,tempH=40,tempL=10;
floattemperature;
unsignedcharTempFlag=0;
chardisplaytemp[16],num1;//定义显示区域临时存储数组
unsignedchartemps[16];//定义显示区域临时存储数组
inti=0,s1num=0,s2num=0,s3num=0,s4num=0;
LCD_Init();//初始化液晶
DelayMs(20);//延时有助于稳定
LCD_Clear();//清屏
Init_Timer0();
Init_Timer1();//定时器0初始化
Ds1302_Init();//ds1302初始化
Ds1302_Read_Time();//首次读取时间
if((time_buf1[2]+time_buf1[7])==0)//如果所有参数都为0,写入一个初始值
Ds1302_Write_Time();
while
(1)//主循环
{
num1=KeyScan();
switch(num1)
{
case1:
s1num++;break;
case2:
s2num++;break;
case3:
s3num++;break;
case4:
s4num++;break;
default:
break;
}
if(s4num==0)
{
if(s1num==1)
{
if(s2num==1&tempH<127)
{
s2num=0;
tempH++;
}
if(s3num==1&tempH>-55)
{
s3num=0;
tempH--;
}
}
elseif(s1num==2)
{
if(s2num==1&tempL<127)
{
s2num=0;
tempL++;
}
if(s3num==1&tempL>-55)
{
s3num=0;
tempL--;
}
}
elseif(s1num==3)
{
s1num=1,s2num=0,s3num=0;
}
switch(TempFlag)
{
case0:
//输出温度上限下限
sprintf(displaytemp,"H.%3dL.%3d",tempH,tempL);
LCD_Wri