用DS18B20做的电子温度计,非常简单。
#include reg51.h
#include\"AscLed.h\"
#include intrins.h
#include stdio.h
//********************************************************
#define Seck (500/TK) //1秒中的主程序的系数
#define OffLed (Seck*5*60) //自动关机的时间5分钟!
//********************************************************
#if (FHz==0)
#define NOP_2uS_nop_()
#else
#define NOP_2uS_nop_();_nop_()
#endif
//**************************************
#define SkipK 0xcc //跳过命令
#define ConvertK 0x44 //转化命令
#define RdDs18b20K 0xbe //读温度命令
//*******************************************
extern LedOut(void);
//*************************************************
sbit PNP1=P3^4;
sbit PNP2=P3^5;
sbit BEEP=P3^2;
//***********************************
#defineDQ PNP2 //原来的PNP2 BEEP
//***********************************
static unsigned char Power=0;
//************************************
union{
unsigned char Temp[2]; //单字节温度
unsigned int Tt; //2字节温度
}T;
//***********************************************
typedef struct{
unsigned char Flag; //正数标志 0;1==》负数
unsigned char WenDu; //温度整数
unsigned int WenDuDot; //温度小数放大了10000
}WENDU;
//***********************************************
WENDU WenDu;
unsigned char LedBuf[3];
//----------------------------------
//功能:10us 级别延时
// n=1=== 6Mhz=14uS 12MHz=7uS
//----------------------------------
void Delay10us(unsigned char n){
do{
#if (FHz==1)
NOP_2uS;NOP_2uS;
#endif
}while(--n);
}
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n){
unsigned char i;
for(i=0;i8;i++){
DQ=0;
Delay10us(1);//延时13us 左右
DQ=n 0x01;
n=n1;
Delay10us(5);//延时50us 以上
DQ=1;
}
}
//------------------------------------
//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void){
unsigned char i;
unsigned char temp;
for(i=0;i8;i++){
temp=temp1;
DQ=0;
NOP_2uS;//延时1us
DQ=1;
NOP_2uS;NOP_2uS;//延时5us
if(DQ==0){
temp=temp0x7F;
}else{
temp=temp|0x80;
}
Delay10us(5);//延时40us
DQ=1;
}
return temp;
}
//-----------------------------------
void Init (void){
DQ=0;
Delay10us(45);//延时500us
DQ=1;
Delay10us(9);//延时90us
if(DQ){ //0001 1111b=1f
Power =0; //失败0
}else{
Power++;
DQ=1;
}
}
//----------------------------------
void Skip(void){
Write_18B20(SkipK);
Power++;
}
//----------------------------------
void Convert (void){
Write_18B20(ConvertK);
Power++;
}
//______________________________________
void Get_Ds18b20L (void){
T.Temp[1]=Read_18B20(); //读低位
Power++;
}
//______________________________________
void Get_Ds18b20H (void){
T.Temp[0]=Read_18B20(); //读高位
Power++;
}
//------------------------------------
//规范化成浮点数
// sssss111;11110000
// sssss111;1111(0.5,0.25,0.125,0.0625)
//------------------------------------
void ReadTemp (void){
unsigned char i;
unsigned intF1=0;
char j=1;
code int Code_F[]={6250,1250,2500,5000};
WenDu.Flag=0;
if (T.Temp[0] 0x80){ //负温度
T.Tt =~T.Tt+1; //取反+1=源吗 +符号S
WenDu.Flag=-1;
}
T.Tt = 4; //左移4位
WenDu.WenDu=T.Temp[0]; // 温度整数
//**************************************************
T.Temp[1]=4;
//---------------------------
for (i=0;i4;i++){ //计算小数位
F1 +=(T.Temp[1] 0x01)*Code_F;
T.Temp[1]=1;
}
WenDu.WenDuDot=F1; //温度的小数
Power=0;
}
//----------------------------------
void Delay1S (void){
static unsigned int i=0;
if (++i==Seck) {i=0ower++;}
}
//----------------------------------
void ReadDo (void){
Write_18B20(RdDs18b20K);
Power++;
}
/**********************************
函数指针定义
***********************************/
code void (code *SubTemp[])()={
Init,Skip,Convert,Delay1S,Init,Skip,ReadDo,Get_Ds18b20L,
Get_Ds18b20H,ReadTemp
};
//**************************************
void GetTemp(void){
(*SubTemp[Power])();
}
//---------------------------------------------------
//将温度显示,小数点放大了10000.
void GetBcd(void){
LedBuf[0]=WenDu.WenDu / 10;
LedBuf[1]=WenDu.WenDu % 10 +DotK;
LedBuf[2]=(WenDu.WenDuDot/1000)%10;
if(LedBuf[0]==0)LedBuf[0]=Black;
if(WenDu.Flag==0) return;
if(LedBuf[0] !=Black){
LedBuf[2]=LedBuf[1];
LedBuf[1]=LedBuf[0];
LedBuf[0]=Led_Pol; //'-'
}else{
LedBuf[0]=Led_Pol; //'-'
}
}
/*
//---------------------------------------------------
void JbDelay (void){
static long i;
if (++i=OffLed){
P1=0xff;
P2=0xff;
PCON=0x02;
}
}
*/
/*****************************************************
主程序开始
1:2002_10_1 设计,采用DS18B20测量
2:采用函数数组读取DS18B20.LED数码管显示正常!
3:改变FHz可以用6,12MHz工作!
******************************************************/
code unsigned char Stop[3] _at_ 0x3b;
void main (void){
P1=0xff;
WenDu.WenDu=0;
while (1){
GetTemp();
GetBcd();
// JbDelay();
LedOut();
}
}
复制代码
20091012_8b1ef92155560c13b5807ZmoDVSacjwD[1].jpg (12 KB)
2009-10-21 23:21 上传
下载次数:0
随着各类建筑的不断发展,建筑规模越来越大,层次越来越高,建筑的标准也越来越高。新建的各类大楼都具备人员密集、设备先进、功能多、装饰豪华等特点,因此,火灾自动报警和自动灭火系统已成为高层建筑不可缺少的重要组成部分。
本设计是以AT89C51单片机为主控芯片,用TLC1543模数转换芯片模拟烟雾浓度检测传感器,用18B20对环境温度进行实时检测,并模拟了视频监控触发开关对环境进行跟踪和报警,并配上单片机的复位电路,时钟电路,液晶显示电路等共同完成了基于单片机的大楼防火报警系统设计。
在本设计中,用protues仿真硬件电路,以keil C51作为软件仿真平台,联合调试共同完成了本系统的设计,仿真效果良好。
目 录
摘 要 1
目 录 2
第1章 绪论 3
1.1 课题研究的背景 3
1.2 课题研究的目的和意义 3
1.3 课题研究的国内外发展现状 4
第2章 大楼防火报警系统方案论证与芯片的准备 6
2.1 设计思路 6
2.2 方案论证与对比 7
2.3 芯片的准备工作 7
2.3.1 AT89C51简介 7
2.3.2 DS18B20测温芯片 11
2.3.3 AD转换芯片TLC1543 13
2.3.4 GPRS短信报警芯片TC35i 14
2.3.5 液晶显示模块LCD1602 16
第3章 大楼防火报警系统硬件电路设计 19
3.1 单片机复位电路 19
3.2 时钟电路 19
3.3 稳压电源 19
3.4 烟雾浓度检测电路 20
3.5 测温模块设计 21
3.6 显示模块设计 21
第4章 系统软件实现和整体调试 23
4.1 软件环境介绍 23
4.2 软件设计方案及流程图 23
4.3 软硬件结合调试 24
第5章 总结与展望 33
参考文献 34
;********************************************************************
;DS18B20温度计 *
;采用4位LED共阳显示器显示测温值,显示精度0.1℃,测温范围-55~+125*
;用AT89C2051单片机,12MHZ晶振 *
;********************************************************************
;***************常数定义********************
TIMEL EQU 0E0H ;20ms,定时器0时间常数
TIMEH EQU 0B1H
TEMPHEAD EQU 36H
;********************工作内存定义**********************
BITST DATA 20H
TIME1S0K BIT BITST.1
TEMPONEOK BIT BITST.2
TEMPL DATA 26H
TEMPH DATA 27H
TEMPHC DATA 28H
TEMPLC DATA 29H
SCANLED DATA 2AH
;*****************引脚定义*****************************
TEMPDIN BIT P3.7
;*****************中断向量区***************************
ORG 0000H
LJMP START
ORG 000BH
LJMP T01T
;***************系统初始化****************************
ORG 0030H
START: MOV SP,#60H
CLSMEM: MOV R0,#20H
MOV R1,#60H
CLSMEM1: MOV @R0,#00H
INC R0
DJNZ R1,CLSMEM1
MOV TMOD,#00100001B ;定时器0工作方式1(16位)
MOV TH0,#HIGH(65536-5000)
MOV TL0,#LOW(65536-5000) ;5ms
SJMP INIT
ERROR: NOP
LJMP START
NOP
INIT: NOP
SETB ET0
SETB TR0
SETB EA
MOV PSW,#00H
CLR TEMPONEOK
MOV 50H,#10
MOV 51H,#10
MOV 52H,#10
MOV 53H,#10
LJMP MAIN
;*******************************************************************
;定时器0中断服务程序
;*******************************************************************
T01T: CLR TR0
MOV TH0,#HIGH(65536-5000)
MOV TL0,#LOW(65536-5000) ;5ms
SETB TR0
LEDDIS:
MOV DPTR,#TAB
MOV R1,#50H
MOV A,SCANLED
ADD A,R1
MOV R1,A
MOV A,SCANLED
JNZ LEDDIS1
MOV P3,#08H
SJMP LEDDIS4
LEDDIS1:
DEC A
JNZ LEDDIS2
MOV P3,#04H
SJMP LEDDIS4
LEDDIS2:
DEC A
JNZ LEDDIS3
MOV P3,#02H
SJMP LEDDIS4
LEDDIS3:
MOV P3,#01H
LEDDIS4:
MOV A,@R1
MOVC A,@A+DPTR
MOV P1,A
INC SCANLED
MOV A,SCANLED
CJNE A,#4,T0CNT
MOV SCANLED,#0
T0CNT:
INC R7
CJNE R7,#200,T0IT1
MOV R7,#00H
SETB TIME1S0K ;1s定时到标志
T0IT1: RETI
;********************************************************************
; 主程序
;********************************************************************
MAIN:
JNB TIME1S0K,MAIN
CLR TIME1S0K ;测温每1s一次
LCALL READTEMP ;读出温度值子程序
LCALL CONVTEMP ;温度BCD码计算处理子程序
LCALL DISPBCD ;显示区BCD码温度值刷新子程序
LJMP MAIN
;********************************************************************
; 子程序区
;********************************************************************
;***************复位DS18B20*****************************************
INITDS1820: SETB TEMPDIN
NOP
CLR TEMPDIN
MOV R6,#251 ;延时480μs
DJNZ R6,$
SETB TEMPDIN
MOV R6,#37 ;
LOOP1820: MOV C,TEMPDIN
JC INITDS1820OUT
DJNZ R6,LOOP1820
SJMP INITDS1820
RET
INITDS1820OUT:
MOV R6,#06BH ;延时200μs
DJNZ R6,$
SETB TEMPDIN
RET
;*******读DS18B20的程序,从DS18B20中读出1字节的数据*****
READDS1820: MOV R7,#08H
READDS1820LOOP: CLR TEMPDIN
NOP
NOP
SETB TEMPDIN
MOV R6,#07 ;延时15μs
DJNZ R6,$
MOV C,TEMPDIN
RRC A
MOV R6,#25
DJNZ R6,$
DJNZ R7,READDS1820LOOP
RET
;******写DS18B20的程序,从DS18B20中写1字节数据*****
WRITEDS1820: MOV R7,#08H
WRITEDS1820LOP: CLR TEMPDIN
MOV R6,#07H ;延时15μs
DJNZ R6,$
RRC A
MOV TEMPDIN,C
MOV R6,#30 ;延时104μs
DJNZ R6,$
SETB TEMPDIN
NOP
DJNZ R7,WRITEDS1820LOP
SETB TEMPDIN
RET
;******************读TEMP******************88
READTEMP: LCALL INITDS1820
MOV A,#0CCH
LCALL WRITEDS1820 ;Skip ROM
MOV A, #44H
LCALL WRITEDS1820 ;开始转换
MOV R6,#250 ;延时
DJNZ R6,$
READTEMP1: LCALL INITDS1820
MOV A,#0CCH
LCALL WRITEDS1820 ;Skip ROM
MOV A,#0BEH
LCALL WRITEDS1820 ;中间结果寄存器
MOV R6,#34H ;延时104μs
DJNZ R6,$
READTEMP2: LCALL READDS1820
MOV TEMPL,A
LCALL READDS1820
MOV TEMPH,A
READTEMPOUT: RET
;**************处理温度BCD码子程序***********
CONVTEMP: MOV A,TEMPH
ANL A,#80H
JZ TEMPC1
CLR C
MOV A,TEMPL
CPL A
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH ;"-"
CPL A
ADDC A,#00H
MOV TEMPH,A ;TEMPHC HI=符号位
MOV TEMPHC,#0BH
SJMP TEMPC11
TEMPC1: MOV TEMPHC,#0AH ;"+"
TEMPC11:
MOV R6,#4H
TEMPC12:
MOV A,TEMPH
RRC A
MOV TEMPH,A
MOV A,TEMPL
RRC A
MOV TEMPL,A
DJNZ R6,TEMPC12
RET
;*****************小数部分码表*********
TEMPDOTTAB: DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
DB 06H,07H,08H,08H,09H,09H
;************显示区BCD码温度值刷新子程序********
DISPBCD: MOV 53H,TEMPHC
MOV A,TEMPL
MOV B,#10
DIV AB
MOV 50H,B
MOV B,#10
DIV AB
MOV 51H,B
JZ DISPBCD2
MOV 52H,A
RET
DISPBCD2: MOV 52H,#10
RET
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH
;共阳段码表 "0","1","2","3","4","5","6","7","8","9","不亮","-"
END
第二阶段 温度变送器的应用
一、实习内容和要求:
1、 采用Pt100热电阻作为温度传感器,测量范围为0~200度;
2、 设计热电阻传感器的测量转换电路、信号放大电路;
3、 设计仪表供电电路,已知外部输入的电源为24V直流电源;
4、 搭建8051单片机最小系统、LM032L液晶显示、基本按键输入电路;
5、 基于AD1674芯片开发A/D转换电路,正确连接AD1674与8051,实现热电阻转换后的信号采集;
6、 采用D/A转换芯片DAC1230实现4~20mA的信号输出;
7、 编写程序代码,实现热电阻信号采集、仪表信号输出、测量值显示、仪表必须的参数设置等智能仪表的基本功能。
二:温度变送器的设计程序:
#includeREG52.h
#includestdio.h
#includeintrins.h
/* ---------------*/
sbit ADC_STS=P1^0;
sbit ADC_CS=P1^1;
sbit ADC_A0=P1^2;
sbit ADC_CE=P1^3;
sbit ADC_RC=P1^4;
sbit L_RS=P1^5;
sbit L_RW=P1^6;
sbit L_E=P1^7;
sbit DAC_CS=P3^0;
sbit DAC_WR=P3^1;
sbit DAC_XFER=P3^2;
float ADC_data;
/*----------------*/
void delay(void)
{
unsigned int j,k;
for(j=20;j0;j--)
for(k=200;k0;k--);
}
/* --------ADC--------*/
void ADC_C( void)
{
P0=0xff;
DAC_CS=1;
_nop_();
ADC_CE=0;
ADC_CS=1;
ADC_RC=1;
ADC_A0=1;
_nop_();
ADC_CS=0;
_nop_();
ADC_RC=0;
_nop_();
ADC_CE=1;
_nop_();
ADC_CE=0;
ADC_CS=1;
ADC_RC=1;
}
void ADC_R(void)
{ ADC_CS=0;
_nop_();
ADC_A0=0;
_nop_();
ADC_RC=1;
_nop_();
ADC_CE=1;
_nop_();
ADC_data=P0;
}
/* ------LCD-------*/
void LCD_init(void)
{ ADC_CS=1;
_nop_();
P2=0x38;
L_RS=1;L_RW=1;L_E=0;
_nop_();
L_RS=0;L_RW=0;
_nop_();
L_E=1;
_nop_();
L_E=0;
delay();
L_RS=1;L_RW=1;P2=0x0e;
_nop_();
L_RS=0;L_RW=0;
_nop_();
L_E=1;
_nop_();
L_E=0;
delay();
L_RS=1;L_RW=1;_nop_();
}
void LCD_display(unsigned char L_data)
{ P2=L_data;
L_RS=1;L_RW=0;
_nop_();
L_E=1;
_nop_();
L_E=0;
delay();
L_RS=1;L_RW=1;_nop_();
}
void LCD_clc(void)
{
P2=0x01;
L_RS=1;L_RW=1;L_E=0;
_nop_();
L_RS=0;L_RW=0;
_nop_();
L_E=1;
_nop_();
L_E=0;
delay();
L_RS=1;L_RW=1;
}
void LCD_shift(void)
{
P2=0xc0;
L_RS=1;L_RW=1;L_E=0;
_nop_();
L_RS=0;L_RW=0;
_nop_();
L_E=1;
_nop_();
L_E=0;
delay();
L_RS=1;L_RW=1;
}
/* ---DAC-------*/
void DAC(int DAC_data)
{ P2=DAC_data;
DAC_CS=1;
DAC_XFER=1;
DAC_WR=1;
_nop_();
DAC_CS=0;
_nop_();
DAC_WR=0;
delay();
DAC_WR=1;
_nop_();
DAC_CS=1;
_nop_();_nop_();
P2=0x00;DAC_CS=0; DAC_XFER=0;
_nop_();
DAC_WR=0;
delay();
DAC_WR=1;
DAC_CS=1;
}
/*------MAIN------*/
void main(void)
{ int length,t;
unsigned char tt[]=" TEMPRETURE";
while(1)
{ADC_C();
ADC_R();
//转换温度的程序,不太清楚。
LCD_init();
LCD_clc();
for(length=0;length15;length++)
{LCD_display(tt[length]);}
LCD_shift();
DAC(t);
delay();
}
}
对应的电路图如下:
三、思考题
1、 仪表零点、量程如何调整?
2、 你所设计的仪表应该采用哪一种线制连接方式?
3、 考虑Pt100热电阻非线性补偿问题该如何处理,可能的同学请实现非线性补偿,测试补偿前后的变送器特性。
四、实习总结
图传不上去
建议 去 我的领地 5d6d 的 proteus 论坛看看
那里有很多 单片机仿真实例,包括仿真图 和 源码
搜 5d6d 和 proteus 2个关键词
单片机测温报警系统仿真的介绍到此就结束了,感谢您耐心阅读,谢谢。
本文标签:单片机测温报警系统仿真