⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 good2.c

📁 单片机单片机单单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机单片机片机单片机单片机单片机
💻 C
字号:
/*该驱动程序是基于------ATMEL89C52-----单片机实现*/
#include<reg52.h>
#include<stdio.h>
#include<intrins.h>

#define uchar unsigned char 
#define uint unsigned int 

sbit dula=P2^6; //段选端口
sbit wela=P2^7; //位选端口
sbit dq=P2^2;  //DS18B20数据端口
sbit feng=P2^3;  //蜂鸣器

uint c1_temper,c2_temper;  //记录两个温度传感器的温度
uint L_temper;  //温度下限值
uint H_temper;  //温度上限值

unsigned char aa[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //记录传感器A的序列号
unsigned char bb[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //记录传感器B的序列号

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f};

void delay_ms(uint z);
void delay_us();
void write_cmd(uchar z);
void get_firstid();
void get_seconedid();
void write_bit(uchar dd);
void deal_temper();
void deal_ds1();
void deal_ds2();
void display_temper(uint wengdu,uchar fc);
void init();
void warn_temper(uchar z);
uchar dq_reset();
uchar keyscanf();
uchar read_byte();
uint get_temper(uchar z);
uchar read_bit();
uchar read_date();

/******************延迟****************/

void delay_ms(uint z)//毫秒级的延迟
{	
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);	
}

void delay_us()//延时微秒
{
	_nop_();
}

/*****************复位*************************/

uchar dq_reset()
{
	uchar t;
	uchar dd;
	dq=0;
	for(t=250;t>0;t--);
	dq=1;
	for(t=5;t>0;t--);
	dd=dq;
	for(t=150;t>0;t--);
	return dd;
}

/******************(bit)位操作**********************/

uchar read_bit()//读一个位
{
	uchar t;
	uchar dd;

	dq=0;
	delay_us();delay_us();
	dq=1;
	for(t=3;t>0;t--);
	dd=dq;//get the signal
	for(t=20;t>0;t--);
	return dd;
}

void write_bit(uchar dd)//写一个位
{
	uchar t;

	if(dd==1)
	{
		dq=0;
		delay_us();
		dq=1;
		for(t=30;t>0;t--);	
	}	
	else
	{
		dq=0;
		for(t=30;t>0;t--);
		dq=1;
		delay_us();
		delay_us();
	}
}

/********************字节操作**************************/

uchar read_byte()//读字节
{ 
	uchar i;
	uchar temp; 
	uchar dd;

	temp=0x00; 
	for(i=0;i<8;i++) 
	{ 
		temp=_cror_(temp,1); 
		dd=read_bit();
		if(dd==1) 
		{ 
			temp=temp|0x80; 
		} 
		else 
		{ 
			temp=temp|0x00; 
		} 
	} 
	return(temp); 
} 

/******************命令与数据***********************/

void write_cmd(uchar z)//发送命令或数据
{
	uchar i,t;
	uchar temp;
	uchar cd=z;

	for(i=0;i<8;i++)
	{
		temp=cd&0x01;
		if(temp)
		{
			dq=0;
			delay_us();delay_us();//
			dq=1;
			for(t=40;t>0;t--);	
		}
		else
		{
			dq=0;
			for(t=40;t>0;t--);
			dq=1;
			delay_us();	delay_us();		
		}
		cd=_cror_(cd,1);
	}	
	
}

/*****************温度******************************/

uint get_temper(uchar z)//从暂存器中获取温度值
{

	uchar LSB_temper=0x00;
	uchar MSB_temper=0x00;
	uchar i;
	uint c_temp=0;
	float f_temp=0;
	
	dq_reset();
	
	write_cmd(0x55);
	if(z==1)//发送传感A的序列号
	{
		for(i=1;i<=8;i++)
		{
			write_cmd(aa[i]);
		}
	}
	else //发送传感器B的序列号
	{
		for(i=1;i<=8;i++)
		{
			write_cmd(bb[i]);
		}
	}
	delay_ms(1);
	write_cmd(0xbe);//读存储器内的温度

	LSB_temper=read_byte();//读低温度字节
	MSB_temper=read_byte();//读高温度字节
	dq_reset();	
	c_temp=MSB_temper;
	c_temp=(c_temp<<8);
	c_temp=c_temp|LSB_temper;
	f_temp=c_temp*0.0625;
	c_temp=f_temp*10+0.5;
	
	return (c_temp);
}

/******************获取序列号************************/
/*这里采用简单的“消除”算法*/

void get_firstid()//获取传感器A的序列号
{
	uchar t;
	uchar w=1;
	uchar d1,d2;
	uchar temp=0x00;
	
	dq_reset();
	write_cmd(0xf0);//搜索序列号命令

	for(t=1;t<=64;t++)
	{
		d1=read_bit();
		d2=read_bit();
		temp=_cror_(temp,1);
		
		if( (d1==1) && (d2==0) )
		{
			temp=temp|0x80;
			write_bit(1);
		}
		else if( (d1==0) && (d2==1))
		{
			temp=temp|0x00;
			write_bit(0);
		}
		else if( (d1==0) && (d2==0) )
		{
			temp=temp|0x00;
			write_bit(0);
		}
		if(t%8==0)
		{
			aa[w]=temp;
			w=w+1;
			temp=0x00;
		}	
	}
	
}

void get_seconedid() //获取传感器B的序列号
{
	uchar t;
	uchar w=1;
	uchar d1,d2;
	uchar temp=0x00;
	
	dq_reset();
	write_cmd(0xf0);//搜索序列号命令
	
	for(t=1;t<=64;t++)
	{
		d1=read_bit();
		d2=read_bit();
		temp=_cror_(temp,1);
		
		if( (d1==1) && (d2==0) )
		{
			write_bit(1);
			temp=temp|0x80;
		}
		else if( (d1==0) && (d2==1))
		{
			write_bit(0);
			temp=temp|0x00;
		}
		else if( (d1==0) && (d2==0) )
		{
			write_bit(1);
			temp=temp|0x80;
		}
		if(t%8==0)
		{
			bb[w]=temp;
			w=w+1;
			temp=0x00;
		}	
	}
}

/*******************温度处理**************************/

void deal_temper()
{
	uchar key=0;
	while(1)
	{
		key=keyscanf(); //键盘扫描
		if(key!=0)
		{
			 deal_ds1();//处理传感器A
			 deal_ds2();//处理传感器B
		}
		key=0;	
	}
}

void deal_ds1() //处理传感器A
{
	uchar t;
	uchar key;

	while(1)
	{
		dq_reset(); //复位
		write_cmd(0xcc); //跳过ROM命令
		write_cmd(0x44);//温度转换命令
		
		key=keyscanf();//检测按键
		if(key==2) break;
		
		c1_temper=get_temper(1);
		if(c1_temper>H_temper) warn_temper(1); //传感器A温度超出上限则进入 warn_temper(1)警告函数
		
		for(t=20;t>0;t--)
		{
			display_temper(get_temper(1),1); //显示传感器A的温度
		}
	}
}

void deal_ds2() //处理传感器B
{
	uchar t;
	uchar key;

	while(1)
	{
		dq_reset();
		write_cmd(0xcc); //跳过ROM命令
		write_cmd(0x44);//温度转换
		
		key=keyscanf();//按键检测
		if(key==1) break;
		
		if(c2_temper>H_temper) warn_temper(2);
		for(t=20;t>0;t--)
		{
			display_temper(get_temper(2),2); //显示传感器B的温度
		}
	}
}

void warn_temper(uchar z) //温度警告函数
{
	uchar t;
	uint c_temper;
	while(1)
	{
		feng=0; //蜂鸣器响
		dq_reset();
		write_cmd(0xcc); //跳过ROM命令
		write_cmd(0x44);//温度转换
		
		c_temper=get_temper(z);
		for(t=5;t>0;t--)
		{
			display_temper(get_temper(z),z);
		}
		if(c_temper<H_temper)
		{
			feng=1; //关闭蜂鸣器
			break;
		}
	}
}
/*********************键盘************************/

uchar keyscanf() //键盘扫描函数
{	
	uchar temp;
	uchar ke=0;

	P3=0xf7; //P3为4*4矩阵键盘与89C52单片机的接口
	temp=P3;
	temp=temp&0xf0;
	while(temp!=0xf0) //判断有无按键情况
	{
		switch(temp)
		{
			case 0xe0: ke=1;break;
			case 0xd0: ke=2;break;
			case 0xb0: ke=3;break;	
			case 0x70: ke=4;break;
		}
		temp=P3;
		temp=temp&0xf0;
		delay_ms(2);
	}
	return ke;
}

/******************温度显示***********************/

void display_temper(uint wengdu,uchar fc)//显示当前温度值
{
	uchar xx,yy,zz;
	uint temp;
	
	temp=wengdu;
	xx=temp/100;
	yy=temp%100/10;
	zz=temp%10;
	
	wela=1;
	P0=0xfe;
	wela=0;

	P0=0x00;
	dula=1;
	P0=table[xx];
	dula=0;
	delay_ms(1);
	
	P0=0xff;
	wela=1;
	P0=0xfd;
	wela=0;

	P0=0x00;
	dula=1;
	P0=(table[yy]+0x80);
	dula=0;
	delay_ms(1);
	
	P0=0xff;
	wela=1;
	P0=0xfb;
	wela=0;

	P0=0x00;
	dula=1;
	P0=table[zz];
	dula=0;
	delay_ms(1);

	P0=0xff;
	wela=1;
	P0=0xdf;
	wela=0;

	P0=0x00;
	dula=1;
	P0=table[fc];
	dula=0;
	delay_ms(1);
}

/****************初始化与主函数******************/

void init()//初始化
{
	L_temper=100;
	H_temper=320; //设定上限温度
	
	c1_temper=200; //随意定义的初值
	c2_temper=200;
	dula=0;
	wela=0;
}

void main()
{
	init();
	while(1)
	{
		uchar t,k;
		get_firstid(); //获取传感器A的序列号
		get_seconedid();  //-------B---------
		for(t=1;t<=8;t++)  //通过流水灯,蜂鸣器,数码管观察是否获取了序列号。DS18B20家族码28H是固定的
		{
			P1=aa[t];
			for(k=0;k<10;k++) { delay_ms(100);}
			feng=0;
			wela=1; P0=0xfe; wela=0;
			delay_ms(2);
			dula=1;	P0=table[1]; dula=0;
			delay_ms(100);
			feng=1;
		}
		
		for(t=1;t<=8;t++)
		{
			P1=bb[t];
			for(k=0;k<10;k++) delay_ms(100);
			feng=0;
			wela=1; P0=0xfe; wela=0;
			delay_ms(2);
			dula=1;	P0=table[2]; dula=0;
			delay_ms(100);
			feng=1;
		}
		wela=1;P0=0xff;wela=0;
		P1=0xff;
		deal_temper(); //温度处理
		}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -