我用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);
}
}
|