① 用51單片機實現溫度報警器的程序,要正確的
/*使用舉例:數碼管
scan()
{
char k;
for(k=0;k<4;k++) //4位LED掃描控制
{
discan=0x00;
Disdata=dis_7[_1820display[k]]; //數據顯示
if (k==1){DIN=0;} //小數點顯示
discan=scan_con[k]; //位選
_18B20_delay(100);
}
}
main()
_18B20_init();//18B20初始化
while(1)
{
EA=0;//在利用18B20測試溫度時,要嚴格遵循時序,禁止一切中斷
_18B20_work(_18B20_read()); //處理溫度數據
EA=1;//測試完畢,恢復系統中斷
scan(); //顯示溫度值
}
*/
#include "intrins.h" //_nop_();延時函數用
//*****************//
//以下是DS18B20驅動程序
//*****************//
/**************************************************
** 功能描述: DS18B20驅動程序,使用12M晶體
** DQ佔用引腳資源P1^7
****************************************************/sbit DQ=P1^7; //溫度輸入口unsigned char data temp_data[2]={0x00,0x00}; //讀出溫度暫放
unsigned char data _1820display[5]={0x00,0x00,0x00,0x00,0x00}; //顯示單元數據,共4個數據和一個運算暫用
unsigned int temp;
//**************溫度小數部分用查表法***********//
unsigned char code ditab[16]=
{
0x00,0x01,0x01,0x02,
0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,
0x08,0x08,0x09,0x09
};/*****************11us延時函數*************************/
//
void _18B20_delay(unsigned int t)
{
for (;t>0;t--);
}/****************DS18B20復位函數************************/
_18B20_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;
_nop_();_nop_();//從高拉倒低
DQ=0;
_18B20_delay(50); //550 us
DQ=1;
_18B20_delay(6); //66 us
presence=DQ; //presence=0 復位成功,繼續下一步
}
_18B20_delay(45); //延時500 us
presence=~DQ;
}
DQ=1; //拉高電平
}/****************DS18B20寫命令函數************************/
//向1-WIRE 匯流排上寫1個位元組
void _18B20_write(unsigned char val)
{
unsigned char i;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();_nop_(); //從高拉倒低
DQ=0;
_nop_();_nop_();_nop_();_nop_(); //5 us
DQ=val&0x01; //最低位移出
_18B20_delay(6); //66 us
val=val/2; //右移1位
}
DQ=1;
_18B20_delay(1);
}/****************DS18B20讀1位元組函數************************/
//從匯流排上取1個位元組
unsigned char _18B20read_byte(void)
{
unsigned char i;
unsigned char value=0;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();_nop_(); //從高拉倒低
value>>=1;
DQ=0;
_nop_();_nop_();_nop_();_nop_(); //4 us
DQ=1;
_nop_();_nop_();_nop_();_nop_(); //4 us
if(DQ)value|=0x80;
_18B20_delay(6); //66 us
}
DQ=1;
return(value);
}
_18B20_read() //讀出溫度函數
{
_18B20_reset(); //匯流排復位
_18B20_delay(200);
_18B20_write(0xcc); //發命令
_18B20_write(0x44); //發轉換命令
_18B20_reset();
_18B20_delay(1);
_18B20_write(0xcc); //發命令
_18B20_write(0xbe);
temp_data[0]=_18B20read_byte(); //讀溫度值的低位元組
temp_data[1]=_18B20read_byte(); //讀溫度值的高位元組
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0]; // 兩位元組合成一個整型變數。
return temp; //返回溫度值
}/****************溫度數據處理函數************************///二進制高位元組的低半位元組和低位元組的高半位元組組成一位元組,這個
//位元組的二進制轉換為十進制後,就是溫度值的百、十、個位值,而剩
//下的低位元組的低半位元組轉化成十進制後,就是溫度值的小數部分/********************************************************/
_18B20_work(unsigned int tem)
{
unsigned char n=0;
if(tem>6348) // 溫度值正負判斷
{
tem=65536-tem;
n=1;
} // 負溫度求補碼,標志位置1
_1820display[4]=tem&0x0f; // 取小數部分的值
_1820display[0]=ditab[_1820display[4]]; // 存入小數部分顯示值
_1820display[4]=tem>>4; // 取中間八位,即整數部分的值
_1820display[3]=_1820display[4]/100; // 取百位數據暫存
_1820display[1]=_1820display[4]%100; // 取後兩位數據暫存
_1820display[2]=_1820display[1]/10; // 取十位數據暫存
_1820display[1]=_1820display[1]%10;
/******************數碼管符號位顯示判斷**************************/
if(!_1820display[3])
{
_1820display[3]=0x0a; //最高位為0時不顯示
if(!_1820display[2])
_1820display[2]=0x0a; //次高位為0時不顯示
}
if(n)
_1820display[3]=0x0b; //負溫度時最高位顯示"-"
}
/******************1602液晶符號位顯示判斷**************************/
if(!_1820display[3])
{
_1820display[3]=' '-'0'; //最高位為0時不顯示
if(!_1820display[2])
_1820display[2]=' '-'0'; //次高位為0時不顯示
}
if(n)
_1820display[3]='-'-'0'; //負溫度時最高位顯示"-"
} _18B20_init()//18B20初始化
{
_18B20_reset(); //開機先轉換一次
_18B20_write(0xcc); //Skip ROM
_18B20_write(0x44); //發轉換命令
}
② 求單片機控制溫度感測器,LCD顯示溫度值,溫度達到30度時,蜂鳴器報警的報警程序
這個有現成的,樓主可以省很多力氣了,請在網上下一個proteusv7.8,里邊程序,模擬電路都有。
樓主把兩個程序中和一下就可以了。
改起來也不難,自己弄哦。
我受點累,樓主可以這樣改:
1.1602引腳挪到P2口,及P3口,程序也要改哈,編譯運行,這個非常簡單。
2.再把1602剪下,粘貼到18b20那張圖上;1602的程序也粘貼到18b20程序上,改掉標號重復的地方,改掉初始化程序。將18b20的結果顯示在LCD上,如有必要,刪除7段數碼管程序。
③ 您好!如何用51單片機顯示DS18b20溫度感測器的溫度變化,並通過藍牙HC08傳送數據給電腦代碼有點難。
你好!
藍牙通訊,是在串口通訊基礎之上完成的,
先完成單片機驅動溫度感測器,實現DS18B20的讀取,
再進行串口通訊,實現和電腦串口收發數據,
加上藍牙模塊,實現無線傳輸
④ 求單片機程序關於溫濕度。感測器採用DHT11,按鍵四個可以設置溫濕度的上下限,顯示用lcd1602,超限報警
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned char unint8; //unint8 代替undigned char 提高可移植性
typedef unsigned char unint16;
unsigned char str1[]={" "};
unsigned char str2[]={" "};
unsigned char code dis1[] = {" Xh RH: "}; //定義數組
unsigned char code dis2[] = {" DO T: "};
sbit buz=P1^0;
sbit TRH = P1^7;//溫濕度感測器DHT11數據接入
sbit LCD_RS = P1^1;
sbit LCD_RW = P1^2;
sbit LCD_EN = P1^3;
unint8 TH_data,TL_data,RH_data,RL_data,CK_data;
unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
unint8 com_data,untemp,temp;
unint8 respond;
void initcom()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
void send(unsigned char temp)
{
//send biao zi
SBUF=temp;
while(!TI);
TI=0;
}
void sendwd()
{
//send wen
uint w_d ;
w_d=TH_data+128;
SBUF=w_d;
while(!TI);
TI=0;
}
void sendsd()
{
//send shi
SBUF=RH_data;
while(!TI);
TI=0;
}
/*********************************************************************************/
void delayNOP() //延時
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/*********************************************************************************/
/*********************************************************************************/
// 毫秒級延時子程序
/*********************************************************************************/
void delay_ms(unsigned int ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i< 150; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/*********************************************************************************/
/*********************************************************************************/
//5us級延時程序
/*********************************************************************************/
void delay_us()
{
unint8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/********************************************************************************/
/********************************************************************************/
// 測試LCD忙碌狀態
//lcd_busy()為1時,忙,等待。lcd_busy()為0時,閑,可寫指令與數據。
/********************************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************************/
/*******************************************************************************/
// 寫入指令數據到LCD
/*******************************************************************************/
void lcd_wcmd(unsigned char cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*****************************************************************************/
/*****************************************************************************/
//寫顯示數據到LCD
//RS=高電平,RW=低電平,E=高脈沖,D0-D7=數據。
/*****************************************************************************/
void lcd_wdata(unsigned char dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/****************************************************************************/
/****************************************************************************/
//LCD初始化設定
/****************************************************************************/
void lcd_init()
{
delay_ms(15);
lcd_wcmd(0x38); //16*2顯示,5*7點陣,8位數據
delay_ms(5);
lcd_wcmd(0x38);
delay_ms(5);
lcd_wcmd(0x38);
delay_ms(5);
lcd_wcmd(0x0c); //顯示開,關游標
delay_ms(5);
lcd_wcmd(0x06); //移動游標
delay_ms(5);
//lcd_wcmd(0x01); //清除LCD的顯示內容,如果屏幕過暗,可將這倆句刪除
//delay_ms(5);
}
/****************************************************************************/
/****************************************************************************/
//設定LCD顯示位置
/****************************************************************************/
void lcd_dis_pos(unsigned char pos)
{
lcd_wcmd(pos | 0x80); //數據指針=80+地址變數
}
/****************************************************************************/
/****************************************************************************/
//收發信號檢測,數據讀取
/****************************************************************************/
char receive()
{
unint8 i;
com_data=0;
for(i=0;i<=7;i++)
{
respond=2;
while((!TRH)&&respond++);
delay_us();
delay_us();
delay_us();
if(TRH)
{
temp=1;
respond=2;
while((TRH)&&respond++);
}
else
temp=0;
com_data<<=1;
com_data|=temp;
}
return(com_data);
}
/****************************************************************************/
/****************************************************************************/
//濕度讀取子程序
//溫度高8位== TL_data
//溫度低8位== TH_data
//濕度高8位== RH_data
//濕度低8位== RH_data
//校驗 8位 == CK_data
//調用的程序有 delay();, Delay_5us();,RECEIVE();
/***************************************************************************/
void read_TRH()
{
//主機拉低18ms
TRH=0;
delay_ms(18);
TRH=1;
//DATA匯流排由上拉電阻拉高 主機延時20us
delay_us();
delay_us();
delay_us();
delay_us();
//delay_us();
//delay_us();delay_us();delay_us();delay_us();
//主機設為輸入 判斷從機響應信號
TRH=1;
//判斷DHT11是否有低電平響應信號 如不響應則跳出,響應則向下運行
if(!TRH)
{
respond=2;
//判斷DHT11發出 80us 的低電平響應信號是否結束
while((!TRH)&& respond++);
respond=2;
//判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
while(TRH && respond++);
//數據接收狀態
RH_temp = receive();
RL_temp = receive();
TH_temp = receive();
TL_temp = receive();
CK_temp = receive();
TRH=1;
//數據校驗
untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
if(untemp==CK_temp)
{
RH_data = RH_temp;
RL_data = RL_temp;
TH_data = TH_temp;
TL_data = TL_temp;
CK_data = CK_temp;
}
}
//濕度整數部分
str1[0] = (char)(0X30+RH_data/10);
str1[1] = (char)(0X30+RH_data%10);
str1[2] = 0x2e; //小數點
//濕度小數部分
str1[3] = (char)(0X30+RL_data/10);
str1[5] = 0X25; //"%"
str1[6] = 0X52; //"R"
str1[7] = 0X48; //"H"
//溫度整數部分
str2[0] = (char)(0X30+TH_data/10);
str2[1] = (char)(0X30+TH_data%10);
str2[2] = 0x2e; //小數點
//溫度小數部分
str2[3] = (char)(0X30+TL_data/10);
str2[5] = 0X27; //"'"
str2[6] = 0X43; //"C"
}
/****************************************************************************/
//冬天適宜溫濕度 夏天適宜溫濕度
//濕度:30%--80% 30%--60%
//溫度:18℃--25℃ 23℃--28℃
/****************************************************************************/
void baoj()//報警函數
{
if(RH_data>=80) //濕度上限80%
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else if(RH_data<=30) //濕度下限30%
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else if(TH_data>=25) //溫度上限25℃
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else if(TH_data<=18) //溫度下限18℃
{
buz=0;
delay_ms(200);
buz=1;
delay_ms(10);
}
else
{
buz=1;
}
}
/****************************************************************************/
//主函數
//TH,TL,RH,RL分別代表溫濕度的整數和小數部分
/****************************************************************************/
void main()
{
lcd_init();
initcom();
delay_us();
while(1)
{
unsigned char i,n=0x40,m;
read_TRH();
//寫字元
for(i=0;i<=7;i++)
{
lcd_dis_pos(i); //顯示字元
lcd_wdata(dis1[i]);
lcd_dis_pos(n+i); //顯示字元
lcd_wdata(dis2[i]);
}
//寫濕度數據
m=0x08;
for(i=0;i<=7;i++)
{
lcd_dis_pos(m);
lcd_wdata(str1[i]);
m++;
}
//寫溫度數據
m=0x48;
for(i=0;i<=7;i++)
{
lcd_dis_pos(m);
lcd_wdata(str2[i]);
m++;
}
//延時
delay_ms(500);
baoj();//報警
send(0xff);//wsd flags
//delay_ms(10);
sendwd();
//delay_ms(10);
sendsd();
//delay_ms(10);
}
}
⑤ 關於C51單片機溫度報警程序的問題 誰能幫我在每段程序後加漢字解釋 及怎麼實現溫度顯示及蜂鳴器報警的
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define out P0 ;
#define INT8U unsigned char //宏定義
#define INT16U unsigned int
sbit smg1=P2^0;
sbit smg2=P2^1;
sbit smg3=P2^2;
sbit smg4=P2^3;
sbit Beep=P1^5; //蜂鳴器引腳定義
sbit led=P1^6;
sbit led1=P1^7; //設置燈光報警鍵
sbit DQ=P2^4; //ds18b20埠
void init_ds18b20(void); //ds18b20初始化子程序
void delay(uchar); //ds18b20工作延時子程序
uchar readbyte(void);//向ds18b20讀一個位元組數據
/*******************************************************************************/
void writebyte(uchar);//向ds18b20寫一個位元組數據
uint retemp();//計數變數
uchar key;
uchar a,b,c,d; //計數變數
uchar x[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uint retemp()
{
uint a,b,t;
init_ds18b20(); //初始化ds18b20
writebyte(0xcc); // 跳過讀序列號的操作
writebyte(0x44); // 啟動溫度轉換
init_ds18b20();
writebyte(0xcc); //跳過讀序號列號的操作
writebyte(0xbe); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
a=readbyte(); //讀出溫度低位LSB
b=readbyte(); //讀出溫度高位MSB
t=b; //將溫度高八位送t
t<<=8; //乘以256移到高八位
t=t|a; //高低八位組合成溫度值
if(t<0x8000) //如果溫度為正計算正溫度值
{
key=0;
t=t*0.625;
}
else //否則溫度為負,取反
{
key=1;
t=(~t+1)*0.625;
}
return(t); //返回溫度值
}
void main()
{
uint i,t;
EA = 1; //開總中斷
TMOD = 0x01; //定時器0工作方式1
TR0=1;
delay(100);
while(1)
{
t=retemp(); 讀溫度值
a=x[t/1000]; //溫度千位數
b=x[t/100%10]; //溫度百位數
c=x[t/10%10]-0x80; //溫度十位數
d=x[t%10]; //溫度個位數
if(key==1) //如果key=1
a=0xbf; //a為「負號"
if((key==0)&&(t>320)) //如果key=0 且t大於320
{
led1=0; //點亮led1
ET0=1; //開啟定時器0中斷
}
else if(t<290) //如果溫度小於290
{
led=0; //點亮led
ET0=1; //開啟定時器0中斷
}
else //否則
{
led1=1; //關閉led1
led=1; //關閉led
ET0=0; //關閉定時器0中斷
}
for(i=0;i<50;i++) //循環50次
{smg1=1;P0=a;delay(100);smg1=0; //顯示千位
smg2=1;P0=b;delay(100);smg2=0; //顯示百位
smg3=1;P0=c;delay(100);smg3=0; //顯示十位
smg4=1;P0=d;delay(100);smg4=0; //顯示個位
}
}
}
/*ds18b20工作延時子程序*/
void delay (uchar i)
{
do
{_nop_();
_nop_();
_nop_();
i--;
}
while(i);}
/*ds18b20初始化子程序*/
void init_ds18b20()
{
uchar x=0;
DQ=0; //單片機將DQ拉低
delay (120);
DQ=1; //拉高匯流排
delay(16);
delay(80);
}
/*讀一個位元組*/
uchar readbyte ()
{uchar i=0,date=0;
for(i=8;i>0;i--)
{
DQ=0; // 給脈沖信號
delay(1);
DQ=1; // 給脈沖信號
date>>=1;
if(DQ)date|=0x80;
delay(11);
}
return(date);
}
/*寫一個位元組*/
void writebyte(uchar dat)
{uchar i=0;
for(i=8;i>0;i--) //寫8位數
{
DQ=0;
DQ=dat&0x01; //寫dat的D0位
delay(12);
DQ=1;
dat>>=1;
delay(5);
}
}
/**************************************************
*函數名:中斷函數
*描 述:產生矩形脈沖使蜂鳴器發聲
**************************************************/
void BeepTimer0(void) interrupt 1
{
Beep = ~Beep;
TH0 = 65335 / 256; //定時器賦初值
TL0 = 65335 % 256;
}
⑥ 51單片機藍牙模塊讀取溫度
51單片機藍牙模塊讀取溫度為18B20。51單片機採集18B20文都感測器數據,並經過藍牙連續發送,藍牙溫度計是接收5位數據的,可在手機上接收。