打印
[AVR单片机]

DS18B20大家帮我看看吧,这东西搞了两天醉了

[复制链接]
872|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 asd9875321 于 2015-11-17 16:09 编辑

这个是我用的18B20程序部分!
#include "config.h"

#define DQ  5  //总线使用PD5口

#define SET_DQ  PORTD|=BIT(DQ)  //拉高总线高电平
#define CLR_DQ  PORTD&=~BIT(DQ) //拉低总线低电平
#define DQ_IN   PIND&BIT(DQ)    //信号输入

#define SET_OUT DDRD|=BIT(DQ);  //DQ输出
#define SET_IN  DDRD&=~BIT(DQ); //DQ输入

uchar  bTemp;

extern uchar LEDText2;
extern uchar LEDText3;
extern uchar LEDText4;
extern uint  TempText;
extern uchar CAN_TX_Buf[8];
uchar  xu[8];

//DS18B20 复位函数
void DS18B20_Reset()
{   
           SET_OUT; //DQ为输出状态
        CLR_DQ; //输出低电平
        DelayUs(720); //延迟大于480 微妙
        SET_DQ; //释放总线
        //SET_IN; //DQ为输入状态
        DelayUs(48); //延迟15~60微妙
        SET_IN; //DQ为输入状态
        
        //while(DQ_IN); //等待从机DS18B20 应答(低电平有效)无效待查证
        while(!DQ_IN); //等待从机DS18B20 释放总线
   

}
//DS18B20 写字节函数,最少持续60us包括周期之间的1us延时
void DS18B20_Write(unsigned char Data)
{
        unsigned char i;
        SET_DQ;
        SET_OUT; //DQ 为输出
        for(i=0;i<8;i++)
         {
         CLR_DQ; //拉低总线
         DelayUs(10); //延迟10 微妙(最大15 微妙)
         if(Data&0x01) SET_DQ;
         else CLR_DQ;
         DelayUs(45); //延迟40 微妙(最大45 微妙)
         SET_DQ; //释放总线
         DelayUs(1); //稍微延迟
         Data>>=1;
     }
         SET_DQ; //释放总线
}
//DS18B20 读字节函数
unsigned char DS18B20_Read()
{
unsigned char i,Temp=0;
  for(i=0;i<8;i++)
  {
        
        SET_OUT; //DQ 为输出状态
        CLR_DQ; //拉低总线,启动输入
        DelayUs(1);
        SET_DQ; //释放总线
        DelayUs(4);
        SET_IN; //DQ 为输入状态
        Temp>>=1; //数据右移
        if(DQ_IN) Temp|=0x80;
        DelayUs(55); //延迟45 微妙(最大45 微妙)
    SET_OUT;      
  }
  return Temp;
}



unsigned int  DS18B20_Int(void)
{
    DS18B20_Reset(); //DS18B20 复位
        DS18B20_Write(0xCC); //跳过ROM
        DS18B20_Write(0x4E); //写RAM
        DS18B20_Write(80); //写报警高位
        DS18B20_Write(10); //写报警低位
        DS18B20_Write(0x7F); //写配置寄存器
        DS18B20_Reset(); //DS18B20 复位
        
}

//读温度函数
unsigned int Read_Temperature()
{
        unsigned int Temp1,Temp2,Temp3;
        if(bTemp==0)
        {
         bTemp=1;
         DS18B20_Reset(); //DS18B20 复位
         DS18B20_Write(0xCC); //跳过ROM
         DS18B20_Write(0x44); //温度转换
        }
        else
        {
         bTemp = 0;
         DS18B20_Reset(); //DS18B20 复位
         DS18B20_Write(0xCC); //跳过ROM
         DS18B20_Write(0xbe); //读取RAM
         Temp1=DS18B20_Read(); //读低八位,LS Byte, RAM0
         Temp2=DS18B20_Read(); //读高八位,MS Byte, RAM1
         DS18B20_Reset(); //DS18B20 复位,表示读取结束
         Temp3=(((Temp2<<8)|Temp1)*6.25); //0.0625=xx, 0.625=xx.x, 6.25=xx.xx
         TempText = Temp3; //0.0625=xx, 0.625=xx.x, 6.25=xx.xx
         LEDText2 = Temp3/1000;
         LEDText3 = (Temp3%1000)/100;
         LEDText4 = (Temp3%100)/10;
         TempText = TempText/10;
         CAN_TX_Buf[0] = 0xE0;
         CAN_TX_Buf[1] = 0x60;
         CAN_TX_Buf[2] = TempText%255;
         CAN_TX_Buf[3] = TempText/255;
         CAN_TX_Buf[6] = 0x79;
         }
}


相关帖子

沙发
asd9875321|  楼主 | 2015-11-17 16:25 | 只看该作者
问题是现在读取18B20一直为1999就是temptext的值。


使用特权

评论回复
评论
SD10A 2015-11-17 21:44 回复TA
你的示波器带宽 和存储深度 是多少呢? 
板凳
asd9875321|  楼主 | 2015-11-18 09:44 | 只看该作者
本帖最后由 asd9875321 于 2015-11-18 10:58 编辑


这个是示波器的参数

使用特权

评论回复
地板
NE5532| | 2015-11-18 16:52 | 只看该作者
你先把复位应答调通,不要想一口吃成胖子。

使用特权

评论回复
5
asd9875321|  楼主 | 2015-11-19 16:59 | 只看该作者
本帖最后由 asd9875321 于 2015-11-20 15:26 编辑

问题是复位最后应该加个延时,就行了,也不知道为什么,有个while指令还要加延时,终于解决了。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

4

帖子

0

粉丝