用80c51单片机实现超温警报功能 哪位大大可以帮小弟编写下程序啊?

我用的就是DS18B20传感器 电路 我现在没有你可以帮我选一个么?
2025-01-03 01:18:53
推荐回答(4个)
回答1:

#include #include "DS18B20.h"   #define uint unsigned int#define uchar unsigned char   //宏定义#define SET  P3_1    //定义调整键#define DEC  P3_2    //定义减少键#define ADD  P3_3    //定义增加键#define BEEP P3_7    //定义蜂鸣器bit shanshuo_st;    //闪烁间隔标志bit beep_st;     //蜂鸣器间隔标志sbit DIAN = P2^7;        //小数点uchar x=0;      //计数器signed char m;     //温度值全局变量uchar n;      //温度值全局变量uchar set_st=0;     //状态标志signed char shangxian=38;  //上限报警温度,默认值为38signed char xiaxian=5;   //下限报警温度,默认值为38uchar code  LEDData[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};

/*****延时子程序*****/void Delay(uint num){ while( --num );}

/*****初始化定时器0*****/void InitTimer(void){  TMOD=0x1;  TH0=0x3c;  TL0=0xb0;     //50ms(晶振12M)}

/*****定时器0中断服务程序*****/void timer0(void) interrupt 1{ TH0=0x3c; TL0=0xb0; x++;}

/*****外部中断0服务程序*****/void int0(void) interrupt 0{  EX0=0;      //关外部中断0 if(DEC==0&&set_st==1) {  shangxian--;  if(shangxian

/*****外部中断1服务程序*****/void int1(void) interrupt 2{ EX1=0;      //关外部中断1 if(ADD==0&&set_st==1) {  shangxian++;  if(shangxian>99)shangxian=99; } else if(ADD==0&&set_st==2) {  xiaxian++;  if(xiaxian>shangxian)xiaxian=shangxian; }  }

/*****读取温度*****/void check_wendu(void){ uint a,b,c; c=ReadTemperature()-5;  //获取温度值并减去DS18B20的温漂误差 a=c/100;     //计算得到十位数字 b=c/10-a*10;    //计算得到个位数字 m=c/10;      //计算得到整数位 n=c-a*100-b*10;    //计算得到小数位 if(m<0){m=0;n=0;}   //设置温度显示上限 if(m>99){m=99;n=9;}   //设置温度显示上限    }

/*****显示开机初始化等待画面*****/Disp_init()    { P2 = 0xbf;      //显示- P1 = 0xf7; Delay(200); P1 = 0xfb; Delay(200);    P1 = 0xfd; Delay(200); P1 = 0xfe; Delay(200);

 P1 = 0xff;         //关闭显示}

/*****显示温度子程序*****/Disp_Temperature()     //显示温度{ P2 =0xc6;      //显示C P1 = 0xf7; Delay(300);

 P2 =LEDData[n];    //显示个位 P1 = 0xfb; Delay(300);

 P2 =LEDData[m%10];    //显示十位 DIAN = 0;         //显示小数点 P1 = 0xfd; Delay(300);

 P2 =LEDData[m/10];    //显示百位 P1 = 0xfe; Delay(300);

 P1 = 0xff;         //关闭显示}

/*****显示报警温度子程序*****/Disp_alarm(uchar baojing){ P2 =0xc6;      //显示C P1 = 0xf7; Delay(200);

P2=0xff;

 P2 =LEDData[baojing%10]; //显示十位 P1 = 0xfb; P2=0xff;

Delay(200);

 P2 =LEDData[baojing/10]; //显示百位 P1 = 0xfd; P2=0xff;

Delay(200);

 if(set_st==1)P2 =0x89; else if(set_st==2)P2 =0xc7; //上限H、下限L标示 P1 = 0xfe; Delay(200);

 P1 = 0xff;         //关闭显示}

/*****报警子程序*****/void Alarm(){ if(x>=10){beep_st=~beep_st;x=0;} if((m>=shangxian&&beep_st==1)||(m

/*****主函数*****/void main(void){    uint z; InitTimer();    //初始化定时器 EA=1;      //全局中断开关 TR0=1; ET0=1;      //开启定时器0 IT0=1;         IT1=1; check_wendu(); check_wendu(); for(z=0;z<300;z++) {  Disp_init();          } while(1)  {  if(SET==0)  {   Delay(2000);   do{}while(SET==0);   set_st++;x=0;shanshuo_st=1;   if(set_st>2)set_st=0;  }  if(set_st==0)  {   EX0=0;    //关闭外部中断0   EX1=0;    //关闭外部中断1    check_wendu();      Disp_Temperature();   Alarm();   //报警检测  }  else if(set_st==1)  {   BEEP=1;    //关闭蜂鸣器   EX0=1;    //开启外部中断0   EX1=1;    //开启外部中断1   if(x>=10){shanshuo_st=~shanshuo_st;x=0;}   if(shanshuo_st) {Disp_alarm(shangxian);}  }  else if(set_st==2)  {   BEEP=1;    //关闭蜂鸣器   EX0=1;    //开启外部中断0   EX1=1;    //开启外部中断1   if(x>=10){shanshuo_st=~shanshuo_st;x=0;}   if(shanshuo_st) {Disp_alarm(xiaxian);}  }    }}

/*****END*****/

DS18B20.h:

#include #define  DQ  P3_6     //定义DS18B20总线I/O

/*****延时子程序*****/void Delay_DS18B20(int num){  while(num--) ;}

/*****初始化DS18B20*****/void Init_DS18B20(void){  unsigned char x=0;  DQ = 1;         //DQ复位  Delay_DS18B20(8);    //稍做延时  DQ = 0;         //单片机将DQ拉低  Delay_DS18B20(80);   //精确延时,大于480us  DQ = 1;         //拉高总线  Delay_DS18B20(14);  x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败  Delay_DS18B20(20);}

/*****读一个字节*****/unsigned char ReadOneChar(void){  unsigned char i=0;  unsigned char dat = 0;  for (i=8;i>0;i--)  {    DQ = 0;     // 给脉冲信号    dat>>=1;    DQ = 1;     // 给脉冲信号    if(DQ)    dat|=0x80;    Delay_DS18B20(4);  }  return(dat);}

/*****写一个字节*****/void WriteOneChar(unsigned char dat){  unsigned char i=0;  for (i=8; i>0; i--)  {    DQ = 0;    DQ = dat&0x01;    Delay_DS18B20(5);    DQ = 1;    dat>>=1;  }}

/*****读取温度*****/unsigned int ReadTemperature(void){  unsigned char a=0;  unsigned char b=0;  unsigned int t=0;  float tt=0;  Init_DS18B20();  WriteOneChar(0xCC);  //跳过读序号列号的操作  WriteOneChar(0x44);  //启动温度转换  Init_DS18B20();  WriteOneChar(0xCC);  //跳过读序号列号的操作  WriteOneChar(0xBE);  //读取温度寄存器  a=ReadOneChar();     //读低8位  b=ReadOneChar();    //读高8位  t=b;  t<<=8;  t=t|a;  tt=t*0.0625;  t= tt*10+0.5;     //放大10倍输出并四舍五入  return(t);}

回答2:

可以给个思路哈。帮忙写程序不现实哈。你用什么传感器都不知道。你的电路怎样的也不知道。我该怎么写呢?
可以这样子:1.比如说用DS18b20,这款温度传感器。它的驱动程序网络上都有的。你先把这个调通。2.只要在其中用个if语句判断,如果超温了就警报。3.警报的装置,你可以用蜂鸣器就可以了。因为估计你这个也只是个小设计,用蜂鸣器意思意思就可以了。
整个工程项目就好了。思路就这么简单。学习的事情要自己稳扎稳打的。

回答3:

;______________________DS18B20温度传感________________________________
;********************************************************
; 定义标志位
;********************************************************
DAT EQU P3.7
TEMP_ZH DATA 24H ;实时温度值存放单元
TEMPL DATA 25H ;温度低位值存放单元
TEMPH DATA 26H ;温度高位值存放单元
BW DATA 27H ;百位数存放单元
ERT DATA 28H ;定义显示寄存器
XS0 DATA 29H
XS1 DATA 30H
FLAG BIT 20H.0 ;温度正负标志
;*********************************************************
; 初始化
;*********************************************************
ORG 0000H
AJMP MAIN
ORG 000BH ;T0定时计数器
LJMP INTO
ORG 0030H
MAIN:MOV SP,#60H
MOV ERT,#00H
MOV TMOD,#01H ;定时1MS
MOV TH0,#0FCH
MOV TL0,#18H
SETB EA
SETB ET0
SETB TR0

;*********************************************************
; 主程序
;*********************************************************

START:LCALL INITION ;调用DS18B20初始化子程序
MOV A,#0CCH ;写CCH命令到DS18B20,以便(skip)跳过ROM匹配
LCALL WRITE18B20 ;调用写DS18B20一个字节子程序

MOV A,#44H ;发温度转换命令
LCALL WRITE18B20

LCALL INITION ;调用DS18B20初始化子程序
MOV A,#0CCH ;写CCH命令到DS18B20
LCALL WRITE18B20
MOV A,#0BEH ;写入读RAM中的数据命令
LCALL WRITE18B20
LCALL READ18B20 ;调用读DS18B20一个字节子程序
MOV TEMPL,A ;将读出的数据暂存TEMPL
LCALL READ18B20
MOV TEMPH,A ;将读出的数据暂存TEMPH

LCALL TEMPCONV ;调用温度转换子程序
; LCALL DIAPLAY ;调用显示子程序【在中断中不能调用子程序】
LJMP START
;*************************************************************
; DS18B20初始化子程序
;*************************************************************
INITION:CLR EA ;关中断
SETB DAT ;复位
MOV R4,#200
AA: CLR DAT
DJNZ R4,AA
SETB DAT ;检测脉冲存在
MOV R4,#30
DJNZ R4,$
JB DAT,INITION
MOV R4,#80
LOOP1: JB DAT,OUT
DJNZ R4,LOOP1
SJMP INITION
OUT:LCALL DELAY480UM

SETB EA ;开中断
RET
;**************************************************************
; 写DS18B20一个字节子程序
;**************************************************************
WRITE18B20:
CLR EA ;关中断
MOV R3,#8 ;写入一个字节8次
LOOP2: SETB DAT ;向18B20读
MOV R5,#8
RRC A
CLR DAT ;稳定
DJNZ R5,$
MOV DAT,C
MOV R5,#20
DJNZ R5,$
DJNZ R3,LOOP2

SETB EA ;开中断
RET
;***************************************************************
; 读DS18B20一个字节子程序
;***************************************************************
READ18B20:
CLR EA ;关中断
; CLR ET0 ;【去掉可以减少中断时间,处理闪烁显现】
; CLR TR0

MOV R3,#8
LOOP3: CLR DAT ;向18B20写
MOV R5,#4
NOP
SETB DAT
DJNZ R5,$
MOV C,DAT
RRC A
MOV R5,#30
DJNZ R5,$
DJNZ R3,LOOP3
SETB DAT

SETB EA ;开中断
; SETB ET0
;SETB TR0
RET
;****************************************************************
; 温度转换子程序
;****************************************************************
TEMPCONV:
MOV A,TEMPH ;判断是为零下
ANL A,#80H ;保留最高位
JZ TEMP0 ;JZ=0表示正温度,跳转
SETB FLAG ;JZ=1顺序执行,标志位置1表示负温度
CLR C ;清C
MOV A,TEMPL ;二进制求补
CPL A ;取反
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H
MOV TEMPH,A
AJMP TEMP1
TEMP0: CLR FLAG ;温度为正值
;----------------小数部分---------------------
TEMP1: MOV A,TEMPL
ANL A,#0FH ;取小数
MOV B,#0AH
MUL AB ;最低位乘以10
MOV B,#16 ;除以16精确度为一位,若要精确多为则取余数乘以10再除以16
DIV AB
MOV 35H,A
;----------------整数部分----------------------
MOV A,TEMPL
ANL A,#0F0H ;屏蔽低四位
SWAP A ;交换字节,取出高四位
MOV TEMPL,A
MOV A,TEMPH
ANL A,#0FH ;屏蔽高四位
SWAP A ;交换字节,取出低四位
ORL A,TEMPL ;将中间两数组合
MOV TEMP_ZH,A ;实时温度值
LCALL ZH_BCD ;调用组合后单字节十六进制BCD转换
RET
;*********************************************************************
; 调用组合后单字节十六进制BCD转换
;*********************************************************************
ZH_BCD:MOV B,#100
DIV AB
MOV 38H,A ;38H=百位数
MOV A,B
MOV B,#10
DIV AB
MOV 37H,A ;十位给37H
MOV 36H,B ;个位给36H
RET
;*********************************************************************
; 中断服务子程序
;*********************************************************************
INTO:PUSH PSW
PUSH ACC
MOV TH0,#0FCH ;重装初值
MOV TL0,#18H
INC ERT
MOV A,ERT

CJNE A,#1,KK0
MOV XS0,#11110111B ;显示百位
MOV XS1,38H
AJMP DIAPLAY

KK0: CJNE A,#2,KK1
MOV XS0,#11111011B ;显示十位 FB
MOV XS1,37H
AJMP DIAPLAY

KK1:CJNE A,#3,KK2
MOV XS0,#11111101B ;显示个位
MOV XS1,36H
AJMP DIAPLAY ;【在两个程序转移时要用LCALL,一个程序中要用LJMP】

KK2:CJNE A,#4,OUTI
MOV XS0,#11111110B ;显示小数位
MOV XS1,35H
MOV ERT,#00H ;重装
; LCALL DIAPLAY
DIAPLAY:
MOV DPTR,#TAB
MOV A,XS1
MOVC A,@A+DPTR
MOV P0,A
MOV A,XS0
CJNE A,#0FDH,OUTT
SETB P0.7
OUTT:MOV P2,XS0
OUTI:POP ACC
POP PSW
RETI
;****************************************************************
; 延时子程序
;****************************************************************
DELAY480UM:MOV R6,#35H
DL1:MOV R7,#03H
DJNZ R7,$
DJNZ R6,DL1
RET
;****************************************************************
; 代码表
;****************************************************************
TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END

回答4:

你好,请把80c51单片机资料发到superbest@live.cn,我帮你编一个