標(biāo)題:
DS18B20+52單片機(jī)+溫度報警+4位數(shù)碼管顯示程序
[打印本頁]
作者:
赤子
時間:
2018-6-25 09:31
標(biāo)題:
DS18B20+52單片機(jī)+溫度報警+4位數(shù)碼管顯示程序
#include <reg52.h>
#include<intrins.h>
#define TH0HIGH 0xe1
#define TL0LOWW 0xa7
#define LOW 0
#define HIGH 1
#define DIS_DAT P0
#define DIS_POS P2 //數(shù)碼管只用到低四位
#define NOP() _nop_()
#define false 0
#define FALSE 0
#define true 1
#define TRUE 1
#define uint unsigned int
extern unsigned char idata flag; //定義外部變量,溫度正負(fù)標(biāo)志
uint HNum = 50,LNum = 10; //報警溫度的高低值
uint Tem;
void delay_16us();
void SetLowTem();
void SetHighTem();
void initalarm();
void alarm();
void delay_ms(uint timer);
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
typedef signed char s8;
typedef signed int s16;
typedef signed long s32;
typedef bit BOOL;
void delay_16us(u16 us);
void init_various(void);
void dynamic_display(void);
float set_temp_data(void);
u8 ds18b20_reset(void);
void ds18b20_write_byte(u8 wByte);
u8 ds18b20_read_byte(void);
u16 ds18b20_get_temp(void);
BOOL b10msEvent;
BOOL b500msEvent;
sbit k1 = P3^0;
sbit k2 = P3^1;
sbit k3 = P3^2;
sbit k4 = P3^3;
sbit led1 = P1^0;
sbit led2 = P1^1;
sbit led3 = P1^2;
sbit buzzer = P3^7;
sbit DQ_PIN = P3^6;//管腳定義
code u8 float_tab[16] = {0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//小數(shù)表
code u8 DisCode[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xff, 0xbf};
u8 DisNum[4] = {0x0a, 0x0a, 0x00, 0x00};
u8 DisPosition = 0;
void delay_16us(u16 us) //(14 + 16 * us) 微秒
{
while(--us);
}
void init_c51(void)
{
TMOD = 0x01;
TH0 = TH0HIGH;
TL0 = TL0LOWW;
ET0 = 1;
TR0 = 1;
}
void init_various(void)
{
EA = 0;
init_c51();
ds18b20_reset();
ds18b20_get_temp();
EA = 1;
}
void dynamic_display(void)
{
static u8 DisPinOn = 0x01;
DisPinOn <<= 1;//DisPinON位選
if(DisPinOn == 0x10)
{
DisPosition = 0;
DisPinOn = 0x01;
}
DIS_DAT = 0xff;
DIS_POS = DisPinOn;
DIS_DAT = DisCode[DisNum[DisPosition++]];
if(DisPinOn == 0x04)
DIS_DAT &= 0x7f;
}
void SetHighTem()//函 數(shù):設(shè)置高溫溫度報警值函數(shù)
{
HNum = 50;
if(k1 == 0) //按鍵消抖
delay_ms(10);
if(k1 == 0)
{ while(!k1); //等待按鍵釋放
while(1)
{
dynamic_display();
if(k1 == 0)
delay_ms(50); //按鍵消抖
if(k1 == 0)
{ while(!k1); //等待按鍵釋放
SetLowTem(); //設(shè)置低溫報警溫度
break;
}
if(k2 == 0)
delay_ms(50); //按鍵消抖
if(k2 == 0)
{ while(!k2); //等待按鍵釋放
HNum++;
}
if(k3 == 0)
delay_ms(50); //按鍵消抖
if(k3 == 0)
{ while(!k3); //等待按鍵釋放
HNum--;
}
if(k4 == 0)
delay_ms(50); //按鍵消抖
if(k4 == 0)
{ while(!k4); //等待按鍵釋放
break;
}
}
}
dynamic_display();
}
void SetLowTem()//函 數(shù):設(shè)置低溫溫度報警值函數(shù)
{
while(1)
{
dynamic_display();
if(k2 == 0)
delay_ms(50); //按鍵消抖
if(k2 == 0)
{ while(!k2); //等待按鍵釋放
LNum++;
}
if(k3 == 0)
delay_ms(50); //按鍵消抖
if(k3 == 0)
{ while(!k3); //等待按鍵釋放
LNum--;
}
if(k4 == 0)
delay_ms(50); //按鍵消抖
if(k4 == 0)
{ while(!k4); //等待按鍵釋放
break;
}
}
}
float set_temp_data(void)
{
u16 TempData;
float Temp;
u8 Negative;
s8 i;
float j;
TempData = ds18b20_get_temp(); //度溫度數(shù)據(jù)
/* 小于零 */
if(TempData & 0xf000)
{
TempData = ~TempData + 1;
TempData &= 0x0fff;
Negative = 1;
}
/* 大于零 */
else
{
Negative = 0;
}
Temp = (TempData >> 4) * 10; //溫度讀數(shù)乘以精度(0.0625),顯示小數(shù)點(diǎn)一位,所以乘以10
j=Temp;
Temp = Temp + float_tab[(TempData & 0x000f)] + 0.5; //加上小數(shù)部分,四舍五入所以加0.5
TempData = Temp;
for(i=3; i>=0; i--)//循環(huán)4次,分別顯示小,個,十,百
{
DisNum[i] = TempData % 10;
TempData /= 10;
}
for(i=0; i<2; i++)
{
if(DisNum[i] != 0)
{
break;
}
else
{
DisNum[i] = 0x0a; //前面為0不顯示
}
}
/* 顯示負(fù)號 */
if(Negative == 1)
{
for(i=2; i>=0; i--)
{
if(DisNum[i] == 0x0a)
{
DisNum[i] = 0x0b; //'-'
break;
}
}
}
return j;
}
u8 ds18b20_reset(void)
{
DQ_PIN = HIGH;
delay_16us(1);
DQ_PIN = LOW;
delay_16us(30); //延時600us
DQ_PIN = HIGH;
delay_16us(5); //延時80us
if(!DQ_PIN)
{
delay_16us(30); //延時420us
return 1;
}
else
return 0;
}
void ds18b20_write_byte(u8 wByte)
{
u8 i;
for(i=0; i<8; i++)
{
DQ_PIN = LOW;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
DQ_PIN = wByte & 0x01;
NOP();
NOP();
NOP();
NOP();
NOP();
DQ_PIN = HIGH;
NOP();
NOP();
NOP();
wByte >>= 1;
}
}
u8 ds18b20_read_byte(void)
{
u8 rByte;
u8 i;
for(i=0; i<8; i++)
{
DQ_PIN = LOW;
NOP();
NOP();
rByte >>= 1;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
DQ_PIN = HIGH;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
if(DQ_PIN)
rByte |= 0x80;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
}
DQ_PIN = HIGH;
return rByte;
}
u16 ds18b20_get_temp(void)
{
u16 Temp;
if(ds18b20_reset() == 0) //復(fù)位
return 0;
ds18b20_write_byte(0xcc); //忽略ROM
ds18b20_write_byte(0x44); //發(fā)送溫度轉(zhuǎn)化命令
delay_16us(30);
if(ds18b20_reset() == 0) //再次復(fù)位
return 0;
ds18b20_write_byte(0xcc); //忽略ROM
ds18b20_write_byte(0xbe);
Temp = ds18b20_read_byte();
Temp |= ds18b20_read_byte() << 8;
return Temp;
}
void main()
{
initalarm();
init_various();
while(1)
{
alarm();
SetHighTem();
if(b10msEvent)
{
b10msEvent = false;
dynamic_display(); //顯示
if(b500msEvent)
{
b500msEvent = false;
set_temp_data(); //讀溫度
}
}
}
}
void timer0(void) interrupt 1
{
static u8 SecCount = 0;
TH0 = TH0HIGH;
TL0 = TL0LOWW;
b10msEvent = true; //10毫秒中斷
if(++SecCount == 50)
{
SecCount = 0;
b500msEvent = true; //1秒到時
}
}
void delay_ms(uint timer)
{
uint i,j;
for(i=0; i<timer; i++)
for(j=0; j<110; j++);
}
void initalarm()//led和蜂鳴器初始化
{
led1 = 0;
led2 = 0;
led3 = 0;
buzzer = 1;
}
void alarm()//函 數(shù):led和蜂鳴器控制
{
Tem = set_temp_data();
if(Tem > HNum)
{
led2 = 1;
led1 = 0;
led3 = 0;
buzzer = 0; //蜂鳴器工作
}
else if(Tem < LNum)
{
led3 = 1;
led1 = 0;
led2 = 0;
buzzer = 0;
}
else
{
led1 = 1;
led2 = 0;
led3 = 0;
buzzer = 1;
}
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1