永发信息网

51单片机关于DS18B20的启动问题

答案:4  悬赏:60  手机版
解决时间 2021-05-02 03:10

各位高手,这是我的温度传感器的复位初始化函数

void start(void)

 unsigned char  i;
 ds = 0;                       //ds为数据I/O口
 for(i=100;i>0;i--);
 ds = 1;
 for(i=5;i>0;i--); 
}

始终不明白为什么我将延时变量 i 定义为 unsigned char 后 温度显示一直为5.9

 后面有几个函数中也有同样的问题 只有定义为unsigned int 后 温度显示才正常

明明没有超出范围啊。。害我调了一天。。太难发现了!

最佳答案

原因可能是:for循环的反汇编代码就是一些加法运算和跳转指令的集合,而51是8位单片机,它做8位(unsigned char)加法运算的速率和16位(unsigned int)加法运算的速率是不一样的,这些可以从反汇编代码中看出来,所以,同样是一句for循环,对于不同类型的循环变量来说,执行时间是完全不一样的。

全部回答

void Init_DS18B20(void)     {  EA = 0;    //关中断  DQ = 1;    //DQ复位    delay(16);    //稍做延时    DQ = 0;    //拉低DQ总线    delay(160);    //精确延时,时间范围可以从480到960微秒    DQ = 1;    //拉高DQ总线  EA = 1;    //开中断    delay(24);    //15到60毫秒之内返回低电平

}

unsigned char ReadOneChar(void)     {    unsigned char i = 0;    unsigned char dat = 0;  EA = 0;    //关中断       for (i=8;i>0;i--)    {      DQ = 0;    // 给脉冲信号      dat>>=1;    // 数据右移一位      DQ = 1;    // 给脉冲信号      if(DQ)    // DQ为1      dat|=0x80;    // 读出数据      delay(8);    // 延时   }  EA = 1;    //开中断       return(dat); }

void WriteOneChar(unsigned char dat) {  unsigned char i, j;    bit testb;  EA = 0;    //关中断    for(j=1;j<=8;j++)    {      testb=dat&0x01;      dat=dat>>1;   DQ=0;      if(testb)          {    //写入 1         i++;i++;i++;i++;    //先短延时"0"     DQ=1;     i=16;while(i>0)i--;    //再长延时"1"      }else         {    //写入 0         i=16;while(i>0)i--;    //先长延时"0"     DQ=1;     i++;i++;i++;i++;    //再短延时"1"     }    }  EA = 1;    //开中断 } void Read_DS18B20_ID(void)     {  Init_DS18B20();   WriteOneChar(READ_ROM);      serial[0]=ReadOneChar();   serial[1]=ReadOneChar();   serial[2]=ReadOneChar();   serial[3]=ReadOneChar();   serial[4]=ReadOneChar();   serial[5]=ReadOneChar();   serial[6]=ReadOneChar();   serial[7]=ReadOneChar();  } void MatchRom(unsigned char *rom) {     unsigned char i;  Init_DS18B20();  WriteOneChar(MATCH_ROM); //匹配ROM  for(i=0;i<8;i++)  {   WriteOneChar(rom[i]);  }  } void TemperatureConversion(void)     {      Init_DS18B20();    // 初始化DS18B20    delay(1);    // 延时    WriteOneChar(SKIP_ROM);    // 跳过序列号命令    WriteOneChar(CONV_TEM);    // 发送温度转换命令     }

void DataTreatment(unsigned char *rom)     {  unsigned char a1,a2;    unsigned int temp;            Init_DS18B20();    // 初始化ds18b2    delay(1);

 if(*rom==0x28) MatchRom(rom);   // 匹配ROM   else WriteOneChar(SKIP_ROM);     // 跳过ROM命令    WriteOneChar(READ_REG);    // 发送读取数据命令    a1=ReadOneChar();        a2=ReadOneChar();    // 连续读两个字节数据

   temp=a2;    temp<<=8;        temp|=a1;        // 两字节合成一个整型变量。         if(temp>0x18CC)    // 温度值正负判断 0001 1000 1100 1100    {          temp=~temp+1;    // 负温度求补码  temp=65536-temp;      Dis_play[5]=1;    // 标记温度负,1为负,0为正    }else Dis_play[5]=0;

   Dis_play[0]=ditab[temp&0x0f];    // 取小数部分转换为十进制数    Dis_play[4]=temp>>4;    // 整数部分的绝对值,可调用    Dis_play[3]=Dis_play[4]/100;    // 获得百位数据    Dis_play[1]=Dis_play[4]%100;    // 后两位数据暂存    Dis_play[2]=Dis_play[1]/10;    // 获得十位数据    Dis_play[1]=Dis_play[1]%10;    // 获得个位数据

 Dis_play[0] += 48;   Dis_play[1] += 48;  Dis_play[2] += 48;  Dis_play[3] += 48;

   if(Dis_play[5])      Dis_play[3]='-';    // 为负数时,百位显示 "-" 11

   if(Dis_play[3]==48)    // 最高位为0则不显示    {      Dis_play[3]=' ';        // 先判断百位是否为0  10      if(Dis_play[2]==48)     Dis_play[2]=' ';      // 再判断十位是否为0  10    } }

时序问题,18B20的时序很严格,请按照它的时序严格操作
为什么要定义为char哦。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
驾驶证全国通用吗?
雕塑广场在哪里啊,我有事要去这个地方
英语作文怎样学唐诗,教小学英语的句型教学有
qq密码能打!·这符号吗?
孩子心里的家长是什么样子得?
雪梨生吃 跟炖过之后吃,效果区别很大,为什
谁知道IS里面《MC AK》的ID是多少吗?
求《银魂-173》末尾那种的《世界奇妙物语》的
笔记本开机时间大于一分钟是否正常?
90后为何如此轻率献身
为啥我右眼皮老跳啊!?
为什么最近、老爱睡觉?
我想买个等级靓号说至少要支付3个月时什么意
康明(郑州)置业有限公司 现在还存在吗?
吉安市千足金多少钱一克
推荐资讯
武汉中南财经政法大学首义校区离哪个汽车站比
搞你妈药品什么
晨光文具龙锦小学店在什么地方啊,我要过去处
违章罚款网上怎么交,怎么在网上用支付宝缴纳
梦幻诛仙寻人任务说财神在那里京城的是那个?
广进便利店在什么地方啊,我要过去处理事情
狼队的背包怎么用
有一区华南 静水湖的吗? 有的MMMM叫个朋友
苏轼 《望江南》的文体
哪位能给个超级马里奥wil?
《伟人细胞》课文
北京怀柔区度假村带小木屋别墅形式的?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?