驱动
//onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include<reg52.h>
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
//定义引脚
sbit DQ = P1^4;
//函数声明
void Delay_OneWire(unsigned int t);
bit Init_DS18B20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
#endif
//onewire.c
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台
日 期: 2011-8-9
*/
#include<onewire.h>
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 0;
Delay_OneWire(200); //拉低总线480us以上
DQ = 1; //然后释放总线
Delay_OneWire(20); //等待15—60us
initflag = DQ; //读取DS18B20复位应答信号
Delay_OneWire(100); //等待60—240us后释放总线
return initflag; //应答信号为低电平,表示复位成功
}
//DS18B20写操作
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0; //将总线拉低10—15us
DQ = dat & 0x01; //想总线写数据
Delay_OneWire(20); //维持20—45us
DQ = 1; //释放总线
dat >>= 1; //右移一位,发送下一位数据
}
}
//DS18B20读时序
unsigned char Read_DS18B20(void)
{
unsigned char i,dat;
for(i=0;i<8;i++)
{
DQ = 0; //将总线拉低10—15us
dat >>= 1; //右移
DQ = 1; //释放总线
if(DQ) //读取总线上的电平,如果为高电平则读1
{
dat |= 0x80;
}
Delay_OneWire(20); //延时45us,再度下一位
}
return dat;
}
主程序
#include<reg52.h>
#include"onewire.h"
unsigned int T_dat; //存放温度,一定要定义为整型,否则会溢出
unsigned char code SEG_code[18] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0xbf,0x7f}; //定义共阳数码管段码内容:0~F,—,.
unsigned char code SEG_dot[10] =
{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//端口选择
void Select_HC138(unsigned char n)
{
switch(n)
{
case 0:
P2 = (P2 & 0x1f) | 0x00;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
//系统初始化
void Init_system()
{
Select_HC138(5);
P0 = 0x00; //关闭蜂鸣器和继电器
Select_HC138(0);
}
//数码管延时函数
void Delay_tube(unsigned char time)
{
while(time--);
}
//数码管显示
void Show_tube(unsigned char position,value)
{
Select_HC138(7);
P0 = 0xff; //注意:先熄灭
Select_HC138(6);
P0 = 0x01 << position;
Select_HC138(7);
P0 = value;
}
void Show_ALL(unsigned char value)
{
Select_HC138(7); //注意:先熄灭
P0 = value;
Select_HC138(6);
P0 = 0xff;
}
//数码管动态显示
void Display_tube(unsigned char dat)
{
Show_tube(5,SEG_code[dat/100]); //显示温度十位
Delay_tube(100);
Show_tube(6,SEG_dot[(dat/10)%10]); //显示温度个位
Delay_tube(100);
Show_tube(7,SEG_code[dat%10]); //显示温度小数位
Delay_tube(100);
Show_ALL(0xff); //熄灭
}
//温度转换延时函数
void Delay_temp(unsigned int t)
{
while(t--)
{
Display_tube(T_dat);
}
}
//读取温度(保留一位小数)
void Read_temperature()
{
unsigned char LSB,MSB; //存放温度
Init_DS18B20(); //复位
Write_DS18B20(0xcc); //跳过ROM操作指令
Write_DS18B20(0x44); //温度转换
Delay_temp(1000); //延时约700ms
Init_DS18B20(); //复位
Write_DS18B20(0xcc); //跳过ROM操作指令
Write_DS18B20(0xbe); //读取RAM
LSB = Read_DS18B20(); //读取温度数据的低8位(低位先读)
MSB = Read_DS18B20(); //读取温度数据的高8位
Init_DS18B20(); //复位,停止读取数据
T_dat = 0x0000;
T_dat = MSB;
T_dat <<= 8; //左移8位
T_dat |= LSB; //整合温度
if((T_dat & 0xf800) == 0x0000) //取温度的高5位,判读是否为正温度
{
T_dat >>= 4; //取温度的整数部分
T_dat *= 10; //放大10倍
T_dat += (LSB & 0x0f)*0.625; //取小数部分并放大10倍,与整数部分相加
}
}
//主函数
void main()
{
Init_system();
while(1)
{
Read_temperature();
Display_tube(T_dat);
}
}