【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; }
|
~~#### 仿真资源和程序源码
🌼更新程序
- 🌿修复了仿真是短路的问题,添加了转换后的距离值显示,但是显示不准确,电压值显示还是比较准确。

- ⚡注意:更新的资源是基于
8.12版本。
1 2 3
| 链接:https://pan.baidu.com/s/1efCSlaPCqP9zZef8euZ9tw 提取码:i1nj
|
| 路是自己选的,所以即使以后会跌倒,会受伤,也都要学会自己承受,自己疗伤。我们都是这样,学会长大的。 |
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!