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