[求助]DS1820谁用过啊?

最近在用1820单线温度传感器时,老出现初始化不成功,请问一般是什么情况引起来的啊?

该芯片对时序要求比较严格,最好用汇编试试


我也一直怀疑是时序的问题,现在我换成12M的晶振后问题解决!多谢提示,也给大家带点经验,1820的时序有点严格!希望大家注意!


#include #include #include #include #define uchar unsigned char #define uint unsigned int // 函数声明区 void init(void); //复位 void delay(uchar t); //延时time=(t+2)*5*Tm void delay_ms(uchar t); void write(uchar dat); //写18b20 子程序 uchar read(void); //读18b20 子程序 void ck(uchar *s, uchar len); //串口发送程序 uchar readtemp(uchar n); // 参数是DS18B20的序号 void initTimer(void); void timerInt(void); // 中断服务程序 void LCD_C_D(bit flag,uchar ldata); void dis_one_zi(uchar x_ass,uchar y_add,uchar code *po); void CLRLCD(uchar number); // 变量定义区 sbit P07 = P0^7; sbit P22 = P2^2; static uchar rom[8]; uchar nowdsp=0; // 当前显示温度所对应的传感器编号 uchar timer=0; // 全局时钟 uchar *out; uchar xiaoshu; uchar displayvalue[4]={'1','2','3','4'}; static uchar temp[3]; uchar code RomCode[8][8]={40,69,62,167,0,0,0,137 , 40,134,186,194,0,0,0,138, 0x28 ,0x0d,0x2e,0xfd,0x00,0x00,0x00,0xe2, 0x28 ,0x48,0x3c,0xfd,0x00,0x00,0x00,0x83, 0x28 ,0x92,0x64,0xfd,0x00,0x00,0x00,0x23, 0x28 ,0xb7,0xf6,0xd9,0x00,0x00,0x00,0x34, 0x28 ,0x74,0x6b,0xfd,0x00,0x00,0x00,0xd7, 0x28 ,0xff,0x61,0xfd,0x00,0x00,0x00,0x78 }; //8个传感器的64为序列号

// 主函数 main() { /* uchar i; init(); write(0x33); for(i=0;i<8;i++) rom[i]=read(); ck(rom ,8); //读序列号 */ initTimer(); while(1) { for(nowdsp=0;nowdsp<8;nowdsp++) { init(); // DS18B20复位子程序 write(0xcc); // 跳过ROM write(0x44); // 启动温度转换 temp[0]=readtemp(nowdsp); // 读取温度值 displayvalue[0]=temp[0]/10+0x30; displayvalue[1]=temp[0]%10+0x30; displayvalue[2]=xiaoshu+0x30; displayvalue[3]=nowdsp+0x31; ck(displayvalue,4); } } }

// 函数定义区 void init(void) // 复位 { //display(temp[0]); EA=0; // 关闭中断 P22=0; //总线为低电平 delay(94); //总线复位电平保持500us P22=1; //释放总线 delay(12); //保持60us while(1) { if(P22==0) // 等于说明存在 { break; } else { P0=0x99; P2=0x00; } } /// 检测到后的处理 delay(80); P22=1; EA=1; // 完成任务后允许中断

} void write(uchar dat) //写一个字节子程序 { uchar i=0; bit b; EA=0; // 关闭中断 for(i=8;i>0;i--) { //display(temp[0]); b=dat&0x01; if(b==1) { // 写1 P22=0; // 拉低总线6us _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); P22=1; delay(11);//64us } else { // 写0 P22=0; //拉低60us delay(10); P22=1; delay(0); //10us } dat>>=1; } EA=1; // 完成任务后允许中断 }

uchar read(void) //读一个字节子程序 { uchar dat=0 ; uchar i=0; EA=0; // 关闭中断 for(i=0;i<8;i++) { P22=0; //拉低总线6us _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); P22; // 释放总线9us _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); dat>>=1; if(P22) { dat=dat|0x80; } delay(9); } EA=1; // 完成任务后允许中断 return(dat); }

void ck(uchar *s , uchar len) // 串口初始化发送子程序 { uchar j; TMOD=0x21; SCON=0x50; // PCON=0x80; TH1=0xF3; TL1=0xF3; TR1=1; if(len==0)len=strlen(s); //display(temp[0]); for(j=0;j { SBUF=s[j]; while(!TI); TI=0; } }

void delay(uchar t) //延时time=(t+2)*5*Tm { while(t--); }

void delay_ms(uchar t) { uchar i, k; for(i=0;i { k=165; while(k--); } }

uchar readtemp(uchar n) {

uchar i=0; EA=0; // 关闭中断 init(); write(0x55); // 匹配rom for(i=0;i<8;i++) { write(RomCode[n][i]); } write(0xbe); // 读入暂存 for(i=0;i<9;i++) { temp[i]=read(); } i = ((temp[0]>>4)|(temp[1]<<4)); temp[0]=temp[0]&0x0f; switch(temp[0]) { case 0 : xiaoshu=0;break; case 1 : xiaoshu=0;break; case 2 : xiaoshu=1;break; case 3 : xiaoshu=1;break; case 4 : xiaoshu=2;break; case 5 : xiaoshu=3;break; case 6 : xiaoshu=3;break; case 7 : xiaoshu=4;break; case 8 : xiaoshu=5;break; case 9 : xiaoshu=5;break; case 10 : xiaoshu=6;break; case 11 : xiaoshu=6;break; case 12 : xiaoshu=7;break; case 13 : xiaoshu=8;break; case 14 : xiaoshu=8;break; case 15 : xiaoshu=9;break; } EA=1; // 完成任务后允许中断 return i; }

void initTimer(void) { TMOD=0x21; TH0=0x3c; TL0=0xb0; EA=1; ET0=1; TR0=1; }

void timerInt(void) interrupt 1 { if(timer==20) //每秒钟更换一次显示 { nowdsp=(nowdsp==7)?0:(nowdsp+1); timer=0; } TH0=0x3c; TL0=0xb0; TR0=1; timer++; }


只有登录才能回复,可以选择微信账号登录