📄 zonghe.c
字号:
#include"ht46r24.h"
#pragma vector isr_8 @ 0x8 //中断函数地址
unsigned long int pulse_flag;//定时数,1对应50ms
unsigned long int den,denc,dens;//den一氧化碳浓度denc修正后的一氧化碳浓度
unsigned char temperture;//temperture温度值
unsigned char ad_i;//一氧化碳读取次数
//掩模中开看门狗
//********************CO A/D采集程序***********************************//
unsigned long int set_ad()
{ unsigned long int ad_result,k,u;
_adcr=0x18; //PB0,AN0通通
_acsr=0x01; //8分频0.5MHZ
_start=0;
_start=1;
_start=0; //启动A/D转换
while(_eocb); //等待A/D转换完成
u=_adrh;
k=_adrl;
k>>=6;
ad_result=u*4+k;
return(ad_result);
}
//**********************************ds1820程序*****************************************//
//***************ds18B20初始化***************//
void initial_ds18B20()
{ unsigned char presence;
presence=1;
while(presence)
{
_pdc=0; //设pd.0为输出
_pd0=1;
#asm
nop;
#endasm
_pd0=0; //DQ拉低
#asm //延时600us 精确延时大于480us小于960us
mov a,100
mov [0D1h],a
mov [0D2h],a
loop:sdz [0D1h]
jmp loop
jmp lp
lp:sdz [0D2h] //sdz和jmp,3个周期
jmp lp
#endasm
_pd0=1; //拉高后15到60us,若复位成功,DS18B20将产生60到240us低电平.
#asm // 延时69us
mov a,23
mov [0D1h],a
loop1:sdz [0D1h]
jmp loop1
#endasm
_pdc=0x01;//设pd.0为输入
#asm
nop;
nop;
#endasm
presence=_pd0;// 复位成功
}
_pdc=0;
_pd0 = 1;
#asm //300us
mov a,50
mov [0D1h],a
mov [0D2h],a
lp1:sdz [0D1h]
jmp lp1
jmp lp2
lp2:sdz [0D2h]
jmp lp2
#endasm
}
//*********向ds18B20写1个字节数据********//
void write_ds18B20(unsigned char wdata)
{unsigned char i,k;
for (i=8; i>0; i--)
{ _pd0=1;
_pdc=0;//设pd.0为输出
k=wdata&0x01;
if(k==0)
{ _pd0=0;
#asm //69us
mov a,23
mov [0D1h],a
loop3:sdz [0D1h]
jmp loop3
#endasm
_pd0=1;
#asm
nop;
nop;
nop;
nop;
nop;
#endasm
}
if(k==1)
{_pd0=0;
#asm
nop;
nop;
nop;
nop;
nop;
#endasm
_pd0=1;
#asm //69us
mov a,23
mov [0D1h],a
loop31:sdz [0D1h]
jmp loop31
#endasm
}
_pdc=0;
_pd0=1;
#asm
nop;
nop;
#endasm
wdata>>=1;
}
}
//*********从ds18B20读1个字节数据********//
unsigned char read_ds18B20()
{ unsigned char j,i;
unsigned char dat=0;
for(i=8;i>0;i--)
{
_pdc=0;//设pd.0为输出
_pd0=1;
#asm
nop;
#endasm
_pd0= 0; //给脉冲信号
#asm //大于1us
nop;
nop;
nop;
nop;
nop;
#endasm
_pdc=0x01;//设pd.0为输入
#asm
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
#endasm // 延时15us
j=_pd0;
#asm //68us
mov a,23
mov [0D1h],a
loop2:sdz [0D1h]
jmp loop2
#endasm
dat>>=1;
j<<=7;
dat|=j;
}
return(dat);
}
//*******读取温度值并转换******//
unsigned char read_temp()
{ unsigned char tvalue;
unsigned char a, b;//低、高位温度值
initial_ds18B20(); //复位
write_ds18B20(0xcc);//*跳过读序列号*/
write_ds18B20(0x44);//*启动温度*/
#asm //延时大于750mS,取1s 等待转换结束
mov a,35
mov [0D1h],a
l1:mov a,100
mov [0D2h],a
l2:mov a,100
mov [0D3h],a
l3:sdz [0D3h]
jmp l3
jmp l4
l4:sdz [0D2h]
jmp l2
jmp l5
l5:sdz [0D1h]
jmp l1
#endasm
initial_ds18B20(); //复位
write_ds18B20(0xcc);//*跳过读序列号*/
write_ds18B20(0xbe);//*读取温度转换*/
a=read_ds18B20();//读低字节
b=read_ds18B20();//读高字节
//数据处理
tvalue=(b<<4)|(a>>4);
return(tvalue);
}
//********************DS18B20程序结束***********************************//
//***********************显示程序***********************************//
void display(unsigned char m)
{ unsigned char a,b;
a=m%10;
b=m/10;
b=b*16;
m=a+b;
_pac=0;
#asm
nop;
nop;
#endasm
_pa=m;
#asm //延时1s
mov a,35
mov [0D1h],a
k1:mov a,100
mov [0D2h],a
k2:mov a,100
mov [0D3h],a
k3:sdz [0D3h]
jmp k3
jmp k4
k4:sdz [0D2h]
jmp k2
jmp k5
k5:sdz [0D1h]
jmp k1
#endasm
}
//********************初始化程序***********************************//
void init()
{ pulse_flag=0;
_pac=0;//温度显示
_pbc=0x01;//pb0一氧化碳输入pb6脉冲输出
_pcc=0;//pc0~pc2三个颜色不同的信号灯\pc3电扇\pc4蜂鸣器
_pdc=0x01;//pd0温度输入DS18B20
}
//********************延时程序***********************************//
void delay(unsigned char t)
{ while(t)
{
#asm //延时100ms
mov a,3
mov [0D1h],a
g1:mov a,100
mov [0D2h],a
g2:mov a,100
mov [0D3h],a
g3:sdz [0D3h]
jmp g3
jmp g4
g4:sdz [0D2h]
jmp g2
jmp g5
g5:sdz [0D1h]
jmp g1
#endasm
t--;
}
}
//******************************脉冲(5S高10S低)程序***************************************//
void isr_8() // timer/event 0
{
pulse_flag++;
if(pulse_flag<=100)//脉冲高
_pb6=1;
if(pulse_flag>100&&pulse_flag<=300)//脉冲低
_pb6=0;
if(pulse_flag==290)//14.5s测量
den=set_ad();// CO A/D PB0 */
if(pulse_flag==300)
pulse_flag=0;
}
void set_timer()
{ _intc0 = 0x5; //enable timer0
_tmr0c = 0x82; //timer0 mode (internal clock) 4分频,1MHZ
_t0on = 0; //timer0 disable
_tmr0l = 0xb0;
_tmr0h = 0x3c;
_t0on= 1; //start timer0
}
//************************温度修正程序*******************************//
void correct_t()
{ if(temperture<5)
denc=den*2/5;
if(temperture>=5&&temperture<15)
denc=den*2/3;
if(temperture>=15&&temperture<35)
denc=den;
if(temperture>=35&&temperture<50)
denc=den*4/3;
}
//********************报警程序***********************************//
void cry( unsigned char t) //t,高警报1,低警报0,pc1红灯,pc0黄灯,蜂鸣器pc4,电风扇pc3
{ if(t==1)
{ _pc4=1;
_pc1=1;
_pc3=1;
delay(4);
_pc4=0;
_pc1=0;
delay(2);
}
if(t==0)
{ _pc4=1;
_pc0=1;
_pc3=0;
delay(2);
_pc4=0;
_pc0=0;
delay(1);
}
}
//************************主程序*******************************//
void main()
{
init();//端口初始化
_pc=0;
ad_i=0;
den=0;
denc=0;
display(88);//初始显示88
set_timer();//定时中断
while(1)
{ temperture=read_temp(); //温度值
//display(temperture);
if(den!=0)
{ correct_t();
dens=denc/10;
display(dens);
if(denc<=800&&denc>500)//控制程序
cry(0);//黄灯,声光警报
if(denc<=500)//红灯,声光警报,电风扇
cry(1);
if(denc>800)
_pc=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -