找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1841|回复: 5
收起左侧

关于stm32单片机ds18b20负温度显示程序

[复制链接]
ID:1062898 发表于 2023-2-13 15:27 | 显示全部楼层 |阅读模式
我用stm32 ds18b20 四位数码管显示,测量冻肉的温度是负的。但是把冻肉拿开测量大气温度的时候,负号就去不掉了。
请各位大佬帮我看看到底怎么回事

#include "74hc595.h"
#include "SysTick.h"
#include "ds18b20.h"
u8 fg=1;
u16 sdata;
unsigned char xiaoshu1;                //小数第一位
unsigned char xiaoshu2;                //小数第二位
unsigned char xiaoshu;                //两位小数

u8 LED_table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳数码管段码“0123456789-”

u8 LED_table_dp[16]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};


u8 wei_table[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//第一位至第八位位码

void HC595_GPIO_Configuration(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        
        GPIO_InitStructure.GPIO_Pin = SCL | RCL | DIO;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(SMG_PROT, &GPIO_InitStructure);
        
        GPIO_SetBits(SMG_PROT,SCL);
        GPIO_SetBits(SMG_PROT,RCL);
        GPIO_SetBits(SMG_PROT,DIO);
}
void HC595_Send_Byte(unsigned char byte)
{
        u8 i;
        
        for(i = 0; i < 8; i++)
        {
                if(byte & 0x80)
                        DIO_HIGH;
                else
                        DIO_LOW;
               
                SCL_LOW;
                delay_us(10);
                SCL_HIGH;
                delay_us(10);
               
                byte <<= 1;
        }
}
void DS18B20_UserConfig()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStructure.GPIO_Mode    =  GPIO_Mode_Out_PP;//推挽输出是GPIO_Mode_Out_PP
    GPIO_InitStructure.GPIO_Pin     =  DS18B20;//定义管脚
    GPIO_InitStructure.GPIO_Speed   =  GPIO_Speed_10MHz;
    GPIO_Init(DS18B20_PROT,&GPIO_InitStructure);

    //GPIO_ResetBits(SMG_PROT,SCL|RCL|DIO);

}

//输入输出模式选择函数
void Output_Input_Mode(u8 cmd)
{
        
        GPIO_InitTypeDef GPIO_InitStructure;//定义结构体
        
        if(cmd)
    {//1:输出模式
        
        GPIO_InitStructure.GPIO_Pin = DS18B20;//PB0
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;//端口输出速率
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
        }
        else
    {//0:输入模式
               
        GPIO_InitStructure.GPIO_Pin = DS18B20;//PB0
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉模式
        }
        GPIO_Init(DS18B20_PROT,&GPIO_InitStructure);//初始串口
}

//启动信号 判断是否成功
u8 DS18B20_Start_Signal(void)
{

        u8 data;
        
        //写
        Output_Input_Mode(1);//输入模式
        DS18B20_LOW;
        delay_us(480);
        DS18B20_HIGH;
        delay_us(30);
        
        //读引脚状态 1:DS18B20失败 0:DS18B20成功
        Output_Input_Mode(0);//输出模式
        data = GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20);//读取输入状态  60~240us
        delay_us(200);//200us  480+30+240=750  960-750=210  取200us即可
        
        return data;
}

//向DS18B20写数据
//写:输出模式 1
void DS18B20_Write_Byte(u8 data)
{
        

        for(u8 i=0;i<8;i++){
               
                Output_Input_Mode(1);
                DS18B20_LOW;
                delay_us(2);
               
                ((data&0x01)) ? DS18B20_HIGH : DS18B20_LOW;//DS18B20 低位先出,故&0x01
                delay_us(45);
                DS18B20_HIGH;//拉高总线

                data>>=1;//数据右移八次 既完成写8bit数据
        }
}

//读DS18B20数据
//读:输入模式 0
u8 DS18B20_Read_Byte(void)
{

        u8 data=0;
        
        for(u8 i=0;i<8;i++){
               
                data>>=1;
                Output_Input_Mode(1);
                DS18B20_LOW;
                delay_us(2);
                DS18B20_HIGH;//拉高总线
               
                Output_Input_Mode(0);
                if(GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20) == SET){
                        
                        data |= 0x80;//从高位开始
                }
                        delay_us(45);
        }
        return data;
}

//获取温度值
void DS18B20_Read_Temperature()
{
        
        u8 LSB = 0,MSB = 0;
        u16 temp=0;
        //温度转换
        DS18B20_Start_Signal();
        DS18B20_Write_Byte(0xcc);//跳过ROM
        DS18B20_Write_Byte(0x44);//温度变换
        //delay_ms(750);
        //12位精度 750ms  数码管本身有延时,故这个延时可以去掉
        
        //读取寄存器
        DS18B20_Start_Signal();
        DS18B20_Write_Byte(0xcc);//跳过ROM
        DS18B20_Write_Byte(0xbe);//读暂存存储器
        
        LSB =  DS18B20_Read_Byte();//读出温度的低位LSB
        MSB =  DS18B20_Read_Byte();//读出温度的高位MSB
        if(MSB>0x7f)
    {
        LSB=~LSB+1;
        MSB=~MSB;
        fg=0;

    }
        sdata = LSB/16+MSB*16;              //整数部分
        xiaoshu1 = (LSB&0x0f)*10/16;                 //小数第一位
        xiaoshu2 = (LSB&0x0f)*100/16%10;        //小数第二位
        xiaoshu=xiaoshu1*10+xiaoshu2;                 //小数两位
}
void SMG_Display(u16 data)
{
    if(fg==1)
    {
        HC595_Send_Byte(LED_table[data/10]);//送出段码
        HC595_Send_Byte(wei_table[3]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);

        HC595_Send_Byte(LED_table_dp[data%10]);//送出段码
        HC595_Send_Byte(wei_table[2]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);

        HC595_Send_Byte(LED_table[xiaoshu1]);//送出段码
        HC595_Send_Byte(wei_table[1]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);

        HC595_Send_Byte(LED_table[xiaoshu2]);//送出段码
        HC595_Send_Byte(wei_table[0]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);
    }
    if(fg==0)
    {
        HC595_Send_Byte(LED_table[11]);//送出段码
        HC595_Send_Byte(wei_table[3]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);

        HC595_Send_Byte(LED_table[data/10]);//送出段码
        HC595_Send_Byte(wei_table[2]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);

        HC595_Send_Byte(LED_table_dp[data %10]);//送出段码
        HC595_Send_Byte(wei_table[1]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);

        HC595_Send_Byte(LED_table[xiaoshu1]);//送出段码
        HC595_Send_Byte(wei_table[0]);//送出位码
        RCL_LOW;
        RCL_HIGH;
        delay_ms(1);

    }

}

void main()
{
    SystemInit();
    SysTick_Init(72);
    HC595_GPIO_Configuration();
    DS18B20_UserConfig();
    while(1)
    {
       DS18B20_Read_Temperature();
       SMG_Display(sdata);
    }
}



回复

使用道具 举报

ID:883242 发表于 2023-2-13 19:53 | 显示全部楼层
只有fg=0;
没有fg=1;
回复

使用道具 举报

ID:1034262 发表于 2023-2-13 21:13 | 显示全部楼层
程序太长没空看,只给出提示:每次刷新显示都要连符号一起刷新。
回复

使用道具 举报

ID:596109 发表于 2023-2-14 08:41 | 显示全部楼层
       if(MSB>0x7f)     {         LSB=~LSB+1;         MSB=~MSB;         fg=0;      }//这段函数加上温度为正的时候fg=1
回复

使用道具 举报

ID:629502 发表于 2023-2-14 09:29 | 显示全部楼层
显示没看出啥问题,标志位赋值时没看到fg=1
回复

使用道具 举报

ID:584195 发表于 2023-2-14 16:25 | 显示全部楼层
你开调试模式进去,看看测的温度是不是对的。
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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