目标:实现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。
以上完成最终的温度读取。