最近需要拿超声波写一个避障的部分,打算拿arduino来写但是板子还在路上,用51单片机来写就需要拿液晶来显示,于是就在网上找了一大堆资料来学,也参考了很多前人的代码,最后把在这过程中查阅读一部分资料整理出来,作为记录。
图片来自网络,侵删。
HC-SR04模块
超声波模块使用原理
- IO口和TRIG两个接口触发测距,给10μs高电平信号
- 模块自动发送8个4kHz方波,自动检测有无信号返回
- 有信号返回,通过IO口给ECHO口输出一个高电平,高电平持续时间为超声波发出到返回时间,测距距离=(高电平持续时间*声速(340M/S))/2
超声波模块时序图
HC-SR04模块引脚
超声波模块共有四个引脚:
- VCC 提供5v电源
- GND 地线
- TRIG 触发控制,信号输入
- ECHO 回响信号输入
HC-SR04模块参数
- 额定电压:5V
- 静态工作电流:2mA
- 感应角度:小于15°
- 探测距离:2cm-400cm
- 精度:0.3cm
- 盲区:<2cm
误差分析
- 盲区:当被测物体与超声波模块探头距离足够近的时候,发射出去的声波会在超声波探头与被测物体之间来回反射,此时串口监视器返回负值.
- 被测物体的材质:当被测物体表面积小于0.5m²或者是表面过于粗糙,都会影响到超声波测距的返回值.
- 反射:(1)三角误差:大部分时候超声波和被测物体之间都存在一个夹角,所测得的距离不是一个直线距离而是带有三角误差(2)多次反射:存在于墙角,所测得距离可能是被多次反射之后才被接收到.
- 噪音:轮子与地面摩擦产生的高频噪音,不同超声波之间的干扰.
- 余震:也可以理解为抖动现象,与探头,外壳甚至电路干扰都有关系.表现为在串口监视器返回的数据中突然出现不是与其他数据产生极大偏差的数据.
解决方案
查阅资料之后网络上提供的大部分方案是算术平均滤波或者是求方差之后取方差较小区域作为返回值。
我在此使用的是算术平均滤波,通俗地讲就是多次测量取平均值。返回N个测量值之后平均,优点是能够在一定程度上让测量结果更准确,但是缺点是占用大量RAM值。
LCD1602模块
LCD1602引脚
编号 | 符号 | 说明 | 编号 | 符号 | 说明 |
---|---|---|---|---|---|
1 | VSS | 电源地 | 9 | D2 | 数据 |
2 | VDD | 电源正极 | 10 | D3 | 数据 |
3 | VL | 液晶显示偏压 | 11 | D4 | 数据 |
4 | RS | 数据/命令选择 | 12 | D5 | 数据 |
5 | RW | 读/写选择 | 13 | D6 | 数据 |
6 | E | 使能信号 | 14 | D7 | 数据 |
7 | D0 | 数据 | 15 | BLA | 背光源正极 |
8 | D1 | 数据 | 16 | BLK | 背光源负极 |
- VDD接5V正电源
- VL是对比度调整端,接正电源对比度最弱,接地对比度最高,对比度过高会产生“白影”,在链接一个10K电位器来调节对比度
- RS寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器
- RW读写选择;高电平进行读操作,低电平进行写操作。(在这里我们只写不读,所以RW=0即可)
- E为使能端,当E端从高电平变成低电平,液晶模块执行命令
- D0-D7为双向数据线。
- BLA/BLK为背光源正负极
LCD1602参数
显示容量:162个字符(1602)
芯片工作电压:4.5-5.5V
模块最佳工作电压:5.0V
工作电流:2.0mA
字符尺寸:2.954.35(W*H)mm
LCD1602指令集
编号 | 指令 | RS | RW | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 清屏 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
2 | 光标返回 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | * |
3 | 置输入模式 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S |
4 | 显示开关控制 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B |
5 | 光标或字符位移 | 0 | 0 | 0 | 0 | 0 | 1 | S/C | R/L | * | * |
6 | 置功能 | 0 | 0 | 0 | 0 | 1 | DL | N | F | * | |
7 | 置字符发生存储地址 | 0 | 0 | 0 | 1 | ||||||
8 | 置数据存储器地址 | 0 | 0 | 1 | |||||||
9 | 读忙标志或地址 | 0 | 1 | BF | |||||||
10 | 写数据到CGRAM | 1 | 0 | ||||||||
- 清显示屏,指令码01H,光标复位到00H位置
- 光标复位,光标返回地址00H
- 光标和显示模式设置:I/D:高电平右移,低电平左移;S:高电平屏幕上所有文字左移或右移,低电平无效
- 显示开关控制:D:高电平整体显示开,低电平整体显示关;C:高电平显示光标,低电平关闭光标;B:高电平光标闪烁,低电平光标不闪烁
- 光标显示与位移:S/C:高电平移动显示文字,低电平移动光标
- 功能设置命令 DL:高电平时为 4 位总线,低电平时为 8 位总线 N:低电平时为单行显示,高电平时双行显示 F: 低电平时显示 5x7 的点阵字符,高电平时显示 5x10 的点阵字符
- 设置字符发生器RAM地址
- DDRAM地址设置
- 读忙信号与光标地址:BF:高电平忙,不能接受命令和数据,低电平为不忙
- 写数据
LCD1602时序图
- 左侧字母对应IO口
- 线交叉表示电平变化,在上为高电平,在下为低电平
- Valid Date 有效数据
LCD1602映射关系
80H为第一行第一位的地址,那么第一行第二位就是0x80+1;第二行第一位就是0x80+40.
LCD1602字库
代码部分
#incl