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

📄 experiment_3.c

📁 学习掌握单总线数字式温度传感器 DS18B20的64位激光ROM码的读出方法。读DS18B20 64位ROM码命令(33h)允许主机直接读出从机的64位ROM代码
💻 C
字号:
/**************************************************************************

实验三  读 ds18b20 64位 ROM码

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

#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 查询方式*/

    
void 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首地址      */
void Match_Rom(U8 *ROM_addr)
	{
		U8 count;
		U8 *p;
//		U8 temp=0x55;		//匹配ROM 命令 55H
		Write_Byte(0x55);
		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代码 */
void 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--;
		}
	}

/*复位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) 
		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] )
返回参数:无  */
void 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 Rom_buf1[8];
	U8 Rom_buf2[8];
    U8 temp;
	
	while(1)
	{
//  读 ds18b20 的8字节ROM码
   	  temp=Reset_18B20();	 //复位
	  if(temp==1)
		Read_Rom(Rom_buf1);  //发(33h)命令,读回64位ROM码。
	
	  temp=Reset_18B20();	 //再读
	  if(temp==1)
		Read_Rom(Rom_buf2);
	  asm("nop");
	 }	
}



⌨️ 快捷键说明

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