#include
/*****延时子程序*****/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 /*****延时子程序*****/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);}
可以给个思路哈。帮忙写程序不现实哈。你用什么传感器都不知道。你的电路怎样的也不知道。我该怎么写呢?
可以这样子:1.比如说用DS18b20,这款温度传感器。它的驱动程序网络上都有的。你先把这个调通。2.只要在其中用个if语句判断,如果超温了就警报。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
你好,请把80c51单片机资料发到superbest@live.cn,我帮你编一个