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

📄 ds18b20.c

📁 该程序解决了单片机c语言中时序要求严格的问题,已经调试通过
💻 C
字号:
#include<reg52.h>
#include<absacc.h>
#include<intrins.h>

#define unit unsigned int
#define uchar unsigned char
#define FALSE 0
#define TRUE 1
#define DS18B20MAX 10

sbit LED=P1^6;
sbit DQ=P1^7;

uchar ROMID[DS18B20MAX][8];     // 该DS18B20的ROMID是 28 CB 81 C2  00 00 00 41
uchar scratchPad[9];
uchar TH=0x64;					// 温度监测系统设定的温度报警上限值
								// 0 1100100 设为100摄氏度
uchar TL=0xd8;					// 温度监测系统设定的温度报警下限值
								// 1 1011000 设为零下40摄氏度
uchar confgReg=0x3f;			// 温度监测系统设定的配置寄存器数据值
								// 0 01 111111 分辨率为10位,最大转换时间187.5秒
void initial(void)
{
	IE=0x00;
    TMOD=0x20;
    PCON=0x00;
    SCON=0x40;
    TH1=0xfd;
    TL1=0xfd;
    LED=1;
   
    
}

    
void delay_1s(void)
{
 	unsigned char i;
	unsigned int j;
	for(i=0;i<250;i++)
	  for(j=0;j<672;j++);
}  


void delay(int time)    		// 延时子程序
{								// 系统采用的是11.059MHz的晶振,所以该延时程序产生16*time+24μs 的延时
	int	i;
	for(i=0;i<time;i++);
}


bit bus_reset(void)          	// 产生单总线系统的总线复位信号,并返回总线上是否存在单总线器件信息
{								// 若返回0表明总线上存在单总线器件,若返回1表明总线上不存在单总线器件
	bit presence;
	DQ=0;					 	// 拉低DQ总线开始复位
	delay(28);					// 保持DQ低480μs
	DQ=1;				 		// 释放DQ
	delay(5);               	// 等待大于60us,等待从设备将总线拉低,如果有从设备就拉低,否则就是高电平
	presence=DQ;				// 获取应答信号
	delay(25);					// 等待总线初始化过程结束
	return(presence);			// 返回应答信号,有芯片应答presence=0
		                        // 无芯片应答presence=1
}


bit read_bit(void)				// 从总线上读取一个数据位
{
	DQ=0;						// 将总线DQ拉低启动读时隙      					
	DQ=1;						// 释放DQ信号线,等待从机返回数据位
	_nop_();                    // 延时4μs再读数据
	_nop_();
	_nop_();
	_nop_();
	return DQ;  
	
}


uchar read_byte(void)         	// 从单总线上读取一个字节
{
	uchar i;
	uchar value=0;				// 将返回值初始化为0
	for(i=0;i<8;i++)
	{
		if(read_bit())
			value|=0x01<<i;		// 读一字节数据,一个读时序中读一位,并做移位处理
			
		delay(3);				// 延时60μs以完成此次读时序,之后再读下一位数据
	}
	return(value);
}


void write_bit(uchar bitval) 	// 向单总线上写一个数据位
{
	DQ=0;						// 拉低DQ以开始一个写时序
	if(bitval==1)
		DQ=1;					// 如要写"1"则将总线置高
	delay(3);					// 延时60μs供DS18B20采样
	DQ=1;				 		// 释放DQ总线
	
}


void write_byte(uchar val)		// 向单总线上写一个数据字节
{
	uchar i;
	uchar temp=0;  				// 将返回值初始化为0
	for(i=0;i<8;i++)			// 写一字节数据,一次写一位
	{
		temp=val>>i;			// 移位操作,将本次要写的位移到最低位
		temp&=0x01;
		write_bit(temp);		// 向总线写该位
	}
	delay(5);                 	// 等待时隙结束
}


/*uchar send_matchRom(uchar DS18B20No)		// 系统主机向总线发出匹配ROM命令
{											// ROM ID是编号为DS18B20No的温度传感器的ROM序列号
	uchar i;
	if(bus_reset()) return FALSE;			// 如果总线上没有器件,返回FALSE
	write_byte(0x55);						// 向总线写匹配命令0x55
	for(i=0;i<8;i++)						// 连续写入8个字节的ROMID
	{
		write_byte(ROMID[DS18B20No][i]);	// 向总线写ROMID的第i个字节
	}
	return TRUE;	
}	
	

void read_scratchPad(uchar DTNo)		// 系统主机从指定的DS18B20中读取便笺存储器的所有字节
{										// 读取的结果放到全局变量scratchPad[9]中
	uchar i;
	send_matchRom(DTNo);				// 向总线发出匹配ROM命令,使编号为DTNo的器件处于选中状态
	write_byte(0xBE);					// 向总线发出读便笺存储器命令
	for(i=0;i<9;i++)					// 连续读入9个字节的便笺存储器单元
	{
		scratchPad[i]=read_byte();		// 从总线读取1个字节存入scratchPad[i]
	}
	
}


void write_scratchPad(uchar DTNo)		// 系统主机向指定的DS18B20中写入TH、TL及配置寄存器数据
{
	send_matchRom(DTNo);				// 向总线发出匹配ROM命令,使编号为DTNo的器件处于选中状态
	write_byte(0x4E);					// 向总线发出写便笺存储器命令
		
	write_byte(TH);
	write_byte(TL);
	write_byte(confgReg);
	
}


void read_ROMID(void)						// 总线上只有一个DS18B20时,主机读出它的64位ROM代码
{
	uchar i;
	write_byte(0x33);					// 启动读ROM
	for(i=0;i<8;i++)
	{
		ROMID[0][i]=read_byte();
	}
}*/

	
main()
{   

	uchar i,k,th,tl;
	unit t=0;
	float result;
	P1=0x7f;
	DQ=0;
    initial();
    TR1=1;	
	
	
	while(1)
	{
		  
		i=bus_reset();					// 如果总线上没有DS18B20,就等待
		
	/*	read_ROMID();						// 读出它的序列号
		for(i=0;i<8;i++)
		{
			SBUF=ROMID[0][i];
       		 while(TI==0);
        	TI=0;
		}*/
	//	delay_1s();
	//	send_matchRom(0);					// 匹配第0个传感器
	//	write_scratchPad(0);				// 写入TH、TL、配置寄存器
	    write_byte(0xCC);
		write_byte(0x44);					// 启动转换 	
		while(!read_bit());					// DQ 为低电平,等待,DQ为高表示转换结束
	
		bus_reset();
	//	read_scratchPad(0);					// 读取温度值,scratchPad的前两个字节就是温度
	    write_byte(0xCC);
	    write_byte(0xBE);
	    
		tl=read_byte();
		th=read_byte();
		tl&=0xfc;							// 精度是10位,因此最低两位无效,屏蔽掉
		t=th;
		t<<=8;
		t|=tl;
		result=t*0.0625;
		k=(uchar)result;
	    
	    LED=!LED; // 发光二极管亮,提示发出一个数据	    
        SBUF=k;
        while(TI==0);
        TI=0;  
        delay_1s();
    	
		    
	}
}






⌨️ 快捷键说明

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