【Proteus仿真】51单片机+红外测距仪(GP2D12)+ADC0808模数转换

【Proteus仿真】51单片机+红外测距仪(GP2D12)+ADC0808模数转换


  • 📍相关篇《【Proteus仿真】51单片机+超声波测距+ 带报警按键可调
  • 🎞Proteus仿真演示
    在这里插入图片描述
  • ✨使用GP2D12测量距离,与输出模拟电压关系:2.35V ~ 0.41V模拟信号对应10cm~80cm,输出与距离成反比非线性关系。
  • ⚡目前该仿真还存在bug,根据仿真来看,lcd显示有短路,后续进行修正。
  • ✨ 利用红外测距仪(GP2D12)模型输出模拟信号,ADC0808进行模数转换,编写程序运用51单片机实现控制,最后将数字信号输出到LCD1602液晶屏上.。

🛠仿真精度调节说明

  • 🔰在仿真中,GP2D12的值和ADC采集的电压值,在一些区段不是成线性关系,导致读取和转换的值存在误差。
👉由于显示精度的问题,在默认情况下操作是每按3下,LCD显示面板的数值才会有变化,如果想实现每调节按下一次,LCD显示值立即更新显示,可以将GP2012模块的参数进行如下调整:
  • 鼠标移动到GP2D12器件上,鼠标右键,点击编辑属性
    在这里插入图片描述
  • 🌿将步进调整为2或者3,也就是每按下调节一次,数值增减2或3.
    在这里插入图片描述

📑仿真器件

  • 🌿红外测距仪(GP2D12 红外测距传感器)
  • 🌿ADC0809模数转换芯片,(本利采用的是通道0,与红外测距传感器输出引脚相连通,进行数据采集)
  • 🌿LCD1602
  • 相关器件ADC0808,

  • ✨如果使用低版本的Proteus平台没有ADC0809器件,可以使用ADC0808替代,ADC0808是ADC0809的简化版,主要的不同点是ADC0808的转换输出out0~7与常用的输出端高低位是相反的,即ADC0809的最低位是out0,ADC0808的最低位是out7。所以在仿真中,可以做到ADC0808取代ADC0809。

📝程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include <reg52.h>
#include <intrins.h> //包含NOP空指令函数\_nop\_
#include<stdio.h>

typedef bit BOOL;

#define uchar unsigned char
#define uint unsigned int

sbit eoc=P3^0;
sbit oe =P3^1;
sbit st =P3^2;

sbit clk=P3^6;

sbit rs=P0^7;
sbit rw=P0^6;
sbit ep=P0^5;

uchar code table[]="0123456789";
uint ad_0809,a1,a2,a3;
uchar out;

void delaynms(uint x);
void display();
void ad0809();


void delayms(uint x)
{
uint i,j;
for(i=x; i>0; i--)
for(j=110; j>0; j--);
}

void delay (int m)
{
unsigned char i,j;
for (i=0; i<m; i++)
for (j=0; j<253; j++);
}

BOOL lcd\_bz()
{
BOOL result;
rs=0; // 读忙信号
rw=1;
ep=1;
\_nop\_();
\_nop\_();
\_nop\_();
\_nop\_();
result = (BOOL)(P2&0x80);
ep=0;
return result ;
}

void lcd\_wcmd (uchar cmd)
{
while (lcd\_bz());
rs=0;
rw=0;
ep=0;
\_nop\_();
\_nop\_();
P2=cmd ;
\_nop\_();
\_nop\_();
\_nop\_();
\_nop\_();
ep=1;
\_nop\_();
\_nop\_();
\_nop\_();
\_nop\_();
ep=0;
}

void lcd\_pos (unsigned char pos)
{
lcd\_wcmd (pos|0x80);
}

void lcd\_wdat (unsigned char dat)
{
while (lcd\_bz());
rs=1;
rw=0;
ep=0;
\_nop\_();
\_nop\_();
P2=dat ;
\_nop\_();
\_nop\_();
\_nop\_();
\_nop\_();
ep=1;
\_nop\_();
\_nop\_();
\_nop\_();
\_nop\_();
ep=0;
}

void lcd\_init ()
{
lcd\_wcmd (0x38);
delay (1);
lcd\_wcmd (0x0c);
delay (1);
lcd\_wcmd (0x06);
delay (1);
lcd\_wcmd (0x01);
delay (1);
}

void main()
{
lcd\_init ();
delay (10);
TMOD=0X01;
TH0=(65536-2)/256;
TL0=(65536-2)%256;
EA=1;
ET0=1;
TR0=1;

while(1)
{
ad0809();
ad_0809=out;
display();

lcd\_pos (7);
lcd\_wdat(table[a1]);

lcd\_pos (8);
lcd\_wdat(table[a2]);

lcd\_pos (9);
lcd\_wdat(table[a3]);
}
}

void T0\_time()interrupt 1
{
TH0=(65536-2)/256;
TL0=(65536-2)%256;
clk=~clk;

}

void delaynms(uint x)
{
while(x-->0)
{
unsigned char k;
for(k=10; k>0; k--);
}
}


void display()
{
a1=(ad_0809\*49/25)/100; //the highest bit
a2=(ad_0809\*49/25)/10%10;
a3=(ad_0809\*49/25)%100%10;
}



void ad0809()
{

P1=0xff;//input
oe=0;
st=0;
st=1;//清0
st=0;//启动
delaynms(1);
while(!eoc); //eoc等于零的话,在这里等待直到eoc=1,结束循环,向下执行
oe=1;
out=P1;
oe=0;
}





~~#### 仿真资源和程序源码

  • 本实验基于Proteus8.9SP2平台。~~

🌼更新程序

  • 🌿修复了仿真是短路的问题,添加了转换后的距离值显示,但是显示不准确,电压值显示还是比较准确。
    在这里插入图片描述
  • ⚡注意:更新的资源是基于8.12版本。
1
2
3
链接:https://pan.baidu.com/s/1efCSlaPCqP9zZef8euZ9tw 
提取码:i1nj


路是自己选的,所以即使以后会跌倒,会受伤,也都要学会自己承受,自己疗伤。我们都是这样,学会长大的。