Origin______ 2024-03-17 21:34 采纳率: 22.2%
浏览 32
已结题

关于#c++#的问题:基于cc2530获取ds18b20温度值,串口调试一直显示的DS18B20:4080.0如何解决呢?

基于cc2530获取ds18b20温度值,串口调试一直显示的DS18B20:4080.0,是什么原因呢?如何解决呢?

img


串口调试结果显示

img


具体代码
ds18b20.c

#include "ds18b20.h" 

#define Ds18b20IO P0_4       //温度传感器引脚

void Delay_us(unsigned int k)//us延时函数
{
    T1CC0L = 0x06; 
    T1CC0H = 0x00; 
    T1CTL = 0x02; 
    while(k)
    { 
        while(!(T1CNTL >= 0x04));
        k--;
    }
    T1CTL = 0x00;  //关闭定时器
}

void Delay_ms(unsigned int k)
{
    T1CC0L = 0xe8;
    T1CC0H = 0x03;
    T1CTL = 0x0a; //模模式 32分频
    while(k)
    {
        while(!((T1CNTL >= 0xe8)&&(T1CNTH >= 0x03)));
        k--;
    }
    T1CTL = 0x00; //关闭定时器
}

void Delay_s(unsigned int k)
{
    while(k)
    {
        Delay_ms(1000);
        k--;
    }
}

//时钟频率为32M
void Ds18b20Delay(unsigned int k)
{
    unsigned int i,j;
    for(i=0;i<k;i++)
        for(j=0;j<2;j++);
}

void Ds18b20InputInitial(void)//设置端口为输入
{
    P0DIR &= 0x7f;
}

void Ds18b20OutputInitial(void)//设置端口为输出
{
    P0DIR |= 0x80;
}

//ds18b20初始化  初始化成功返回0x00,失败返回0x01
unsigned char Ds18b20Initial(void)
{
    unsigned char Status = 0x00;
    unsigned int CONT_1 = 0;
    unsigned char Flag_1 = 1;
    Ds18b20OutputInitial();
    Ds18b20IO = 1;      //DQ复位
    Ds18b20Delay(260);  //稍做延时
    Ds18b20IO = 0;      //单片机将DQ拉低
    Ds18b20Delay(750);  //精确延时 大于 480us 小于960us
    Ds18b20IO = 1;      //拉高总线
    Ds18b20InputInitial();//设置IO输入
    while((Ds18b20IO != 0)&&(Flag_1 == 1))//等待ds18b20响应,具有防止超时功能
    {                                      //等待约60ms左右
        CONT_1++;
        Ds18b20Delay(10);
        if(CONT_1 > 8000)Flag_1 = 0;
        Status = Ds18b20IO;
    }
    Ds18b20OutputInitial();
    Ds18b20IO = 1;
    Ds18b20Delay(100);
    return Status;       //返回初始化状态
}

void Ds18b20Write(unsigned char infor)
{
    unsigned int i;
    Ds18b20OutputInitial();
    for(i=0;i<8;i++)
    {
        if((infor & 0x01))
        {
            Ds18b20IO = 0;
            Ds18b20Delay(6);
            Ds18b20IO = 1;
            Ds18b20Delay(50);
        }
        else
        {
            Ds18b20IO = 0;
            Ds18b20Delay(50);
            Ds18b20IO = 1;
            Ds18b20Delay(6);
        }
        infor >>= 1;
    }
}

unsigned char Ds18b20Read(void)
{
    unsigned char Value = 0x00;
    unsigned int i;
    Ds18b20OutputInitial();
    Ds18b20IO = 1;
    Ds18b20Delay(10);
    for(i=0;i<8;i++)
    {
        Value >>= 1; 
        Ds18b20OutputInitial();
        Ds18b20IO = 0;// 给脉冲信号
        Ds18b20Delay(3);
        Ds18b20IO = 1;// 给脉冲信号
        Ds18b20Delay(3);
        Ds18b20InputInitial();
        if(Ds18b20IO == 1) Value |= 0x80;
        Ds18b20Delay(15);
    } 
    return Value;
}

//温度读取函数
unsigned char ReadDs18B20(void) 
{
    unsigned char V1,V2;   //定义高低8位 缓冲
    unsigned char temp;    //定义温度缓冲寄存器
    
    Ds18b20Initial();
    Ds18b20Write(0xcc);    // 跳过读序号列号的操作
    Ds18b20Write(0x44);    // 启动温度转换
    
    Ds18b20Initial();
    Ds18b20Write(0xcc);    //跳过读序号列号的操作 
    Ds18b20Write(0xbe);    //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
    
    V1 = Ds18b20Read();    //低位
    V2 = Ds18b20Read();    //高位
    temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据 

    return temp;
}

//温度读取函数 带1位小数位
float floatReadDs18B20(void) 
{
    unsigned char V1,V2;   //定义高低8位 缓冲
    unsigned int temp;     //定义温度缓冲寄存器
    float fValue;
    Ds18b20Initial();
    Ds18b20Write(0xcc);    // 跳过读序号列号的操作
    Ds18b20Write(0x44);    // 启动温度转换
    
    Ds18b20Initial();
    Ds18b20Write(0xcc);    //跳过读序号列号的操作 
    Ds18b20Write(0xbe);    //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
    
    V1 = Ds18b20Read();    //低位
    V2 = Ds18b20Read();    //高位
    //temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据 
    temp=V2*0xFF+V1;
    fValue = temp*0.0625;
    
    return fValue;
}

ds18b20.h

#ifndef __DS18B20_H__
#define __DS18B20_H__
#include"iocc2530.h"

extern unsigned char Ds18b20Initial(void);
unsigned char ReadDs18B20(void);
float floatReadDs18B20(void);
#endif

main.c


/****************************************************************************
* 描    述: 设置串口调试助手波特率:115200bps 8N1
*           DS18B20采集的温度通过串口传给电脑显示
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "ds18b20.h"  
#include "LCD.h"

typedef unsigned char uchar;
typedef unsigned int  uint;
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr)[0])
#define FLOAT_TEMP      1          //输出更高精度时打开此注释

extern void Delay_ms(unsigned int k);//外部函数ms的声明

/****************************************************************************
* 名    称: InitCLK()
* 功    能: 设置系统时钟源
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitCLK()
{
    CLKCONCMD &= ~0x40;             //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);        //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;             //设置系统主时钟频率为32MHZ   
}

/****************************************************************************
* 名    称: InitUart()
* 功    能: 串口初始化函数
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitUart()
{
    PERCFG = 0x00;                  //位置1 P0口
    P0SEL = 0x0c;                   //P0用作串口
    P2DIR &= ~0xc0;                 //P0优先作为UART0 
    U0CSR |= 0x80;                  //串口设置为UART方式
    U0GCR |= 8;
    U0BAUD |= 59;                  //波特率设为115200
    U0CSR |= 0x40;                  //UART接收器使能
    UTX0IF = 0;                     //UART0 TX中断标志初始置位0
}

/****************************************************************************
* 名    称: UartSendString()
* 功    能: 串口发送函数
* 入口参数: Data:发送缓冲区   len:发送长度
* 出口参数: 无
****************************************************************************/
void UartSendString(char *Data, int len)
{
    uint i;
    
    for(i=0; i<len; i++)
    {
        U0DBUF = *Data++;
        while(UTX0IF == 0);
        UTX0IF = 0;
    }
}

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main()
{
    char str[9]="DS18B20:";
    char strTemp[30];
    float fTemp;

    
    InitCLK();                      //设置系统时钟源
    InitUart();                     //串口初始化
    P0SEL &= 0x7f;                  //DS18B20的io口初始化
    
    LCD_Init();                 //oled 初始化  
    LCD_CLS();                  //屏全亮 
    LCD_welcome();
    
    while(1)
    {        
        memset(strTemp, 0, ARRAY_SIZE(strTemp)); 

//厂家提供的程序温度值不带小数,Ds18B20本身是支持1位小数位的,修改后使其支持,精度更高        
#if defined(FLOAT_TEMP)                 
        fTemp = floatReadDs18B20();       //温度读取函数 带1位小数位
        sprintf(strTemp, "%s%.01f", str, fTemp); //将浮点数转成字符串  
        UartSendString(strTemp, strlen(strTemp));       //通过串口发送温度值到电脑显示
#else       
        ucTemp = ReadDs18B20();           //温度读取函数
//        strTemp[0] = ucTemp/10+48;        //取出十位数
//        strTemp[1] = ucTemp%10+48;        //取出个位数
        sprintf(strTemp, "%s%d%d", str, ucTemp/10, ucTemp%10);
        UartSendString(strTemp, strlen(strTemp));       //通过串口发送温度值到电脑显示
#endif 
        LCD_P8x16Str(0, 5, (unsigned char*)strTemp);
        UartSendString("\r\n", 2);          // 回车换行     
        Delay_ms(1000);                   //延时函数使用定时器方式
    }
}
  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2024-03-17 21:34
    关注

    Origin______ 晚上好🌙🌙🌙
    本答案参考ChatGPT-3.5

    问题:基于cc2530获取ds18b20温度值,串口调试一直显示的DS18B20:4080.0,是什么原因呢?如何解决呢?

    原因:

    • DS18B20传感器未正确初始化。
    • 读取温度值的代码逻辑错误。

    解决方案:

    1. 确保DS18B20传感器的引脚连接正确,并且在代码中正确定义引脚。
    2. 确保在读取温度值之前先进行DS18B20传感器的初始化。
    3. 修改温度读取函数中的转换逻辑,确保正确计算温度值。

    修改后的代码如下:

    // ds18b20.c
    #include "ds18b20.h"
    
    #define Ds18b20IO P0_4 // 温度传感器引脚
    
    void Delay_us(unsigned int k)//us延时函数
    {
        // 省略部分代码
    
    }
    
    void Delay_ms(unsigned int k)
    {
        // 省略部分代码
    }
    
    void Delay_s(unsigned int k)
    {
        // 省略部分代码
    }
    
    // 时钟频率为32M
    void Ds18b20Delay(unsigned int k)
    {
        // 省略部分代码
    }
    
    void Ds18b20InputInitial(void)//设置端口为输入
    {
        P0DIR &= 0x7f;
    }
    
    void Ds18b20OutputInitial(void)//设置端口为输出
    {
        P0DIR |= 0x80;
    }
    
    // ds18b20初始化 初始化成功返回0x00,失败返回0x01
    unsigned char Ds18b20Initial(void)
    {
        unsigned char Status = 0x00;
        unsigned int CONT_1 = 0;
        unsigned char Flag_1 = 1;
        Ds18b20OutputInitial();
        Ds18b20IO = 1; //DQ复位
        Ds18b20Delay(260); //稍做延时
        Ds18b20IO = 0; //单片机将DQ拉低
        Ds18b20Delay(750); //精确延时 大于 480us 小于960us
        Ds18b20IO = 1; //拉高总线
        Ds18b20InputInitial();//设置IO输入
        while((Ds18b20IO != 0)&&(Flag_1 == 1))//等待ds18b20响应,具有防止超时功能
        {
            //等待约60ms左右
            CONT_1++;
            Ds18b20Delay(10);
            if(CONT_1 > 8000)
                Flag_1 = 0;
            Status = Ds18b20IO;
        }
        Ds18b20OutputInitial();
        Ds18b20IO = 1;
        Ds18b20Delay(100);
        return Status; //返回初始化状态
    }
    
    void Ds18b20Write(unsigned char infor)
    {
        // 省略部分代码
    }
    
    unsigned char Ds18b20Read(void)
    {
        // 省略部分代码
    }
    
    // 温度读取函数
    unsigned char ReadDs18B20(void)
    {
        unsigned char V1,V2; //定义高低8位 缓冲
        unsigned char temp; //定义温度缓冲寄存器
        Ds18b20Initial();
        Ds18b20Write(0xcc); // 跳过读序号列号的操作
        Ds18b20Write(0x44); // 启动温度转换
        Ds18b20Initial();
        Ds18b20Write(0xcc); //跳过读序号列号的操作
        Ds18b20Write(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
        V1 = Ds18b20Read(); //低位
        V2 = Ds18b20Read(); //高位
        temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据
        return temp;
    }
    
    // 温度读取函数 带1位小数位
    float floatReadDs18B20(void)
    {
        unsigned char V1,V2; //定义高低8位 缓冲
        unsigned int temp; //定义温度缓冲寄存器
        float fValue;
        Ds18b20Initial();
        Ds18b20Write(0xcc); // 跳过读序号列号的操作
        Ds18b20Write(0x44); // 启动温度转换
        Ds18b20Initial();
        Ds18b20Write(0xcc); //跳过读序号列号的操作
        Ds18b20Write(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
        V1 = Ds18b20Read(); //低位
        V2 = Ds18b20Read(); //高位
        temp = (V2 << 8) | V1;
        fValue = temp * 0.0625;
        return fValue;
    }
    
    // ds18b20.h
    #ifndef __DS18B20_H__
    #define __DS18B20_H__
    
    extern unsigned char Ds18b20Initial(void);
    unsigned char ReadDs18B20(void);
    float floatReadDs18B20(void);
    
    #endif
    
    // main.c
    #include <stdio.h>
    #include <string.h>
    #include "ds18b20.h"
    #include "LCD.h"
    
    typedef unsigned char uchar;
    typedef unsigned int uint;
    #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr)[0])
    #define FLOAT_TEMP 1 //输出更高精度时打开此注释
    
    extern void Delay_ms(unsigned int k);//外部函数ms的声明
    
    // 省略部分代码
    
    int main(void)
    {
        // 省略部分代码
    
        while(1)
        {
            uchar temp;
    
            temp = ReadDs18B20();
            // 温度值显示
            #ifdef FLOAT_TEMP
            float fTemp = floatReadDs18B20();
            printf("DS18B20: %f\n", fTemp);
            #else
            printf("DS18B20: %d\n", temp);
            #endif
    
            Delay_ms(1000);
        }
    
        // 省略部分代码
    }
    

    你可以根据实际情况调整代码中的延时时间和其他相关配置。注意,如果希望输出更高精度的温度值,可以将代码中的#define FLOAT_TEMP 1取消注释,并使用floatReadDs18B20函数读取温度值。

    希望对你有帮助!

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月22日
  • 创建了问题 3月17日