CYusb与DS18B20通信

Posted leftXDD

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CYusb与DS18B20通信相关的知识,希望对你有一定的参考价值。

目标:实现CYusb------ds18b20温度读取

环境:EZ_usb_suit

注意事项:单总线通信时序一定要正确。

思路:

        硬件:在18b20-DQ处有4.7k上拉电阻,焊接时需要注意。购买成品则无需再焊接(上拉顾名思义通过电源正极拉高电压)。

        软件:初始化、写指令、读温度数据;

1.初始化

        拉低总线至少480us,释放15-60us,18b20响应60-240us,拉高总线保证设备从总线释放到最后被拉高持续周期至少为480us。

  在初始化中注意设置IO的IN和OUT方向。代码如下:

CyBool_t
Init_DS18B20(void)    
{
	CyBool_t gpioValue;
	Init_DQ_Output(1);
	CyU3PGpiosetValue (DQ, CyTrue);
	delay(250);//稍作延时 250->12.11us   
   
	CyU3PGpioSetValue (DQ, CyFalse);
	delay(10000);//延时>480us        

	CyU3PGpioSetValue (DQ, CyTrue);//拉高总线 15-60us 
	delay(750);

	Init_DQ_Output(0);
	CyU3PGpioGetValue (DQ,&gpioValue);//读总线状态 为0复位成功,为1则不成功
	

	Init_DQ_Output(1);
	CyU3PGpioSetValue (DQ,CyTrue);
	delay(10000);            
	
	 return gpioValue;
}

 2.写、读指令,时序图为:

写0:拉低总线持续60-120us后释放;写1:拉低总线15us后释放总线;

写数据的周期为60us;

读0:拉低总线至少1us,释放总线,等待设备响应在拉低总线开始内的15us读总线数据;

读1:拉低总线至少1us,释放总线;

代码如下

uint8_t
Read(void)            //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{
	CyBool_t gpioValue;
	unsigned char i=0; //每个读周期持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
    unsigned char dat=0;
    for (i=8;i>0;i--)         //一个字节有8位
    {
		Init_DQ_Output(1);
		CyU3PGpioSetValue (DQ, CyTrue);
		delay(10);             //6.9
		CyU3PGpioSetValue (DQ, CyFalse);
		delay(50);
		dat>>=1;
		CyU3PGpioSetValue (DQ, CyTrue);
		Init_DQ_Output(0);
		CyU3PGpioGetValue (DQ, &gpioValue);
		if(gpioValue)
			dat|=0x80;
		delay(250);
		CyU3PGpioSetValue (DQ, CyTrue);
		delay(1250);
    }
    return(dat);
}
void
Write(uint8_t dat)
{
		uint8_t i=0;
		CyBool_t gpioValue;

		for(i=0;i<8;i++)
		{
			Init_DQ_Output(1);
			CyU3PGpioSetValue (DQ, CyFalse);
			delay(250);

			gpioValue=dat&0x01;
			CyU3PGpioSetValue (DQ, gpioValue);
			delay(1000);//延时约45us,DS18B20在15~60us对数据采样

			CyU3PGpioSetValue (DQ, CyTrue);
			dat>>=1;
		}
		delay(500);
}

 3.读温度

初始化设备,跳过ROM指令,开始温度转换命令;初始化,跳过ROM指令,读寄存器,进行温度转换。(其他指令网上可查)

代码如下:

//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
double
Get_Temp(void)
{

	double temp=0;
	uint8_t TL,TH,tl,th;
	Init_DS18B20();
	Write(0xcc);//发跳过ROM命令
	Write(0x44);//发读开始转换命令
	Init_DS18B20();
	Write(0xcc);//发跳过ROM命令
	Write(0xbe);//读寄存器,共九字节,前两字节为转换值
	TL=Read(); //a存低字节 读取到的第一个字节为温度LSB
	TH=Read(); //b存高字节 读取到的第一个字节为温度MSB

	tl = TL & 0x0F;
	th = ((TH&0x0F)<<4) + (TL >>4);
	temp = (int)th;
	if(TH > 0x08)
	{
		th=~th+1;
		temp = -th;
	}
	temp +=tl*0.0625;

	return temp;

}

 4.波形检测

 上图写数据为:00110011  00100010由于是LSB的方式,所以读完后,反方向读,所以最终写入的真实指令为:0xcc,0x44。

读取的温度数据:

 再次初始化,读取寄存器,经过转化最终读取的数据为1A,即为26°C。

以上完成最终的温度读取。

以上是关于CYusb与DS18B20通信的主要内容,如果未能解决你的问题,请参考以下文章

一起玩转树莓派——DS18B20测温模块应用

Arduino ESP8266/ESP32 多路DS18B20温度采样读取

1-wire单总线DS18B20

DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号

Proteus51单片机+双DS18B20浮点数温度显示

STM32单片机学习(11) DS18B20温度传感器实验