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

📄 experiment_5.c

📁 学习掌握使用多片单总线数字式温度传感器 DS18B20温度采集方法。
💻 C
字号:
/******************************************************************************
实验五  多片ds18b20 温度采集    2005.1.13



*******************************************************************************/

#include <string.h>
#include "..\inc\option.h"
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\timer.h"

/***************************************************************************
	Timer5 初始化
	入口参数:Timing_count=定时时间常数,定时时间=定时时间常数*0.02ms
			  T5_int_Enable=1,T5 中断方式,T5_int_Enable=0,T5 查询方式
****************************************************************************/
    
Timer_Init(U16 timing_count,U8 T5_int_Enable)
	{
		rINTMSK=BIT_GLOBAL|BIT_TIMER5;  
		rTCFG0=0X0c70101;//prescaler=199  rTCFG0=0X010101;prescaler=1
		rTCFG1=0X0100000; // DIV=4        

		rTCNTB5=timing_count;
		//rTCMPB5=(timing_count/2); havn't rTCMPB5!!! but T0--T4 have.
		
		rTCON=0X2000000;
		rTCON=0X1000000;

		if(T5_int_Enable)
		{
	 		rINTCON=0X05;
			rINTMOD=0X0;
			rINTMSK=~(BIT_GLOBAL|BIT_TIMER5);
		}
	}

/**********************************************************************************
	匹配ROM(命令 55H),发8字节ROM代码
  	入口参数:*ROM_addr 为DS18B20-ID首地址     
**********************************************************************************/
Match_Rom(U8 *ROM_addr)
	{
		U8 count;
		U8 *p;
		U8 temp=0x55;		//匹配ROM 命令 55H
		Write_Byte(temp);
		p=ROM_addr;			//发8字节ROM代码
		count=8;
		while(count)
		{
			Write_Byte(*p);
			p++;
			count--;
		}
	}


/***********************************************************************************
读ROM(命令 33H),读回8字节ROM代码
  入口参数:Read_Addr=ROM代码首地址   
  出口参数:Read_Addr 地址开始的8个单元= 读回8字节ROM代码 
***********************************************************************************/
Read_Rom(U8 *Read_Addr)
	{
		U8 count;
		U8 *p;
		U8 temp=0x33;		//读ROM 命令 33H
		Write_Byte(temp);
		p=Read_Addr;		//从18b20 读回8字节ROM代码
		count=8;
		while(count)
		{
			*p=Read_Byte();
			p++;
			count--;
		}
	}

/**********************************************************************************

发启动温度转换 命令(44h)   

***********************************************************************************/
void Convert_Start(void)
	{
		Write_Byte(0x44);
//		Write_Byte(0X01);   //主机 发'1',释放总线,非窃电方式时可不用
	}

/**********************************************************************************

发Skip ROM 命令(CCh)

***********************************************************************************/
void Skip_Rom(void) 
	{
		Write_Byte(0xCC);
	}
/**********************************************************************************

发 Read_Ram 命令,读回2字节12位转换结果

**********************************************************************************/

U16 Read_Ram()      
	{
		U8 Temperature_L;
		U8 Temperature_H;
		U16 Temperature; 			//12位转换结果Temperature
		float Celsius;              //分辨度为 0.0625 度
		Write_Byte(0xBE); 			//发Read_Ram 命令,
		Temperature_L= Read_Byte(); //读回2字节12位转换结果
		Temperature_H= Read_Byte();
		Temperature=Temperature_H;
		Temperature=(Temperature_H<<8)+Temperature_L;
		Celsius=Temperature*0.0625;
		return Temperature;
	}




/***********************************************************************************

复位ds18b20
 入口参数:无   
 返回参数:=1:总线上有18B20应答; =0:总线上无应答;

***********************************************************************************/

U8 Reset_18B20(void)
	{
		U8 temp;
		rPCONG |= 0X0100;  //PCONG[15:0]16位, G口配置寄存器.
		rPCONG &= 0x0fdff; //PCONG[9:8]=01, 定义PG4 output。
		rPUPG &=0xef;      //PUPG[7:0]8位, PUPG[4]=0,pull up enabled
		
		rPDATG |=0x0100;   //置"1"总线,3.8us.
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		rPDATG &=0x0ef;    //主机发复位脉冲"0",500 us.
		
		temp=150;          //500us
		while(temp)
		{
		asm("nop");
		temp--;
		}
				 
		rPDATG |=0x10;  //主机发"1",17 us.(ds18b20等候15--60us,实测25us)
		temp=4;        	 
		while(temp)
		{
		asm("nop");
		temp--;
		}

		rPCONG &=0xfcff;  //PG4[9:8]=00,input
		Timer_Init(12,0); //12*0.02ms=240 us
		while(1)
		{
			temp=rPDATG;
			temp &=0x10;
			if(temp==0x0)       //有应答? 
			{
				rTCON=0x0;  	//停止T5计时
				while(temp==0x0)
				{
					temp=rPDATG;//等应答结束
					temp &=0x10;
				}
	
				temp=80;         //250us
				while(temp)
				{
					asm("nop");
					temp--;
				}
				return 1;		 //有应答,返回1.
			}
			else
			{
				if(~(rTCNTO5))
					return 0;    //无应答,返回0.
			}
		}
	}

/***********************************************************************************

主机读 1 Byte
入口参数: 无
返回参数: 读入的 1 Byte数据, 低位在先!!  

***********************************************************************************/

U8 Read_Byte()
   {
		U8 count;
		U8 temp_Byte=0;
		U8 temp;
		count=8;				 //读入1 Byte数据(=8bit) 
		temp_Byte;
		while(count)
		{
			temp=Read_Bit();	 //读入 1 Bit 
			temp_Byte=(temp_Byte>>1)|(temp&0x80);
        	count--;
		}
		return temp_Byte;
	}

/**********************************************************************************

主机读 1 Bit
入口参数: 无
返回参数: 读入的 1 Bit数据(U8 temp的 Bit[0] )  

***********************************************************************************/
U8 Read_Bit()
   {
		U8 temp;
		U8 read_bit;
		rPDATG &=0x0ef;         //主机发"0",2.2us
		asm("nop");
		asm("nop");
		rPDATG |=0x010;         //主机发"1",3.8us.
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		rPCONG &=0xfcff; 		//PG4[9:8]=00,input.
		asm("nop");
		while(1)
		{
			read_bit=(rPDATG<<3)&0x80;	   //读总线 PG4
			asm("nop");
			if(read_bit==(rPDATG>>4)&0X01);//再读总线 PG4
				break;                     //两次读相等?
		}				
		
		temp=8;                            //30us
		while(temp)
			{
				asm("nop");
				temp--;
			}
		
		rPCONG |=0x0100;  	//PG4[9:8]=01,output
		asm("nop");
			
		rPDATG |=0x10; 		//发"1",2us.
		asm("nop");
		asm("nop");
		return read_bit;
	}
/**********************************************************************************

主机写 1 Byte
入口参数:欲写的 1 Byte数据 
返回参数:无  

***********************************************************************************/		
void Write_Byte(U8 write_Byte)
	{
		U8 count;
		U8 temp_bit;
		count=0x08;
		while(count)
		{
			temp_bit=write_Byte&0x01;
			Write_Bit(temp_bit);
			write_Byte=write_Byte>>1;
			count--;
		}
	}

/***********************************************************************************

主机写 1 Bit
入口参数:欲写的 1 Bit数据(U8 temp的 Bit[0] )
返回参数:无  

************************************************************************************/
U8 Write_Bit(U8 write_Bit)
	{
		U8 temp;
		rPCONG |=0x100;  //PG4[9:8]=01,output
		asm("nop");

		rPDATG &=0x0ef;  //发"0",3us.
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");	
		asm("nop");
		asm("nop");				
		if((write_Bit &0x01)==0x01)
			rPDATG |=0x10;
		else
			rPDATG &=0x0ef;
		temp=8;             //30us
		while(temp)
			{
				asm("nop");
				temp--;
			}
		
		rPDATG |=0x10;      //发"1",2us.
		asm("nop");
		asm("nop");	

	}


void Main(void)
{
    U8 temp;
	U16 temperature[6];
	float Celsius[6];
	U8 count;
	U8 ds18b20_Rom_1[8]={0x28,0x47,0x30,0x05f,0x0,0x0,0x0,0x28};
	U8 ds18b20_Rom_2[8]={0x28,0x8f,0x44,0x05f,0x0,0x0,0x0,0x64};
	U8 ds18b20_Rom_3[8]={0x28,0x00,0x45,0x05f,0x0,0x0,0x0,0x67};
	U8 ds18b20_Rom_4[8]={0x28,0x35,0x3b,0x05f,0x0,0x0,0x0,0xae};
	U8 ds18b20_Rom_5[8]={0x28,0x38,0x2d,0x05f,0x0,0x0,0x0,0x04};	
	
	while(1)
	{

		temp=Reset_18B20();	              //复位	
		if(temp==1)
		Skip_Rom();                       //发 skip_Rom 命令
		Convert_Start();                  //发启动温度转换 命令(44h)
		Timer_Init(50000,0);              //延时 1s
		asm("nop");
        while(rTCNTO5);

		count=5;
		while(count)
		{
			temp=Reset_18B20();               //复位	
  			if(temp==1) 
			switch(count)
			{
				case 1:
					Match_Rom(ds18b20_Rom_1);//发 匹配 ROM_ID 命令(55h),及ds18b20_1 Rom地址
					break;
				case 2:
					Match_Rom(ds18b20_Rom_2);
					break;
				case 3:
					Match_Rom(ds18b20_Rom_3);
					break;
				case 4:
					Match_Rom(ds18b20_Rom_4);
					break;
				case 5:
					Match_Rom(ds18b20_Rom_5);
				default:
					break;
			}

			temperature[count]=Read_Ram();    // 发Read_Ram命令,读回温度值 12位 
			Celsius[count]=temperature[count]*0.0625;
			count--;
		}
		/*	rPCONG |= 0X0400;				// PCONG[15:0]16位, G口配置寄存器.
			rPCONG &= 0x0f7ff;				//  PCONG[11:10]=01, 定义PG5 output。

			rPDATG |=0x020;					// 断开加热棒
			asm("nop");
			rPDATG &=0x0df;					//接通加热棒*/
		
			asm("nop");
	}
}































⌨️ 快捷键说明

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