OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4478|回复: 0

想问下大家stm8使用ds18b20测温度一直显示4095是什么情况?

[复制链接]

0

主题

0

帖子

0

精华

新手入门

积分
10
金钱
10
注册时间
2020-10-1
在线时间
1 小时
发表于 2021-11-27 21:53:23 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 ZMan 于 2021-11-28 16:57 编辑

网上都说是延时问题,但是怎么改都不行。
单片机主控芯片为stm8s105c6t6,外部时钟是12M






#include "ds18b20.h"

void Alarm_for_No_DS18B20(void)

{

    //单总线上没有发现DS18B20则报警,该动作据具体应用具体处理

}

unsigned char DS18B20_Start(void) //复位ds18b20芯片

{

    unsigned char i,succ=0xff;

    DS18B20_PIN_SET_OUT();              //置为输出口

    DS18B20_WR0();                     //总线产生下降沿,初始化开始

    for(i=0; i<30; i++)delay_us(25);   //总线保持低电平在480 - 960微秒之间  ;i<20;(25us)

    DS18B20_WR1();                    //总线拉高

    DS18B20_PIN_SET_IN();             //置为输入,主机释放总线,准备接收DS18B20的应答脉冲

    i=0;

    while(R_DS18B20())               //等待DS18B20发出应答脉冲

    {

        delay_us(5);                 //5

        if(++i>12)                  //DS18B20检测到总线上升沿后等待15-60us

        {

            succ=0x00;              //如果等待大于约60us,报告复位失败

            break;

        }

    }

    i=0;

    while(!R_DS18B20())            //DS18B20发出存在脉冲,持续60-240us

    {

        delay_us(5);               //5

        if(++i>48)                //如果等带大于约240us,报告复位失败

        {

            succ=0x00;

            break;

        }

    }

    delay_ms(20);

    return succ;

}

void DS18B20_SendU8(unsigned char d8)//向DS18B20写一字节函数

{

    unsigned char i;

    DS18B20_PIN_SET_OUT();        //置为输出口

    for(i=0; i<8; i++)

    {

        DS18B20_WR0();           //总线拉低,启动“写时间片”

        delay_us(2);             //大于1微妙

        if(d8&0x01)DS18B20_WR1();

        delay_us (32);           //延时至少60微秒,使写入有效

        delay_us (30);

        DS18B20_WR1();           //总线拉高,释放总线,准备启动下一个“写时间片”

        d8>>=1;

        delay_us (1);

    }

    DS18B20_PIN_SET_IN();       //主机释放总线

}

unsigned char DS18B20_ReadU8(void)//从DS18B20读1个字节函数

{

    unsigned char i,d8;

    for(i=0; i<8; i++)

    {

        d8>>=1;

        DS18B20_PIN_SET_OUT();//置为输出口

        DS18B20_WR0();        //总线拉低,启动读“时间片”

        delay_us(2);         //大于1微妙

        DS18B20_WR1();        //主机释放总线,接下来(2~15)us内读有效

        DS18B20_PIN_SET_IN(); //引脚设定为输入口,准备读取

        delay_us(2);         //延时2个us后进行读

        if(R_DS18B20())d8|=0x80;//从总线拉低时算起,约15微秒内读取总线数据

        delay_us(32);       //60us后读完成

        delay_us(30);

        DS18B20_WR1();       //总线拉高,主机释放总线,准备启动下一个“写时间片”

    }

    DS18B20_PIN_SET_IN();    //主机释放总线

    return(d8);

}

void Init_DS18B20(void)           //初始化DS18B20

{

    unsigned char i;

    i=DS18B20_Start();             //复位

    if(!i)                        //单总线上没有发现DS18B20则报警

    {

        Alarm_for_No_DS18B20();

        return;

    }

    DS18B20_SendU8 (SKIP_ROM);    //跳过rom匹配

    DS18B20_SendU8 (WRITE_RAM);   //设置写模式

    DS18B20_SendU8 (0x64);        //设置温度上限100摄氏度

    DS18B20_SendU8 (0x8a);        //设置温度下线-10摄氏度

    DS18B20_SendU8 (0x7f);        //12bit(默认)

}

//--------------------------------------------------------------------------------------

unsigned int Read_DS18B20(void)  //读取并计算要输出的温度

{

    unsigned char i;

    unsigned char tl;

    unsigned int th;

//    unsigned char t;

//    unsigned char temp;

    i=DS18B20_Start();            //复位

    if(!i)                        //单总线上没有发现DS18B20则报警

    {

        Alarm_for_No_DS18B20();

        return 0;

    }

    delay_ms(1);

    DS18B20_SendU8(SKIP_ROM);     //发跳过序列号检测命令

    DS18B20_SendU8(CONVERT_TEM);  //命令Ds18b20开始转换温度

    i=0;

    delay_ms(1);

    while(!R_DS18B20())          //当温度转换正在进行时,主机读总线将收到0,转换结束为1

    {

        delay_ms(3);

        if(++i>250) break;      //至多转换时间为750ms

    }

    DS18B20_Start();            //初始化

    delay_ms(1);

    DS18B20_SendU8(SKIP_ROM);   //发跳过序列号检测命令

    DS18B20_SendU8(READ_RAM);   //发读取温度数据命令

    tl = DS18B20_ReadU8();      //先读低8位温度数据

    th = DS18B20_ReadU8()<<8;   //再读高8位温度数据

    return (th|tl)*10>>4;      //温度放大了10倍,*0.0625=1/16=>>4

   

//    temp = DS18B20_ReadU8();          //先读低八位

//    t = (((temp & 0xF0) >> 4) + (temp & 0x0F) * 0.0625);

//    temp = DS18B20_ReadU8();          //再读高八位

//    t += ((temp & 0x0F) << 4);

//  

//    return t;

}





void delay_us(uint16_t nCount)

{

    nCount *= 3;

    while(--nCount);

}

void delay_ms(uint16_t nCount)

{

    while(nCount--)

    {

        delay_us(1000);

    }

}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-5-29 09:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表