📄 ddddd.c
字号:
#include <REG52.H>
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P2^4; //DS18B20接口
sbit LED_CLK=P2^2; //74HC595输入时钟脉冲
sbit SERD=P0^3; // 小数位输入
sbit SERP=P0^2; // 个位输入
sbit SERT=P0^1; // 十位输入
sbit SERH=P0^0; // 百位,符号位输入
sbit RCKD=P0^7; // 小数位输出时钟脉冲
sbit RCKP=P0^6; // 个位输出时钟脉冲
sbit RCKT=P0^5; // 十数位输出时钟脉冲
sbit RCKH=P0^4; // 百位,符号位输出时钟脉冲
sbit Set1=P3^2; //上限温度设定
sbit Set2=P3^3; //下限温度设定
sbit Bit=P1^0; //位选择
sbit Up=P1^1; //所选位加1
sbit Down=P1^2; //所选位减1
sbit Out=P1^3; //退出设定
sbit alm=P2^3; //报警信号
uint temp_value,tempV; //温度值
uchar flag1; //所测温度为负数的标志位
char tempsh=40,tempsl=10,sym=1; //温度上下限及符号位
uchar count,tbit,intr; //设定模式标志位
uchar data Dis_play[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据和一个运算暂用
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};
//共阴数码管段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "灭" "-"
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//带小数点的编码
//共阴数码管带小数点段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//小数部分对应十进制 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F"
//***********ds18b20延迟子函数(晶振12MHz )*******//
void delay_18B20(unsigned int i)
{
while(i--);
}
//************************************************//
//******************延时子程序********************//
void delay(uint delay)
{ uint i;
for(;delay>0;delay--)
{for(i=0;i<62;i++) //1ms延时.
{;}
}
}
//***********************************************//
//**********ds18b20初始化函数**********************//
void Init_18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(4);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
//************************************************//
//***********ds18b20读一个字节**************//
unsigned char Read_18B20(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
//*****************************************//
//*************ds18b20写一个字节****************//
void Write_18B20(uchar dat)
{
unsigned char i=0;
for (i=8;i>0;i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
//**********************************************//
//**************读取ds18b20当前温度************//
uint ReadTemp()
{
unsigned char a=0;
unsigned char b=0;
unsigned char t=0;
Init_18B20();
Write_18B20(0xCC); // 跳过读序号列号的操作
Write_18B20(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_18B20();
Write_18B20(0xCC); //跳过读序号列号的操作
Write_18B20(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
delay_18B20(100);
a=Read_18B20(); //读取温度值低位
b=Read_18B20(); //读取温度值高位
temp_value=b;
temp_value<<=8;
temp_value=temp_value|a;
return temp_value;
}
//*******************************************//
//*************温度数据处理*****************//
void tem_deal(uint tem)
{
if(tem>6348) // 温度值正负判断
{tem=65536-tem;flag1=1;} // 负温度求补码,标志位置1
Dis_play[4]=tem&0x0f; // 取小数部分的值
Dis_play[0]=ditab[Dis_play[4]]; // 存入小数部分显示值
Dis_play[4]=tem>>4; // 取中间八位,即整数部分的值
Dis_play[3]=Dis_play[4]/100; // 取百位数据暂存
Dis_play[1]=Dis_play[4]- Dis_play[3]*100; // 取后两位数据暂存
Dis_play[2]=Dis_play[1]/10; // 取十位数据暂存
Dis_play[1]=Dis_play[1]-Dis_play[2]*10; // 取个位数据暂存
if(Dis_play[3]==0) // 最高位为0都不显示
{
Dis_play[3]=0x0a; // 先判断百位是否为0
if(Dis_play[2]==0)
{
Dis_play[2]=0x0a; // 再判断十位是否为0
}
}
if(flag1)
{
Dis_play[3]=0x0b; // 为负数时,最高位显示 "-"
}
}
//******************************************//
//***************74HC595四位读程序**************//
void WR_74HC595(uchar dat,uchar k)
{
uchar i;
for(i=0;i<8;i++)
{
switch(k)
{
case 0:SERD=0;LED_CLK=0;dat=dat<<1;SERD=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break; //小数位
case 1:SERP=0;LED_CLK=0;dat=dat<<1;SERP=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break; //个位
case 2:SERT=0;LED_CLK=0;dat=dat<<1;SERT=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break; //十位
case 3:SERH=0;LED_CLK=0;dat=dat<<1;SERH=CY;LED_CLK=1;_nop_();LED_CLK=0;_nop_();break; //百位 负号位
default:break;
}
}
}
//****************************************************//
//****************74HC595四位写出程序*****************//
void Send_74HC595(uchar k)
{
switch(k)
{
case 0:RCKD=0;_nop_();_nop_();RCKD=1;_nop_();_nop_();RCKD=0;_nop_();break; //小数位
case 1:RCKP=0;_nop_();_nop_();RCKP=1;_nop_();_nop_();RCKP=0;_nop_();break; //个位
case 2:RCKT=0;_nop_();_nop_();RCKT=1;_nop_();_nop_();RCKT=0;_nop_();break; //十位
case 3:RCKH=0;_nop_();_nop_();RCKH=1;_nop_();_nop_();RCKH=0;_nop_();break; //百位 负号位
default:break;
}
}
//***************************************************//
//******************温度数据显示********************//
void display()
{
uchar k;
for(k=0;k<4;k++) //4位轮流显示
{
if (k==1)
{WR_74HC595(table1[Dis_play[k]],k); //小数点显示
Send_74HC595(k);}
else
{WR_74HC595(table[Dis_play[k]],k);
Send_74HC595(k);}
}
}
//*************************************************//
//****************上下限显示***********************//
void display_data(char temp)
{
uchar i,j,k;
if(temp<0)
{
i=11; //显示负号
temp=0-temp;
}
else
i=0;
j=temp/10;
k=temp-j*10;
WR_74HC595(table[i],3);
Send_74HC595(3); //显示百位为0
// _nop_();
// _nop_();
WR_74HC595(table[j],2); //显示十位
Send_74HC595(2);
// _nop_();
// _nop_();
WR_74HC595(table1[k],1); //显示个位
Send_74HC595(1);
// _nop_();
// _nop_();
// _nop_();
WR_74HC595(table[0],0); //显示小数位
Send_74HC595(0);
}
//************************************************//
//***************设定模式按键*****************//
void setkey1() //设定上限
{
Set1=1;
if(Set1==0)
{
delay(8);
count=1; //设定模式标志
tbit=0; //位选择归零
while(Set1==0);
}
}
void setkey2() //设定下限
{
Set2=1;
if(Set2==0)
{
delay(8);
count=2; //设定模式标志
tbit=0; //位选择归零
while(Set2==0);
}
}
//********************************************//
//***************位选择按键*******************//
void bitkey()
{
Bit=1;
if(Bit==0)
{
delay(8);
tbit=tbit+1;
if(tbit==4)
tbit=1;
while(Bit==0);
}
}
//*******************************************//
//***************升序按键********************//
void upkey()
{
uchar one,ten; //个位与十位
Up=1;
if(Up==0)
{
delay(8);
if(count==1) //上限增加
{
ten=tempsh/10;
one=tempsh-ten*10;
switch(tbit)
{
case 1:
one=one+1;
if(one>9)
one=0;
break;
case 2:
ten=ten+1;
if(ten>9)
ten=0;
break;
}
tempsh=ten*10+one; //设定后的值
}
if(count==2) //下限增加
{
if(tempsl<0)
{
ten=(0-tempsl)/10;
one=(0-tempsl)-ten*10;
}
else
{
ten=tempsl/10;
one=tempsl-ten*10;
}
switch(tbit)
{
case 1:
one=one+1;
if(one>9)
one=0;
break;
case 2:
ten=ten+1;
if(ten>9)
ten=0;
break;
case 3: //设定是否为负数
if(sym==1)
sym=-1;
else if(sym==-1)
sym=1;
}
tempsl=sym*(ten*10+one); //设定后的值
}
while(Up==0);
}
}
//******************************************//
//**************降序按键********************//
void downkey()
{
uchar one,ten; //个位与十位
Down=1;
if(Down==0)
{
delay(8);
if(count==1) //上限减少
{
ten=tempsh/10;
one=tempsh-ten*10;
switch(tbit)
{
case 1:
if(one==0)
one=9;
else
one=one-1;
// down_flag=1;
break;
case 2:
if(ten==0)
ten=9;
else
ten=ten-1;
// down_flag=1;
break;
}
tempsh=ten*10+one; //设定后的值
}
if(count==2)
{
if(tempsl<0)
{ten=(0-tempsl)/10;
one=(0-tempsl)-ten*10;}
else
{
ten=tempsl/10;
one=tempsl-ten*10;
}
switch(tbit)
{
case 1:
if(one==0)
one=9;
else
one=one-1;
// down_flag=1;
break;
case 2:
if(ten==0)
ten=9;
else
ten=ten-1;
// down_flag=1;
break;
}
tempsl=sym*(ten*10+one); //设定后的值
}
while(Down==0);
}
}
//***********************************************//
//******************退出按键*****************//
void outkey()
{
Out=1;
if(Out==0)
{
delay(8);
count=0;
intr=0;
while(Out==0);
}
}
//***********************************************//
//****************中断初始化*********************//
void init(void)
{
EA=1;//中断总开关
EX0=1;//开中断0开关。中断1为,EX1=1;
EX1=1;
IT0=1;//采用边沿触发,下降沿有效。IT1=0为低电平触发中断
IT1=1;
}
//**********************************************//
//***************中断0服务程序(设定上限)***************//
void int_0()interrupt 0 using 1
{
intr=1;
EA=0;
count=0;
alm=0;
delay(100);
while(intr==1)
{
display_data(tempsh);
setkey1();
delay(1);
bitkey();
upkey();
downkey();
outkey();
}
EA=1;
}
//******************************************************//
//****************中断1服务程序(设定下限)*************//
void int_1()interrupt 2 using 2
{
EA=0;
count=0;
intr=1;
alm=0;
delay(100);
while(intr==1)
{
display_data(tempsl);
delay(1);
setkey2();
bitkey();
upkey();
downkey();
outkey();
}
EA=1;
}
//***************************************************//
//****************超限报警***********************//
void alarm()
{
uchar temp;
alm=0;
temp=Dis_play[2]*10+Dis_play[1];
// if((flag1)&&(temp>(0-tempsl)))
// alm=1;
if(temp>tempsh)
alm=1;
else if(temp==tempsh)
if(Dis_play[0])
alm=1;
delay(300);
if(temp<tempsl)
alm=1;
// else
// alm=0;
}
//***********************************************//
void main()
{
P1=0xff;
P0=0x00;
P3=0xff;
count=0;
intr=0;
alm=0;
init();
do
{
while(intr==0)
{
delay(100);
tempV=ReadTemp();
delay(100);
tem_deal(tempV);
display();
delay(10);
alarm();
}
}
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -