DS18B20之Proteus仿真使用分类:传感器AVR与C2010-05-2212:20886人阅读评论(0)收藏举报对于数字单线温度传感器DS18B20可谓是久仰大名,但是一直都没有认真的去弄过。曾经看过网络上流传的中文PDF文档,感到其对时序要求比较严格,其他倒无所谓。这几天感到有必要把曾经弄过的以及没有弄过但是比较常用的传感器写个范例,以便于以后的工作。就从这个18B20开始了。结果。。。。第一天没搞定!第二天。。。。又没搞定!这下怒了,虽说不是什么高手,但是搞个温度传感器都要2天那还了得!于是在周末决定好好研究一下。先来看18B20的时序。-----K,竟然不能插入图片!好吧,口述。一般要求DS18B20数据总线使用4.7K左右的电阻上拉,所以在MCU或者DS18B20没有强制将总线拉低的情况下,总线应该是高电平的。复位的要求是持续拉低总线480us以上(小于960us),然后释放总线。对于AVR之类的有数据方向存储器的MCU,将数据方向设置为输入即可。这个时候总线应该会被上拉电阻拉高。然后静静等待,如果DS18B20正常,那它应该会在15-60us之后将总线拉低60-240us。我对这两个数据感到非常的不爽。MCU什么时候采样电平最合适呢?只能在MCU释放总线60us后,才能保证此时DS18B20如果存在肯定是将总线拉低的,但是也不能再后了,因为DS18B20将总线拉低最短只有60us。万一DS18B20在MCU释放总线后15us后就拉低了总线,且又仅拉低60us。。。。。留给MCU采样的时间只有15us了!郁闷!这里要注意一条C的语句可能执行N多个机器周期,所以还要注意指令执行时间,如果你的MCU时钟比较慢,那就等死吧。恩还有,从释放总线开始到开始执行其他操作这段时间最短也要480us。(其实我没这么干也成功了)写时序:DS18B20以下降沿开始表示一次操作开始。无论读写都是如此。写操作有写“1”与写“0”(二进制就是好啊)。如果是写“1”,要遵循先拉低总线至少1us然后再释放总线,或者输出高。这里延时1us其实是非常短的时间,你的指令执行周期可能都超过这个1us,所以未必需要显式的延时。注意,拉高后还要延时60us,因为读写周期最少都要60us。写“0”就简单点了,拉低直接延时60us就OK。读时序:读也要先将总线拉低至少1us然后再释放,交给DS18B20来操作,如果DS18B20要输出“1”,就会将总线拉高(其实是上拉电阻的功劳)如果是输出“0”,就会将总线拉低。MCU要做的就是在释放总线之后15us内采样总线电平。在Proteus中,奇怪了。通过示波器发现DS18B20对总线的控制时间都在60us以上,所以MCU采样总线可以在60us以内完成。不知道事实是不是如此了。好了,基本的读写操作搞定之后,DS18B20也就算是被驯服了。来个测试,要想知道自己的复位、读写时序有没有真正搞定就写个程序来读写DS18B20内部的RAM好了。内部RAM有9个字节,其中第一个与第二个分别存储了当前的温度的低字节与高字节。默认的这两个字节内容分别是0x50,0x05。试试看能不能读出来喽。小例子奉上。[c-sharp:showcolumns]viewplaincopy·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······1501.//18b20数字温度传感器使用2.//element.zhou3.//2010.5.164.//8MHz5.#includeavr/io.h6.#includeutil/delay.h7.8.#defineucharunsignedchar9.#defineuintunsignedint10.#definedelay1usasm(nop);asm(nop);asm(nop);asm(nop);asm(nop);asm(nop);asm(nop);asm(nop);11.#definedelay2usdelay1us;delay1us;12.#definedelay5usdelay2us;delay2us;delay1us;13.#definedelay15us{delay5us;delay5us;delay5us;}14.#definedelay60us{delay15us;delay15us;delay15us;delay15us;}15.16.uchardigit[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06};17.ucharsegcode[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};18.19.voidinit_mcu(void)20.{21.DDRA=0x03;22.PORTA=0x01;23.DDRC=0xFF;24.PORTC=0xFF;25.DDRD=0x80;26.PORTD=0x80;27.}28.ucharreset(void)29.{30.uchari=0,data=0;31.PORTD=0x00;32.DDRD=0x80;33.for(i=0;i8;i++)//延时480us34.delay60us;35.DDRD=0x00;//输入,外部上拉,等待18b20拉低36.delay60us;//延时60us37.data=PIND&0x80;38.for(i=0;i4;i++)39.delay60us;40.if(data)41.return0;42.else43.return1;44.}45.voidwrite(uchardata)46.{47.uchari=0;48.PORTD=0x80;49.DDRD=0x80;50.for(i=0;i8;i++)51.{52.PORTD=0x00;53.if(data&(1i))54.PORTD=0x80;55.delay60us;56.PORTD=0x80;57.delay1us;58.}59.}60.ucharread_byte(void)61.{62.uchari=0,data=0x00;63.for(i=0;i8;i++)64.{65.PORTD=0x00;66.DDRD=0x80;67.delay1us;68.DDRD=0x00;//输入,准备读取数据69.delay1us;70.if(PIND&0x80)71.data|=(1i);72.PORTA^=0x02;//测试数据73.delay60us;74.}75.//PORTC=data;76.//while(1)77.//;78.returndata;79.}80.voidwait_busy(void)81.{82.PORTD=0x00;83.DDRD=0x00;84.while(!(PIND&0x80))85.;86.}87.88.intmain(void)89.{90.uchari=0;91.init_mcu();92.while(1)93.{94.//reset();95.//write(0xcc);//跳过ROM96.//write(0x4e);97.//write(0x0f);98.//write(0x50);99.//reset();100.//write(0xcc);101.//write(0xbe);102.//for(i=0;i9;i++)103.//digit[i]=read_byte();104.reset();105.write(0xcc);106.write(0x44);//启动温度转换107.wait_busy();108.reset();109.write(0xcc);110.write(0xbe);111.for(i=0;i9;i++)112.digit[i]=read_byte();113.reset();114.115.digit[5]=(digit[0]4)+(digit[1]4);116.//PORTC=digit[5];117.//while(1);118.PORTC=~segcode[digit[5]/10];119.for(i=0;i10;i++)120._delay_ms(2000);121.PORTC=~segcode[digit[5]%10];122.for(i=0;i10;i++)123._delay_ms(2000);124.}125.return0;126.}刚搞好,调试的痕迹还很明显没办法只有计算机其他为0,条件艰苦。K,最后了又发现能传点图片。1。Proteus仿真电路2。读时序(黄色的是总线波形,蓝色的是采样波形时间是每小隔50us)3。读时序(时间每小隔20us,其他同上,黄色的是DS18B20控制的总线电平,也有60us)4。官方复位时序-----------链上去了