|
- //熟悉使用单片机运用DS18B20温度传感器测试温度,并用1602显示屏显示温度
- //1、第一行显示:Temperature
- //2、第二行显示:实测温度值
- //**************************************************
- //**************************************************
- //硬件设置:
- //1、SW2,SW4开关全部断开
- //2、插上DS18B20温度传感器
- //**************************************************
- //**************************************************
- //*****************定义头文件**********************
- //**************************************************
- #include<PIC.h>
- #include "delay.h"
- //**************************************************
- //******************定义配置位*********************
- //**************************************************
- __CONFIG(0x3545);
- //FLASH代码不保护,RB6和RB7为调试模式,FLASH不写保护,数据代码不保护
- //RB3为数字IO口,低电压复位使能,上电延时开,看门狗开,4M晶体XT振荡器
- //**************************************************
- //******************定义常量***********************
- //**************************************************
- #define uchar unsigned char
- #define uint unsigned int
- //**************************************************
- //***************定义DS18B20引脚*******************
- //**************************************************
- #define DQ RE0
- #define DQ_IO TRISE0
- //**************************************************
- //******************定义LCD引脚*********************
- //**************************************************
- #define RS RA1
- #define RW RA2
- #define E RA3
-
- //**************************************************
- //******************定义变量***********************
- //**************************************************
- uchar lowtemp,hightemp; //低8位温度变量,高8位温度变量
- uchar zhengshu,xiaoshu; //温度整数变量,温度小数变量
- uint temperature; //转换后的温度值BCD码形式
- uchar temp[7]; //转换后温度存放变量
- //**************************************************
- //******************定义数据***********************
- //**************************************************
- //显示: Temperature
- //显示:WWW.PICAVR.COM
- const uchar name[16]=
- //{0x20,0x20,0x20,0x54,0x65,0x6d,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x20};
- {0x20,0x57,0x57,0x57,0x2E,0x50,0x49,0x43,0x41,0x56,0x52,0x2E,0x43,0x4F,0x4D,0x20};
-
- //***********************************************
- //函 数 名:delayms(uchar time);
- //入口参数:time
- //出口参数:无
- //函数作用:毫秒延时
- //说 明:
- //***********************************************
- void delayms(uchar time)
- {
- uint i;
- while(time--)
- {
- for(i=93;i>0;i--){;}
- }
- }
- //***********************************************
- //函 数 名:port_init();
- //入口参数:无
- //出口参数:无
- //函数作用:端口初始化
- //说 明:
- //***********************************************
- void port_init(void)
- {
- ADCON1=0X07; //设置RA,RE口为数字口
- TRISA=0X00; //设置RA口为输出口
- TRISD=0X00; //设置RD口为输出口
- TRISE=0X00; //设置RE口为输出口
- OPTION=0X8F; //分频给WDT,分频比为128
- }
- //***********************************************
- //函 数 名:lcd_enable();
- //入口参数:无
- //出口参数:无
- //函数作用:LCD写使能
- //说 明:
- //***********************************************
- void lcd_enable(void)
- {
- RS=0; //写命令
- RW=0; //写操作
- E=0; //低电平信号
- delayms(10); //低电平信号保持
- E=1; //拉高电平信号
- }
- //***********************************************
- //函 数 名:lcd_writebyte(uchar data);
- //入口参数:data
- //出口参数:无
- //函数作用:LCD写一个字节数据
- //说 明:
- //***********************************************
- void lcd_writebyte(uchar data)
- {
- PORTD=data; //向RD口写数据
- RS=1; //写数据
- RW=0; //写操作
- E=0; //低电平信号
- delayms(10); //低电平信号保持
- E=1; //拉高电平信号
- }
- //***********************************************
- //函 数 名:lcd_writedata(const uchar *ptt);
- //入口参数:*ptt
- //出口参数:无
- //函数作用:LCD写数据块函数
- //说 明:
- //***********************************************
- void lcd_writedata(const uchar *ptt)
- {
- uchar i;
- for(i=0;i<16;i++) //写16个字节数据
- {
- lcd_writebyte(ptt[i]); //查表写数据
- }
- }
- //***********************************************
- //函 数 名:lcd_init();
- //入口参数:无
- //出口参数:无
- //函数作用:LCD初始化
- //说 明:
- //***********************************************
- void lcd_init(void)
- {
- PORTD=0X01; //清除显示
- lcd_enable();
- PORTD=0X38; //8位2行5*7点阵
- lcd_enable();
- PORTD=0X0e; //显示开,光标开,闪烁
- lcd_enable();
- PORTD=0X06; //文字不动,光标右移
- lcd_enable();
- }
- //***********************************************
- //函 数 名:ds18b20_reset();
- //入口参数:无
- //出口参数:无
- //函数作用:DS18B20复位
- //说 明:
- //***********************************************
- void ds18b20_reset(void)
- {
- uchar x=1;
- while(x)
- {
- DQ_IO=0; //设置RE0为输出口
- DQ=0; //RE0输出低电平
- DelayUs(201); //延时503us(最短480us低电平信号)
- DQ_IO=1; //释放总线,进入接收(设置RE0为输入口)
- DelayUs(29); //延时70us(18b20检测到上升沿时,等待15-60us)
- if(DQ){x=1;} //有应答信号,跳出
- else {x=0;} //没有应答信号,继续复位(低电平持续在60-240us)
- DelayUs(172); //延时430us
- }
- }
- //***********************************************
- //函 数 名:ds18b20_writebyte(uchar data);
- //入口参数:data
- //出口参数:无
- //函数作用:DS18B20写一个字节数据
- //说 明:
- //***********************************************
- void ds18b20_writebyte(uchar data)
- {
- uchar i,temp;
- for(i=8;i>0;i--) //写8位数据
- {
- temp=data&0x01; //先写低位数据
- DQ_IO=0; //设置RE0为输出口
- DQ=0; //RE0输出低电平
- DelayUs(1); //延时6us(15us之内把数据送到总线上)
- if(temp){DQ_IO=1;} //设置RE0为输入口(写1时序)
- DelayUs(25); //延时61us(总线采样时间15-60us)
- DQ_IO=1; //设置RE0为输入口(写0时序)
- DelayUs(1); //延时6us(写第二位时间间隙大于1us)
- data=data>>1; //右移一位
- }
- }
- //***********************************************
- //函 数 名:ds18b20_readbyte();
- //入口参数:无
- //出口参数:无
- //函数作用:DS18B20读一个字节数据
- //说 明:
- //***********************************************
- unsigned char ds18b20_readbyte(void)
- {
- uchar i,data=0; //读出温度
- for(i=8;i>0;i--) //读8位数据
- {
- data=data>>1; //数据先右移一位
- DQ_IO=0; //设置RE0为输出口
- DQ=0; //RE0输出低电平
- DelayUs(1); //延时6us(低电平时间大于1us)
- DQ_IO=1; //拉高总线,产生读时间间隙(设置RE0为输入口)
- DelayUs(1); //延时6us(从拉低电平开始15us之内完成读位)
- if(DQ){data=data|0x80;} //先读高位数据,高位为1
- else {data=data|0x00;} //高位为0
- DelayUs(25); //延时61us(从拉低电平开始60-120us之内释放总线)
- }
- return(data);
- }
- //***********************************************
- //函 数 名:read_ds18b20_data();
- //入口参数:无
- //出口参数:无
- //函数作用:读DS18B20测试的温度数据
- //说 明:
- //***********************************************
- void read_ds18b20_data(void)
- {
- DQ_IO=1; //设置RE0为输入口
- ds18b20_reset(); //调用复位函数
- ds18b20_writebyte(0XCC); //跳过ROM匹配
- ds18b20_writebyte(0X44); //发送温度变换命令
- ds18b20_reset(); //再次复位
- ds18b20_writebyte(0XCC); //跳过ROM匹配
- ds18b20_writebyte(0XBE); //发送读温度命令
- lowtemp=ds18b20_readbyte(); //读出低8位温度值
- hightemp=ds18b20_readbyte(); //读出高8位温度值
- DQ_IO=1; //释放总线
- zhengshu=((lowtemp>>4)|(hightemp<<4))&0X3F;
- xiaoshu=lowtemp<<4;
- temp[0]=(zhengshu/100)%10; //整数百位
- temp[1]=(zhengshu/10)%10; //整数十位
- temp[2]=zhengshu%10; //整数个位
- temperature=0;
- if(xiaoshu&0x80) //下面是把小数部分转换为BCD码形式
- {
- temperature+=5000;
- }
- if(xiaoshu&0x40)
- {
- temperature+=2500;
- }
- if(xiaoshu&0x20)
- {
- temperature+=1250;
- }
- if(xiaoshu&0x10)
- {
- temperature+=625;
- }
- temp[3]=(temperature/1000)%10; //十分位
- temp[4]=(temperature/100)%10; //百分位
- temp[5]=(temperature/10)%10; //千分位
- temp[6]=temperature%10; //万分位
- DelayUs(1); //延时6us
- }
- //***********************************************
- //函 数 名:lcd_display_temp();
- //入口参数:无
- //出口参数:无
- //函数作用:LCD显示测试温度程序
- //说 明:
- //***********************************************
- void lcd_display_temp(void)
- {
- PORTD=0X80; //设置第1行显示地址
- lcd_enable();
- lcd_writedata(name); //调用显示函数
- PORTD=0XC0; //设置第2行显示地址
- lcd_enable(); //调用写使能函数
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- if(temp[0]==0)
- {
- lcd_writebyte(0x20);
- }
- else
- {
- lcd_writebyte(temp[0]+0x30);
- }
- lcd_writebyte(temp[1]+0x30);
- lcd_writebyte(temp[2]+0x30);
- lcd_writebyte(0x2e);
- lcd_writebyte(temp[3]+0x30);
- lcd_writebyte(temp[4]+0x30);
- lcd_writebyte(temp[5]+0x30);
- lcd_writebyte(temp[6]+0x30);
- lcd_writebyte(0x20);
- lcd_writebyte(0x43);
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- }
- //***********************************************
- //函 数 名:main();
- //入口参数:无
- //出口参数:无
- //函数作用:MAIN函数
- //说 明:
- //***********************************************
- void main(void)
- {
- port_init(); //调用端口初始化函数
- lcd_init(); //调用LCD初始化函数
- while(1)
- {
- read_ds18b20_data(); //调用温度转换函数
- CLRWDT(); //清看门狗
- lcd_display_temp(); //调用温度显示函数
- }
- }
复制代码
|
|