📄 srf25.c
字号:
#include <intrins.h>
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define nop() _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
sbit Fout=P1^6;//40kHZ
sbit Damp=P3^3;//阻尼
sbit Block=P3^4;//封锁
sbit Led_seg=P1^1;
sbit Led_rclk =P1^0;
sbit Led_srclk=P3^7;
sbit DQ =P1^7; //定义通信端口
const char tab[]= //定义LED数码管显示数字.常量(不带点)
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//0-9,-,全灭 0-9带小数点 共阳数码管
float Distance;//距离
uint Time;
uchar wd;//存储计时器高位,低位
uchar ReceiveOk=0,flag=0;
void Init();//初始化
void Delay(uchar t);
void Send();//发射声波
void Receive();//接收外部中断程序
void Display(uint x);//显示程序
void Disp(void);
float ReadTemperature(void);
void WriteOneChar(uchar dat);
uchar ReadOneChar(void);
void Init_DS18B20(void);
void delays(uint i);
//-----------------------主程序-------------------------------
void main(void)
{
uchar j, k;
TMOD=0x01; //计数器1模式1
IE=0x00;
// PX0=1; //INT0高优先级
TF0=0;
IT0=0; //INT0下降沿触发0
wd=ReadTemperature();//读温度
while (1)
{
Send();
for(j=0;j<5;j++) Delay(250);
IT0=1; //INT0下降沿触发0
while(1)
{
if(ReceiveOk==1)
{
ReceiveOk=0;
// Distance=(331.5+0.6*wd)*Time/20000;//89C2051
Distance=(331.5+0.6*wd)*Time/29000;//STC2051
Display((int)(Distance));
break;
}
if(flag==1)
{
flag=0;
TF0=0;
Distance=0;
Display(0);
break;
}
Delay(250);
}
for(k=0;k<100;k++) Delay(250);
}
}
//------------------------延时函数----------------------------
void Delay(uchar t)
{
uchar i,j=0xff;
for(i=0;i<t;i++)
{
for(j=0x19;j>0;j--);
}
}
//------------------------40KHZ超声波发射----------------------------
void Send()
{
uchar counter;
IE=0x00;
IT0=0; //INT0下降沿触发0
Damp=0; //关阻尼
Block=0; //开始封锁 低电平9012导通
Fout=0;
TH0=0;
TL0=0; //计数器清零
TR0=1; //启动计数器1;
for (counter=0;counter<20;)
{
nop() nop() nop() nop() nop() nop()
nop() nop() nop() nop() nop() nop()
nop() nop() nop() nop() nop() nop()
nop()
counter++;
Fout=!Fout;
}
Damp=1; //开阻尼 9014高电平导通
Block=1; //解除封锁 9012高电平关断
EX0=1; //外部中断0允许
ET0=1; //定时器0溢出允许
EA=1;
}
void Out595(void)
{
Led_rclk=0;
nop()
Led_rclk=1;
}
void Sendbyte(uchar byte)
{
uchar data count;
uchar num;
num=tab[byte];
for(count=0;count<=7;count++)
{
Led_srclk=0;
if((num&0x80)==0x80) //*最高位为1,则向SDATA_595发送1*/
Led_seg=1; //*发出数据的最高位*/
else
Led_seg=0;
num<<=1; //*右移位*/
Led_srclk=1; //*产生上生沿*/
}
}
void Display(uint x)
{
uchar a,b,c;
a=x%10;
b=x/10%10;
c=x/100%10;
Sendbyte(a);
Sendbyte(b);
Sendbyte(c+0x0b);
Out595();
}
//--------------------外部中断接收程序-------------------------
void Receive() interrupt 0 //外部中断INT0
{
TR0=0;
IE=0x00; //关中断
Time=TH0*256+TL0;
ReceiveOk=1;
}
void Overtime() interrupt 1 //定时器0溢出
{
TR0=0;
IE=0x00; //关中断
flag=1;
}
//读取温度
float ReadTemperature(void)
{
uchar a=0;
uchar b=0;
uint t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();
b=ReadOneChar();
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
return(tt);
}
//写一个字节
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delays(5);
DQ = 1;
dat>>=1;
}
delays(4);
}
//读一个字节
uchar ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delays(4);
}
return(dat);
}
//初始化函数
void Init_DS18B20(void)
{
uchar x=0;
DQ = 1; //DQ复位
delays(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delays(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delays(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delays(20);
}
//延时函数
void delays(uint i)
{
while(i--);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -