打印

红外测距传感器基于AT89C51的仿真

[复制链接]
1522|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
df_flying| | 2014-4-11 14:32 | 只看该作者
多测几个点,进行软件矫正吧,传感器一般都不是线性的。

使用特权

评论回复
板凳
wyh000aini| | 2014-4-11 14:47 | 只看该作者
仿真做的只是电路有没有问题,不能实际测出数据

使用特权

评论回复
地板
dirtwillfly| | 2014-4-11 16:25 | 只看该作者
软件仿真测不了实际距离的。
可以用实物电路多采集几个距离,然后对比实际距离进行优化和校准

使用特权

评论回复
5
jiagaokui|  楼主 | 2014-4-11 18:46 | 只看该作者
也连了实际电路,只是电压变化很灵敏,距离并不随着电压对应变化,而是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';

}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

5

帖子

0

粉丝