单片机的两个接口直接与USB连接,已有这根线
上位机用串口调试助手2.2,波特率9600
/*高低温调整按键,初始加电高温报警值为32度,低温报警值为20度,这两个值可通过按键进行调整,
高温报警最高值为125度,低温报警最低值为0度,调整完毕后按温度开始测量键恢复温度测量状态,
当温度到达调整后的高低温报警值时,蜂鸣器响,4位一体数码管用于显示温度,有效值为小数点后一位。*/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
char TH=32; //高温报警
char TL=20; //低温报警
bit K_THcountflag=0,K_TLcountflag=0,T_flag=1; //高低温报警值调整标志位,开始温度测量标志位
sbit DQ=P1^0;
sbit beep=P3^3;
sbit K_SET=P3^4; //设置键
sbit K_ADD=P3^5; //加调整
sbit K_JIAN=P3^6; //减调整
sbit K_play=P3^7; //循环显示按键
sbit red_led=P1^6; //红灯控制端(高温报警时红灯亮)
sbit yellow_led=P1^7;//黄灯控制端(低温报警时黄灯亮)
uchar keyn,keyn1=1;
uchar code str1[]={0x28, 0xA7, 0xE0, 0x91, 0x04, 0x00, 0x00, 0xED}; //ROM 1
uchar code str2[]={0x28, 0x7A, 0x6F, 0x92, 0x04, 0x00, 0x00, 0x4F}; //ROM 2
uchar code str3[]={0x28, 0x4A, 0x16, 0x92, 0x04, 0x00, 0x00, 0x3C}; //ROM 3
//uchar time;
//bit beep_st; //蜂鸣器间隔标志
uchar x=0; //计数器
unsigned char bai,shi,ge,dian;//用于保存温度的百位,十位,个位及小数位
signed char TN,TD,TN1,TD1,TN2,TD2,TN3,TD3;
void delay(uchar ms)
{
uchar y;
for(;ms>0;ms--)
for(y=120;y>0;y--);
}
void Delayms(int num)//延时函数
{
while(num--) ;
}
uchar code tabledu[]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,
0xba,0x20,0x28,0x64,0x74,0x31,0xe5,0x30,0x25,0xe4}; //共阳0-9 E F H L
uchar code tableduge[]={0x80,0x9b,0x42,0x0a,0x19,0x0c,0x04,0x9a,0x00,0x08};//共阳0.-9.
uchar code tablewe[]={0XFE,0XFD,0XFB,0XF7};//共阳数码管位选择
//***************初始化ds18b20***********//
void Init_DS18B20(void)
{
//bit flag; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,标识不存在
DQ=1; //先将数据线拉高
Delayms(5);//略微延时
DQ=0; //再将数据线从高拉低,要求保持480-960us
Delayms(100); //略微延时约600微秒//以向DS18B20发出一持续480-960us的低电平复位脉冲
DQ=1; //释放数据线(将数据线拉高)
Delayms(20); //延时约30us(释放总线后需等待15-60us让DS18B20输出存在脉冲)//10
}
//*************位置1处传感器读取温度程序***************//
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat=0; //储存读出的一个字节数据
for(i=0;i<8;i++)
{
DQ=0; //单片机从DS18B20读数据时,将数据线从高拉低即启动读时序
dat>>=1;
DQ=1; //将数据线“人为”拉高,为单片机检测DS18B20的输出电平作准备
if(DQ)
dat|=0x80;
Delayms(8); //延时3us,两个读时序之间必须有大于1us的恢复期//8
}
return(dat); //返回读出的十进制数据
}
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
DQ=0; //将数据线从高拉低时即启动写时序
DQ=dat&0x01; //利用与运算 去除要写得某位二进制数据,并将数送到数据线上
Delayms(4); //延时约30us,DS18B20在拉低后的15-60us期间从数据线上采样
DQ=1; //释放数据线
dat>>=1; //将dat中的各二进制数据右移一位
}
}
void b20_Matchrom(uchar a) //匹配ROM
{
char j;
WriteOneChar(0x55); //发送匹配ROM命令
if(a==1)
{
for(j=0;j<8;j++)
WriteOneChar(str1[j]); //发送18B20的序列号,先发送低字节
}
if(a==2)
{
for(j=0;j<8;j++)
WriteOneChar(str2[j]); //发送18B20的序列号,先发送低字节
}
if(a==3)
{
for(j=0;j<8;j++)
WriteOneChar(str3[j]); //发送18B20的序列号,先发送低字节
}
}
void ReadTemp(uchar z) //读取温度
{
unsigned char a=0; //储存寄存器的温度低位
unsigned char b=0; //储存寄存器的温度高位
Init_DS18B20(); //将DS18B20初始化
WriteOneChar(0xCC); //跳过读序号列号的操作
Init_DS18B20(); //将DS18B20初始化
if(z==1)
{
b20_Matchrom(1); //匹配ROM2
}
if(z==2)
{
b20_Matchrom(2); //匹配ROM2
}
if(z==3)
{
b20_Matchrom(3); //匹配ROM3
}
WriteOneChar(0x44); //启动温度转换
delay(2);
Init_DS18B20(); //将DS18B20初始化
WriteOneChar(0xCC); //跳过读序号列号的操作
Init_DS18B20(); //将DS18B20初始化
if(z==1)
{
b20_Matchrom(1); //匹配ROM2
}
if(z==2)
{
b20_Matchrom(2); //匹配ROM2
}
if(z==3)
{
b20_Matchrom(3); //匹配ROM3
}
WriteOneChar(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
TN=b*16+a/16; //实际温度值=(b*256+a)/16,即:b*16+a/16,这样得出的是温度的整数部分,小数部分被丢弃了
TD=(a%16)*10/16;//计算温度的小数部分,将余数乘以10再除以16取整,这样得出的是温度小数部分的第一位
if(TN<0){TN=0;TD=0;} //设置温度显示下限
if(TN>99){TN=99;TD=9;} //设置温度显示上限;
/* bai=TN/100; //计算温度的百位
shi=TN%100/10; //计算温度的十位
ge=TN%10; //计算温度的个位
dian=TD;*/
}
void T0_Init(void)
{
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
EA=1;
}
void timer0(void) interrupt 1
{
TH0=(65536-50000)/256; //50ms
TL0=(65536-50000)%256;
x++;
if(x>=7){beep=~beep;x=0;}
}
/*****显示开机初始化等待画面*****/
Disp_init()
{
P0 = 0x7F; //显示-
P2=tablewe[0];
delay(2);
P2=tablewe[1];
delay(2);
P2=tablewe[2];
delay(2);
P2=tablewe[3];
delay(2);
P2=0xff; //关闭显示
}
void display(void)
{
if(K_THcountflag==1)
{
 0=tabledu[12]; //第一位显示H
 2=tablewe[0];
delay(7);
 0=0;
 2=0XFF;
 0=tabledu[TH/100];
 2=tablewe[1];
delay(7);
 0=0;
 2=0XFF;
 0=tabledu[TH%100/10];
 2=tablewe[2];
delay(7);
P0=0;
P2=0XFF;
P0=tabledu[TH%10];
P2=tablewe[3];
delay(7);
P0=0;
P2=0XFF;
}
if(K_TLcountflag==1)
{
P0=tabledu[13]; //第一位显示L
P2=tablewe[0];
delay(7);
P0=0;
P2=0XFF;
P0=tabledu[TL/100];
P2=tablewe[1];
delay(7);
P0=0;
P2=0XFF;
P0=tabledu[TL%100/10];
P2=tablewe[2];
delay(7);
P0=0;
P2=0XFF;
P0=tabledu[TL%10];
P2=tablewe[3];
delay(7);
P0=0;
P2=0XFF;
}
if(T_flag==1)
{
P0=tabledu[bai];
P2=tablewe[0];
delay(7);
P0=0;
P2=0XFF;
P0=tabledu[shi];
P2=tablewe[1];
delay(7);
P0=0; //消隐
P2=0XFF;
P0=tableduge[ge];
P2=tablewe[2];
delay(7);
P0=0;
P2=0XFF;
P0=tabledu[dian];
P2=tablewe[3];
delay(7);
P0=0;
P2=0XFF;
}
}
void temp_Scan(void) //按键扫描
{
if(K_SET==0) //设置按键
{
delay(15);
if(K_SET==0)
{
while(!K_SET);
keyn++;
if(keyn==4)
keyn=1;
switch(keyn)
{
case 1: K_THcountflag=1;
K_TLcountflag=0;
T_flag=0;
break;
case 2: K_THcountflag=0;
K_TLcountflag=1;
T_flag=0;
break;
case 3: K_THcountflag=0;
K_TLcountflag=0;
T_flag=1;
//break;
}
beep=1;
}
}
if(K_ADD==0) //加调整
{
delay(15);
if(K_ADD==0)
{
while(!K_ADD);
switch(keyn)
{
case 1:TH++;
if(TH>=99)
TH=99;
break;
case 2:TL++;
if(TL>=TH)
TL=TH;
break;
}
}
}
if(K_JIAN==0) //减调整
{
delay(15);
if(K_JIAN==0)
{
while(!K_JIAN);
switch(keyn)
{
case 1:TH--;
if(TH<=TL)
TH=TL;
break;
case 2:TL--;
if(TL<=0)
TL=0;
break;
}
}
}
}
void main(void)
{
uint z;
beep=1;
T0_Init();
ReadTemp(1); //读取三点温度值
ReadTemp(2);
ReadTemp(3);
for(z=0;z<400;z++)
{
Disp_init();
}
while(1)
{
ReadTemp(1);//读取1点温度值
TN1=TN;TD1=TD;
display();//显示到数码管?
ReadTemp(2);//读取2点温度值
TN2=TN;TD2=TD;
display();//显示到数码管上
ReadTemp(3);
TN3=TN;TD3=TD;
display();//显示到数码管上
if(K_play==0) //设置按键
{
delay(15);
if(K_play==0)
{
while(!K_play);
keyn1++;
if(keyn1==4)
keyn1=1;
}
}
if(keyn1==1)
{
bai=14;
shi=TN1%100/10;
ge=TN1%10;
dian=TD1;
}
if(keyn1==2)
{bai=15;
shi=TN2%100/10;
ge=TN2%10;
dian=TD2; }
if(keyn1==3)
{ bai=16;
shi=TN3%100/10;
ge=TN3%10;
dian=TD3;}
temp_Scan();
// display();//显示到数码管上
if(((TN1>=TH)||(TN2>=TH)||(TN3>=TH)||(TN1<TL)||(TN2<TL)||(TN3<TL))&&(T_flag==1))//如果到达报警值
TR0=1;//打开定时器0,蜂鸣器报警
else{TR0=0;beep=1;yellow_led=1;red_led=1;}
if(((TN1<TL)||(TN2<TL)||(TN3<TL))&&(T_flag==1))//如果为低温报警
yellow_led=0;//黄灯亮
else yellow_led=1;
if(((TN1>=TH)||(TN2>=TH)||(TN3>=TH))&&(T_flag==1))//如果为高温报警
red_led=0;//红灯亮
else
red_led=1;
}
}
|