用c51写基于温度补偿的超声波测距系统的代码,传感器用DS18B20和HC-SR04,显示用LC0612
时间: 2024-03-05 20:48:47 浏览: 112
基于C51单片机的DS18B20温度传感器显示
好的,下面是一个基于C51单片机的温度补偿超声波测距系统的示例代码。在这个代码中,我们使用一个DS18B20数字温度传感器来测量环境温度,并使用该温度值来进行超声波测距的温度补偿。同时,我们使用一个HC-SR04超声波传感器来进行距离测量,使用LC0612 OLED模块来显示测量结果。
```
#include <REGX51.H>
#include <intrins.h>
#define DS18B20 DSPORT=P2^7
sbit DSPORT=P2^0;
sbit TRIG=P2^1;
sbit ECHO=P2^2;
sbit SCL=P1^0;
sbit SDA=P1^1;
unsigned char temp;
unsigned char TH,TL;
unsigned int distance;
unsigned char code ASCII[10][8]={
{0x7E,0x81,0x81,0x81,0x81,0x81,0x81,0x7E}, //0
{0x00,0x41,0xFF,0x01,0x00,0x00,0x00,0x00}, //1
{0x43,0x85,0x89,0x91,0x61,0x00,0x00,0x00}, //2
{0x42,0x81,0x91,0x91,0x6F,0x00,0x00,0x00}, //3
{0x0C,0x14,0x24,0x44,0xFF,0x04,0x04,0x00}, //4
{0xF1,0x91,0x91,0x91,0x8E,0x00,0x00,0x00}, //5
{0x3E,0x51,0x91,0x91,0x0E,0x00,0x00,0x00}, //6
{0x80,0x80,0x8F,0x90,0xA0,0xC0,0x00,0x00}, //7
{0x6E,0x91,0x91,0x91,0x6E,0x00,0x00,0x00}, //8
{0x70,0x89,0x89,0x8A,0x7C,0x00,0x00,0x00} //9
};
void delay_10us(unsigned char t);
void delay_ms(unsigned int t);
void I2CStart();
void I2CStop();
void I2CACK(bit ack);
bit I2CWrite(unsigned char dat);
unsigned char I2CRead();
bit Ds18b20Init();
void Ds18b20WriteByte(unsigned char dat);
unsigned char Ds18b20ReadByte();
void Ds18b20ChangTemp();
unsigned int GetDistance();
void OLEDWriteCmd(unsigned char cmd);
void OLEDWriteData(unsigned char dat);
void OLEDInit();
void OLEDShowNum(unsigned char x,unsigned char y,unsigned int num);
void main()
{
OLEDInit();
while(1)
{
TH0=0;
TL0=0;
TRIG=0;
delay_10us(2);
TRIG=1;
delay_10us(10);
TRIG=0;
while(!ECHO);
TH=TL0;
while(ECHO);
TH-=(unsigned char)110-temp;
distance=TH*256+TL0;
distance/=58;
OLEDShowNum(0,0,distance); //显示距离
delay_ms(200);
}
}
void delay_10us(unsigned char t)
{
while(t--)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void delay_ms(unsigned int t)
{
while(t--)
delay_10us(100);
}
void I2CStart()
{
SDA=1;
SCL=1;
SDA=0;
SCL=0;
}
void I2CStop()
{
SDA=0;
SCL=1;
SDA=1;
}
bit I2CWrite(unsigned char dat)
{
unsigned char i;
bit ack;
for(i=0;i<8;i++)
{
SDA=dat&0x80;
SCL=1;
_nop_();
_nop_();
SCL=0;
dat<<=1;
}
SDA=1;
SCL=1;
ack=SDA;
SCL=0;
return ack;
}
unsigned char I2CRead()
{
unsigned char i,dat=0;
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;
dat<<=1;
dat|=SDA;
SCL=0;
}
return dat;
}
void I2CACK(bit ack)
{
SDA=!ack;
SCL=1;
_nop_();
_nop_();
SCL=0;
SDA=1;
}
void Ds18b20WriteByte(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DSPORT=0;
_nop_();
_nop_();
DSPORT=dat&0x01;
_nop_();
_nop_();
DSPORT=1;
dat>>=1;
}
}
unsigned char Ds18b20ReadByte()
{
unsigned char i,dat=0;
for(i=0;i<8;i++)
{
DSPORT=0;
_nop_();
_nop_();
dat>>=1;
if(DSPORT)
dat|=0x80;
_nop_();
_nop_();
DSPORT=1;
}
return dat;
}
bit Ds18b20Init()
{
bit initflag=0;
DSPORT=1;
delay_10us(20);
DSPORT=0;
delay_10us(200);
DSPORT=1;
delay_10us(20);
initflag=DSPORT;
delay_10us(20);
return initflag;
}
void Ds18b20ChangTemp()
{
Ds18b20Init();
Ds18b20WriteByte(0xcc);
Ds18b20WriteByte(0x44);
}
unsigned int GetDistance()
{
unsigned int distance;
TH0=0;
TL0=0;
TRIG=0;
delay_10us(2);
TRIG=1;
delay_10us(10);
TRIG=0;
while(!ECHO);
TH=TL0;
while(ECHO);
TH-=(unsigned char)110-temp;
distance=TH*256+TL0;
distance/=58;
return distance;
}
void OLEDWriteCmd(unsigned char cmd)
{
I2CStart();
I2CWrite(0x78);
I2CACK(1);
I2CWrite(0x00);
I2CACK(1);
I2CWrite(cmd);
I2CACK(1);
I2CStop();
}
void OLEDWriteData(unsigned char dat)
{
I2CStart();
I2CWrite(0x78);
I2CACK(1);
I2CWrite(0x40);
I2CACK(1);
I2CWrite(dat);
I2CACK(1);
I2CStop();
}
void OLEDInit()
{
OLEDWriteCmd(0xAE);//display off
OLEDWriteCmd(0x20);//Set Memory Addressing Mode
OLEDWriteCmd(0x10);//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
OLEDWriteCmd(0xb0);//Set Page Start Address for Page Addressing Mode,0-7
OLEDWriteCmd(0xc8);//Set COM Output Scan Direction
OLEDWriteCmd(0x00);//---set low column address
OLEDWriteCmd(0x10);//---set high column address
OLEDWriteCmd(0x40);//--set start line address
OLEDWriteCmd(0x81);//--set contrast control register
OLEDWriteCmd(0xff);
OLEDWriteCmd(0xa1);//--set segment re-map 0 to 127
OLEDWriteCmd(0xa6);//--set normal display
OLEDWriteCmd(0xa8);//--set multiplex ratio(1 to 64)
OLEDWriteCmd(0x3f);//--1/64 duty
OLEDWriteCmd(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
OLEDWriteCmd(0xd3);//-set display offset
OLEDWriteCmd(0x00);//-not offset
OLEDWriteCmd(0xd5);//--set display clock divide ratio/oscillator frequency
OLEDWriteCmd(0xf0);//--set divide ratio
OLEDWriteCmd(0xd9);//--set pre-charge period
OLEDWriteCmd(0x22); //
OLEDWriteCmd(0xda);//--set com pins hardware configuration
OLEDWriteCmd(0x12);
OLEDWriteCmd(0xdb);//--set vcomh
OLEDWriteCmd(0x20);//0x20,0.77xVcc
OLEDWriteCmd(0x8d);//--set DC-DC enable
OLEDWriteCmd(0x14);
OLEDWriteCmd(0xaf);//--turn on oled panel
}
void OLEDShowNum(unsigned char x,unsigned char y,unsigned int num)
{
unsigned char i;
for(i=0;i<5;i++)
OLEDWriteData(ASCII[num/10000][i]);
OLEDWriteData(0);
for(i=0;i<5;i++)
OLEDWriteData(ASCII[(num%10000)/1000][i]);
OLEDWriteData(0);
for(i=0;i<5;i++)
OLEDWriteData(ASCII[(num%1000)/100][i]);
OLEDWriteData(0);
for(i=0;i<5;i++)
OLEDWriteData(ASCII[(num%100)/10][i]);
OLEDWriteData(0);
for(i=0;i<5;i++)
OLEDWriteData(ASCII[num%10][i]);
OLEDWriteCmd(0xb0+y);
OLEDWriteCmd(((x&0xf0)>>4)|0x10);
OLEDWriteCmd((x&0x0f)|0x00);
}
```
请注意,这只是一个示例代码,并不能保证在所有情况下都能正确工作。在编写实际应用代码时,请根据具体情况进行调整和优化。
阅读全文