DS18B20设计1个温度监测系统

DS18B20设计1个温度监测系统

项目要求
采集环境温度(0~99.9℃)显示在前3位数码管上。

原理图
引用图片
引用图片

代码编写

#include <reg52.h>
#include <intrins.h>	//包含函数库,用于调用_nop_()函数
#define uchar unsigned char 
#define uint unsigned int
bit flag;				//定义标志位,返回值作为是否存在的标志
sbit ds=P2^2;
sbit dula=P2^6;
sbit wela=P2^7;
uint temp;		//16位变量
uchar code table_du[]=
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
void delayus(uint t)	//us级延时函数
{
	while(t--);
}

void delay_ms(uchar z)	//ms级延时
{
	uchar i,j;
	for(i=z;i>0;i--)
		for(j=110;j>0;j--);
}
void ds_reset()	//复位初始化程序
{
	ds=1;		//先将数据线置高电平1
	delayus(5);	//如果11.0592M,大约为66us
	ds=0;		//数据线拉低到低电平0
	delayus(80);	//延时约700us
	ds=1;			//数据线拉到高电平1
	delayus(14);	//延时约154us
	if(ds==0)
		flag=1;		//标志位,表示18B20存在
	else
		flag=0;
	delayus(20);	//约200us
}

bit ds_read_bit()	//读取1位时序,用于下面读字节
{
	bit dat;		//定义一个位变量,作为返回值
	ds=0;			//拉低总线到0
	_nop_();		//一个机器周期,大约1us
	_nop_();		//延时约1us,加上上面的总计约2us
	ds=1;			//主机采样
	_nop_();		//延时用于稳定数据
	dat=ds;			//ds的电平的高低即为数据
	delayus(10);	//约100us
	return dat;		//这里之所以有返回值是因为单片机从DS18B20读出数据时,DS18B20要返回数据给到单片机。
}					//写操作里是因为单片机直接写数据到DS18B20,不需要DS18B20返回值。

uchar ds_read_byte()	//读1个字节,即单片机从DS18B20读数据,需要DS18B20返回数据
{
	uchar i,j,k;
	for(i=0;i<8;i++)	//1个字节由8位组成,将读的位数据一位一位的移入,
	{					//移入8位就组成1字节
		j=ds_read_bit();	//例如:j=1010 0101
		k=(j<<7)|(k>>1);	//Ex: j=1010 0101|k=0000 0000=1010 0101		
	}						
	return k;				//循环8次返回的值为j=1010 0101
}

void ds_write_byte(uchar dat)	//写1个字节,dat即为单片机向DS18B20中写的数据
{
	uchar i;
	for(i=0;i<8;i++)
	{
		ds=0;			//数据线先置低电平
		_nop_();		//约1us
		_nop_();
		ds=dat&0x01;	//每次只能写1位,即dat的最低位,数据读写均按照从低位到高位
		delayus(6);		//延时约70us	
		ds=1;			//将数据线拉到高电平1,准备下次的写入
		dat=dat>>1;		//右移1位
	}
	delayus(6);			//约70us
}

uint read_temperature()	//单片机读取DS18B20温度值
{
	uchar a,b;
	ds_reset();		//初始化
	ds_write_byte(0xcc);	//ROM操作指令,跳过ROM
	ds_write_byte(0xbe);	//存储器操作指令,读取温度指令
	a=ds_read_byte();		//执行/数据,低8位,a为8位变量。例a=0101 1010
	b=ds_read_byte();		//高8位, b为8位变量。例b=1010 0101
	temp=b;					//16位变量存放温度值(高8位+低8位)将b的值赋给temp。由于temp为16位变量,所以高位补0。temp=0000 0000 1010 0101
	temp=temp<<8;			//temp<<8为1010 0101 0000 0000
	temp=temp|a;			//temp|a为1010 0101 0101 1010
	temp=temp*0.0625*10+0.5;//按照固定公式进行转换运算,加0.5是用于四舍五入
	return temp;			//返回温度值
}

void display(uint temp)		//数码管显示程序
{							//将温度值得每位分开进行单独显示
	P0=table_du[temp/100];	//显示十位
	dula=1;
	dula=0;
	P0=0xfe;				//点亮第一个数码管
	wela=1;
	wela=0;
	delay_ms(10);

	P0=table_du[temp%100/10]|0x80;//添加小数点,使dp=1.即dp g f e d c b a =1000 0000
	dula=1;
	dula=0;
	P0=0xfd;
	wela=1;
	wela=0;
	delay_ms(10);

	P0=table_du[temp%100%10];	
	dula=1;
	dula=0;
	P0=0xfb;
	wela=1;
	wela=0;
	delay_ms(10);		
}

void main()
{
	while(1)
	{
		ds_reset();	//初始化
		ds_write_byte(0xcc);	//跳过ROM
		ds_write_byte(0x44);		//启动温度转换
		display(read_temperature());
	}
}

**DS18B20初始化时序图**
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
此为12864显示的ds18B20 ************液晶显示子程序**********************************// #define DATA_OUT PORTA #define DATA_IN PINA //端口定义使用============= #define DATA_DIR DDRA //使用寄存器================ #define CNTL PORTB #define CNTL_DIR DDRB #define OUT 0xff #define IN 0x00 #define RS 0 #define RW 1 #define E 2 /******************************************************************** */ #define SETBIT(x,y) (x|=(1<<y)) //set bit y in byte x #define CLRBIT(x,y) (x&=(~(1<<y))) //clear bit y in byte x #define CHKBIT(x,y) (x&(1<<y)) //check bit y in byte x /******************************************************************** */ uchar character1[]="关于显示器的问题"; uchar character2[]="数字信号是要测量"; uchar character3[]="液晶显示效果是好"; uchar character4[]="显示效果还是加强"; uchar adress_table[][8]={ {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87},//第一行汉字位置 {0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97},//第二行汉字位置 {0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F},//第三行汉字位置 {0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F},//第四行汉字位置 }; /************************************************************ * 函数名称:void DelayMS(unsigned int time) * 功 能:软件延时 1/1000s * 入口参数:time 延时时间 MS * 出口参数:无 ************************************************************ void DelayMS(uint time) { uint i; while(time--) { for(i=1;i<(uint)(xtal*143-2);i++) ; } } */ /*----------------------------------------------------- 状态检查函数,判断是否处于忙状态 -------------------------------------------------------*/ void CheckState() { //unsigned char dat; //CLRBIT(CNTL,RS); //RS=0 CLRBIT(CNTL,RS); //RS=0 SETBIT(CNTL,RW); //RW=1 DATA_DIR=IN; // portd as input do { SETBIT(CNTL,E); CLRBIT(CNTL,E); } while (DATA_IN&0x80); } /*---------------------------------------------- 写显示数据 形参dat:显示数据 -------------------------------------------------*/ void write_data(unsigned char dat) { CheckState(); SETBIT(CNTL,RS); CLRBIT(CNTL,RW); DATA_DIR=OUT; //portd as output DATA_OUT=dat; SETBIT(CNTL,E); CLRBIT(CNTL,E); } /*------------------------------------------------- 向LCD发送命令 形参command :命令 --------------------------------------------------*/ void write_command(unsigned char command) { CheckState(); CNTL_DIR=OUT; //PORTB&=0xfc; CLRBIT(CNTL,RS); //RS=0,RW=0 CLRBIT(CNTL,RW); DATA_DIR=OUT; //portd as output DATA_OUT=command; SETBIT(CNTL,E); CLRBIT(CNTL,E); } void LCD_Init(void) { Init_IO(); write_command(0x30);//功能设置 8位数据,基本指令 write_command(0x0C); //显示状态 ON,游标OFF,反白OFF write_command(0x01); //清除显示 write_command(0x02); //地址归位 write_command(0x80); //设置DDRAM地址 } void display_CGROM(uchar row,uchar column,uchar *p) { //while(row<4&&((*p)!='\0')) //{ while(column<8&&((*p)!='\0')) { write_command(adress_table[row][column]); write_data(*p++); write_data(*p++); column++; } //column=0; //row++; // } } //============液晶子程序=========================// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// void main(void) { Init_IO(); //初始化I/O口 TCCR0=0x03; //T/C0工作于定时方式,系统时钟64分频 TCNT0=0x83; //计数初始值83 _SEI(); TIMSK=0x01; LCD_Init(); while(1) { Display_ds18B20(); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值