用STM8的库函数开发DS18B20弄了三天了还是没弄好,求助帮我看看代码。

2019-07-19 21:40发布

硬件我用51测试过了没有问题。时序也照做了,也参考了别人的代码,但还是失败。我感觉问题出在IO口的配置上,推挽输出、上拉输出、浮空输入、上拉输入都试过,还是不成功。下面是我的代码,麻烦帮我看一下。我的延时函数是用定时器计数的,一个_delay_us()有15us。

uchar DS18B20_Rst()
{
       uchar dat=1;
   
        GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_SLOW);//推挽输出高电平,释放单总线 
        _delay_us(1); //稍做延时
   
        GPIO_WriteLow(GPIOA, GPIO_PIN_6); //拉低单总线至少480μs来产生复位脉冲
       _delay_us(40);     //复位脉冲 //精确延时 大于 480us 小于960u
     
       GPIO_WriteHigh(GPIOA, GPIO_PIN_6); //释放总线并进入接收模式
        _delay_us(5);//需要等待15~60us,再发出存在脉冲:拉低总线60-240us

        GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT); //上拉无中断输入
        if (GPIO_ReadInputPin(GPIOA, GPIO_PIN_6)== SET) 
             dat = 1;
        else
             dat = 0;
        
        _delay_us(15);      
        GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_SLOW);
      
        //如果dat=0则初始化成功, dat=1则初始化失败
        return dat;
}

/*
 * 函数名 : DS18B20_ReadData
 * 描述 : 从DS18B20读一字节数据
 * 输入 : 无
 * 输出 : uchar dat   读出的数据
 * 调用 : 内部调用
*/

static uchar DS18B20_ReadData()
{
    uchar i = 0;
    uchar dat = 0;
    
    for (i=0; i<8; i++)             
    {      
        GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_OD_LOW_SLOW);            //拉低总线,产生读信号 
        _delay_us(1);
        dat >>= 1;
        GPIO_WriteHigh(GPIOA, GPIO_PIN_6);                //释放总线,准备读数据
        _delay_us(1);       //延时几微秒读数据
        
        GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);        
        if( GPIO_ReadInputPin(GPIOA, GPIO_PIN_6) == SET )
            dat |= 0x80;//读取数据
        
        _delay_us(4);      //延时 60us 
        
        GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_SLOW)           //拉高总线,准备下一位数据的读取
        _delay_us(1);  
    }
    return dat;
}

/*
 * 函数名 : DS18B20_WriteData
 * 描述 : 写数据到DS18B20
 * 输入 : uchar dat   要写入的数据
 * 输出 : 无
 * 调用 : 内部调用
*/

static void DS18B20_WriteData(uchar dat)
{
    uchar i = 0;
    
    for (i=0; i<8; i++)             
    {
        GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_SLOW);            //拉低总线,产生写信号
        _delay_us(1);   
       
        if (dat&0x01)
           GPIO_WriteHigh(GPIOA, GPIO_PIN_6);
        else
           GPIO_WriteLow(GPIOA, GPIO_PIN_6);
        dat >>= 1;                 
        _delay_us(4);  //至少60μs
        GPIO_WriteHigh(GPIOA, GPIO_PIN_6); //释放总线
        _delay_us(1);
    }
}

/*
 * 函数名 : Get_Temp
 * 描述 : 读DS18B20获取温度
 * 输入 : 无
 * 输出 : uint xdata temp   温度X100
 * 调用 : 内部调用
*/

uint Get_Temper()
{
    uint temp;
    uchar TPH;           //存放温度值的高字节
    uchar TPL;             //存放温度值的低字节
    float f_temp; //存放实际温度
    
    uchar tiu;
  

    DS18B20_Rst();                  //设备复位
    DS18B20_WriteData(0xCC);        //跳过ROM命令
    DS18B20_WriteData(0x44);        //开始转换命令

    GPIO_Init(GPIOA, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);
    if( GPIO_ReadInputPin(GPIOA, GPIO_PIN_6) == SET )
        tiu = 1;
    else 
        tiu = 0;
    
    while (!tiu);                    //等待转换完成
      
    DS18B20_Rst();                  //设备复位
    DS18B20_WriteData(0xCC);        //跳过ROM命令
    DS18B20_WriteData(0xBE);        //读暂存存储器命令
    TPL = DS18B20_ReadData();       //读温度低字节
    TPH = DS18B20_ReadData();       //读温度高字节

temp = TPH; //将高字节和低字节合成一个十六位数
temp <<= 8;
temp |= TPL;

f_temp = temp * 0.0625; //计算实际温度
temp = f_temp * 10 + 0.5; //将浮点数转成整数,保留一位小数,四舍五入

return temp;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
exv
1楼-- · 2019-07-20 02:52
这是一个关于STM8奇葩bug的帖子,参考下:
http://www.openedv.com/posts/list/0/37203.htm      

如楼下所言,可能是delay的问题,用逻辑分析仪测下。  
正点原子
2楼-- · 2019-07-20 03:54
 精彩回答 2  元偷偷看……
qian327
3楼-- · 2019-07-20 08:15
我也正在搞这个DS18B20,应该是延时函数有问题,你是怎么延时的
平衡小车新手
4楼-- · 2019-07-20 13:47
 精彩回答 2  元偷偷看……
stm8s003
5楼-- · 2019-07-20 14:40
 精彩回答 2  元偷偷看……
XXL
6楼-- · 2019-07-20 15:49
回复【5楼】平衡小车新手:
---------------------------------
可以把源代码分享下不?

一周热门 更多>