也连了实际电路,只是电压变化很灵敏,距离并不随着电压对应变化,而是10cm的增加(范围10—80cm),以下是计算程序,还望大家帮忙看一下!
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define disdata P3 //显示数据码输出口
sbit SCL = P1^5; // 将p1.5口模拟时钟口
sbit SDA = P1^6; // 将p1.6口模拟数据口
bit askflag;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uint data dis[4] = {0x00,0x00,0x00,0x00}; //定义3个显示数据单元和1个数据存储单元
float L[3];
uint L2;
uchar L0,L1;
uchar code dis0[] = {"GP2D12"};
uchar code dis1[] = {"V= . V,L= . CM"};
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
bit bdata SystemError; //从机错误标志位
/*********************** PCF8591专用变量定义 ***********************/
#define PCF8591_WRITE 0x90
#define PCF8591_READ 0x91
#define NUM 4 //接收和发送缓存区的深度
uchar idata receivebuf[NUM]; //数据接收缓冲区
/************************** 延时函数 *******************************/
void delay(uint ms)
{
uint x,y;
for(x=0;x<ms;x++)
for(y=0;y<110;y++);
}
/*********************** 检察LCD忙碌状态 **************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P3&0x80);
LCD_EN = 0;
return(result);
}
/************************* LCD写指令函数 **************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P3 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/************************* LCD写数据函数 **************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P3 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/************************* LCD初始化函数 **************************/
void lcd_init()
{
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c);
delay(5);
lcd_wcmd(0x06);
delay(5);
lcd_wcmd(0x01);
delay(5);
}
/********************* LCD设定显示地址函数 ************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
}
/*************将采集到的数据进行16进制转换为ASCLL码****************/
show_value(uchar ad_data)
{
dis[2] = ad_data/51; //AD值转换为3位BCD码,最大为5.00V
L[2] = dis[2];
dis[2] = dis[2]+0x30; //转换为ACSII码
dis[3] = ad_data%51; //余数暂存
dis[3] = dis[3]*10; //计算小数第一位
dis[1] = dis[3]/51;
L[1] = dis[1]*0.1;
dis[1] = dis[1]+0x30; //转换为ACSII码
dis[3] = dis[3]%51;
dis[3] = dis[3]*10; //计算小数第二位
dis[0] = dis[3]/51;
L[0] = dis[0]*0.01;
dis[0] = dis[0]+0x30; //转换为ACSII码
L2 = (1/(L[2]+L[1]+L[0]))*2.5;
L1 = L2/10+'0';
L0 = L2%10+'0';
}
|