#include <pic.h>
__CONFIG(0x3B31);
#define uchar unsigned char
#define uint unsigned int
#define rs RD5 //命令/数据选择
#define rw RD4 //读写口
#define e RD3 //锁存控制
#define Dataport PORTB //数据口定义
unsigned char temp1;
unsigned char temp2;
//转换后的温度值小数点部分查表
const unsigned char table[16]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};
uchar dis0[16]={'T','h','e',' ','t','e','m','p',' ','n','o','w',' ','i','s',':',};//LCD第1行
uchar dis[10]={' ',' ',' ',' ',0x00,0x00,'.',0x00,0xeb,'C'}; //LCD第2行
//***********************************************************************************
//延时
//***********************************************************************************
void delay1(uint time)
{
uint i,j;
for(i = 0;i < time; i++)
{
for(j = 0;j < 30; j++);
}
}
//**************************************************************************************************
//向LCD写一命令
//**************************************************************************************************
wcode(uchar t)
{
rs=0; // 写的是命令
rw=0; // 写状态
e=1; //使能
Dataport=t; //写入命令
delay1(20); //等待写入,如果时间太短,会导致液晶无法显示
e=0; //数据的锁定
}
//**************************************************************************************************
//向LCD写一数据
//**************************************************************************************************
wdata(uchar t)
{
rs=1; // 写的是数据
rw=0; // 写状态
e=1; //使能
Dataport=t; //写入数据
delay1(20); //等待写入,如果时间太短,会导致液晶无法显示
e=0; //数据的锁定
}
//**************************************************************************************************
//LCD显示
//**************************************************************************************************
show()
{
uchar i;
wcode(0x80); //设置第一行显示地址
for(i=0;i<16;i++) //循环16次,写完1行
{
wdata(dis0[i]); //写入该行数据
}
wcode(0xc6); //设置第一行显示地址
for(i=0;i<10;i++) //循环16次,写完1行
{
wdata(dis[i]); //写入该行数据
}
}
//**************************************************************************************************
//LCD 初始化
//**************************************************************************************************
InitLCD()
{
wcode(0x01); //清屏
wcode(0x06); //输入方式控制,增量光标不移位
wcode(0x0e); //显示开关控制
wcode(0x38); //功能设定:设置16x2显示,5x7显示,8位数据接口
}
//---------------------------------------
//名称:复位DS18B20函数
//---------------------------------------
unsigned char Reset(void)
{
unsigned int i;
unsigned char k;
TRISD7=1;//先设置为输入
NOP();NOP();
TRISD7=0; //设置输出口
NOP();NOP();
RD7=0; //拉低DQ总线开始复位
i=67;while(i>0)i--; //保持DQ低大约870uS,符合不低于480US的要求
TRISD7=1; //设置为输入口,以释放总线等电阻拉高总线
i=6;while(i>0)i--; //大约78uS后,判断是否复位成功
if(RD7==0) //读出数据并保存
k=0;
else
k=1;
i=31;while(i>0)i--; //维持约400US,符合总读时隙不低于480US的要求
return k; //k=0为复位成功,k=1为复位失败
}
//---------------------------------------
//名称:写字节函数
//---------------------------------------
void WriteByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
for(j=0;j<8;j++)
{
if(dat&0x01) //如果写1
{
TRISD7=0; //设置RA4位输出口
//NOP();
RD7=0; //拉低
NOP();NOP();NOP();NOP();NOP();NOP();//维持6US,符合大于1US小于15US的规范
TRISD7=1; //设置RA4为输入口,以释放总线等电阻拉高总线
i=14;while(i>0)i--; //维持约63US,符合不低于60US的要求
}
else //如果写0
{
TRISD7=0; //设置R位输出口
//NOP();
RD7=0; //拉低
i=14;while(i>0)i--; //维持约63US,符合不低于60US的要求
TRISD7=1; //设置为输入口,以释放总线等电阻拉高总线
NOP();//NOP(); //维持2US,符合大于1US的规范
}
dat=dat>>1; //写入字节右移1位
}
}
//---------------------------------------
//名称:读字节函数
//---------------------------------------
unsigned char ReadByte(void)
{
unsigned int i;
unsigned char j,buf=0;
for(j=1;j<=8;j++) //接收8次还原一个字节数据
{
buf=buf>>1; //接收前,先将接收缓冲区右移
TRISD7=0; //设置位输出口
RD7=0; //拉低
NOP();NOP();NOP();NOP();NOP();NOP();//维持2US,符合大于1US小于15US的规范
TRISD7=1; //设置为输入口,以释放总线等电阻拉高总线 准备读
NOP();NOP(); //维持6US,符合大于1US小于15US的规范
if(RD7==1) buf|=0x80; //读出1位数据保存于buf中最高位
i=3;while(i>0)i--; //维持约52US,符合总读时隙不低于60US的要求
}
return buf; //退出的同时将接收缓冲区参数返回
}
//---------------------------------------
//名称:启动读温度函数
//---------------------------------------
unsigned char Convert(void)
{
unsigned int i;
if(Reset()==0) //如果复位成功
{
i=77; //延时约1000US
while(i>0) //延时约1000US
i--; //延时约1000US
WriteByte(0xCC); // 跳过多器件识别
WriteByte(0x44); // 启动温度转换
return 1;
}
else
{
return 0;
}
}
//---------------------------------------
//名称:读温度函数
//---------------------------------------
void ReadFlash(void)
{
unsigned int i;
unsigned char Lsb,Msb;
if(Reset()==0)
{
i=77;while(i>0)i--; //延时约1000US
WriteByte(0xCC); // 跳过多器件识别
WriteByte(0xBE); // 读暂存器
Lsb=ReadByte(); // 低字节
Msb=ReadByte(); // 高字节
temp2=Lsb&0x0f; //LSB的低4位为小数部分
temp1=(Lsb>>4)|(Msb<<4);//LSB的高4位和MSB拼成整数部分
}
else
{
temp1=0;
temp2=0;
}
}
//**************************************************************************************************
//主函数
//**************************************************************************************************
main()
{
TRISB=0x00; //RB设置为输出
PORTB=0xff; //初始化为高
TRISA=0xff;
PORTA=0x00;
TRISD=0x80;
PORTD=0x80;
InitLCD(); //液晶初始化
while(1)
{
if(Convert()==1) //启动转换
{
ReadFlash(); //读取温度
if(temp1>99) temp1=99;
if(temp2>15) temp2=0;
dis[4]=temp1/10+0x30;
dis[5]=temp1%10+0x30;
dis[7]=table[temp2&0x0f]+0x30;
}
show(); //显示温度值
delay1(500); //延时
}
} |
|