基于单片机的智能拐杖软件设计
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式
文章目录
- 概要
- 一、整体设计方案
- 2.1本设计设计原理
- 2.1.1单片机基本介绍
- 二、本设计方案选择
- 三、软件设计
- AD原理图:
- 原理图
- 程序
- 四、结论
- 五、 文章目录
概要
导盲设备的研发一直是各国科研的一个重点,不仅是因为它有重大的社会意义,还因为它对于机器人视觉等多个研究领域有着不小的研究意义,能够给人类提供道路信息的导盲设备,在自动化机器人上也能起到同样的效果。有许多研究已经有了成功的案例。
本设计采用STC89C51单片机作为主控板,HC-SR04超声测距传感器作为探测装置,达到导盲的效果。这款仪器结构简单,功能可靠,它可以对前方的障碍物进行探测,在达到预设范围时蜂鸣器会提醒使用者小心障碍物,从而达到智能导盲的效果。
关键词:STC89C51单片机 HC-SR04超声测距传感器 智能拐杖
一、整体设计方案
2.1本设计设计原理
2.1.1单片机基本介绍
主控板- ST STC89C51系列是由STC公司制造的STC89C51兼容的8位微控制器(μC)系列。
基于8051内核,由于其行业标准指令集,低单位成本以及DIL(DIP)封装中的这些芯片的可用性,因此AT89系列仍然非常受欢迎。这允许在新应用程序中重新使用大量的旧代码而不进行修改。虽然比较新的AT90系列AVR RISC微控制器的功能较弱,但AT89系列的新产品开发继续为上述优点。
虽然英特尔不再生产8051核心控制器或其衍生产品,但众多供应商制造的增强型二进制兼容衍生产品仍然受欢迎,如STC的STC89C51及其衍生产品,恩智浦P89v51及其衍生产品等。一些衍生产品集成了数字信号处理器(DSP)。 除了这些物理设备,几家公司还提供MCS-51衍生产品作为FPGA核心,用于FPGA或ASIC设计。
2.1.2引脚功能介绍
图2.1 AT89C51引脚图
(1)4 KB芯片程序存储器。
(2)128字节片上数据存储器(RAM)。
(3)32个字节专用于注册库。
(4)16位可位寻址存储器。
(5)80字节的通用存储器。
(6)4组并行I/O端口。
(7)128个用户定义的软件标志。
(8)8位数据总线。
(9)16位地址总线。
(10)16位定时器(通常为2,但可能有更多或更少)。
(11)3个内部和2个外部中断。
(12)位和字节可寻址RAM区域为16字节。
(13)四个8位端口(短型号有两个8位端口)。
(14)16位程序计数器和数据指针。
(15)1微秒指令周期,12 MHz晶振。
(16)8051的变体还可以有一些特殊的特定模型,如UART,ADC,Op_Amps等,使其成为更强大的微控制器。
这个芯片一共有四十个引脚,并且引脚的排列顺序为靠进芯片的缺口的左边那一列引脚逆时针开始数起,依次为1、2、3、……40,其中芯片的1脚顶上有个凹起的点。在单片机的40个引脚中,电源引脚有2根,外接晶体振荡器引脚有2根,控制引脚有4根以及4组8位可编程I/O引脚有32根。
各个引脚的功能为:VCC(40):电源输入,接+5V电源;GND(20):接地线;XTAL1(19):片内振荡电路的输入端;XTAL2(20):片内振荡电路的输出端;RST/VPP(9):用于将微控制器复位到其初始值;ALE/PROG(30):地址锁存的允许信号;PSEN(29):外部存储器的读选通信号;EA/VPP(31):程序存储器的内外部选通,接高电平从内部程序存储器读指令,接低电平则从外部程序存储器读指令;PO口(39~32):8位双向I/O口线,名称分别为P0.0~P0.7;P1口(1~8):8位准双向I/O口线,名称分别为P1.0~P1.7 ;P2口(21~28):8位准双向I/O口线,名称分别为P2.0~P2.7 ;P3口(10~17):8位准双向I/O口线,名称分别为P3.0~P3.7。
二、本设计方案选择
2.2.1硬件部分
下图是该硬件系统的元器件清单
图2.4元器件清单
三、软件设计
AD原理图:
原理图
下图是该硬件部分的原理图,每一个模块所对应的管脚所对应的I/O口都已标注清楚,下面将详细介绍每一个模块的作用。
程序
主函数源代码:
#include "main.h"/*----------------------------------------------** 宏定义 **----------------------------------------------*/
#define BEEP_ON ( 1 )
#define BEEP_OFF ( 0 )#define BUTTON_NUM_ALARM_INC ( 0 )
#define BUTTON_NUM_ALARM_DEC ( 1 )sbit beep_pin = P2^0;
/*----------------------------------------------** 枚举定义 **----------------------------------------------*//*----------------------------------------------** 结构体定义 **----------------------------------------------*//*----------------------------------------------** 外部函数原型说明 **----------------------------------------------*//*----------------------------------------------** 内部函数原型说明 **----------------------------------------------*//*----------------------------------------------** 全局变量 **----------------------------------------------*/
time_event_define(key_loop);
button_event_define(key_distance_alarm_inc);
button_event_define(key_distance_alarm_dec);
time_event_define(get_distance);
static uint16_t distance;
static uint8_t display_buf[16];
static uint16_t alarm_distance = 30;
/*----------------------------------------------** 常量定义 **----------------------------------------------*//*---------------------------------------------------------------------------*/
/**
*@brief 处理按键事件
*
*
*@param key_num:按键编号
*@param button_event:参考 button_event_t
*
*@return static
*
*
*@note
*
*/
static void button_response_handle(uint8_t key_num, button_event_t button_event)
{switch(key_num){case BUTTON_NUM_ALARM_INC:if(button_event == BUTTON_PRESS_DOWN){INC_LIMIT(alarm_distance, 100);sprintf(display_buf, "%ucm ", alarm_distance);lcd1602_display_string(sizeof("Alarm:") - 1, 1, display_buf);}break;case BUTTON_NUM_ALARM_DEC:if(button_event == BUTTON_PRESS_DOWN){DEC_LIMIT(alarm_distance, 10);sprintf(display_buf, "%ucm ", alarm_distance);lcd1602_display_string(sizeof("Alarm:") - 1, 1, display_buf);}break;}
}
/*---------------------------------------------------------------------------*/
/**
*@brief 查询按键是否按下
*
*
*@param none
*
*@return
*
*
*@note
*
*/
static void key_loop_handle(void)
{button_event_scan(key_distance_alarm_inc, BUTTON_NUM_ALARM_INC, get_key_value, button_response_handle);button_event_scan(key_distance_alarm_dec, BUTTON_NUM_ALARM_DEC, get_key_value, button_response_handle);time_event_start(key_loop);
}
/*---------------------------------------------------------------------------*/
/**
*@brief 获得超声波传感器数据
*
*
*@param none
*
*@return
*
*
*@note
*
*/
static void get_distance_data(void)
{distance = get_ultrasonic_distance();printf("distance = %u\r\n", distance);time_event_start(get_distance);
}
/*---------------------------------------------------------------------------*/
/**
*@brief 显示查询
*
*
*@param none
*
*@return
*
*
*@note
*
*/
static void display_loop(void)
{static uint16_t distance_bak;if(distance_bak != distance){distance_bak = distance;sprintf(display_buf, "%ucm ", distance);lcd1602_display_string(sizeof("Distance:") - 1, 0, display_buf);}
}
/*---------------------------------------------------------------------------*/
/**
*@brief 显示固定字符
*
*
*@param none
*
*@return
*
*
*@note
*
*/
static void display_fix_string(void)
{lcd1602_display_string(0, 0, "Distance:");lcd1602_display_string(0, 1, "Alarm:");sprintf(display_buf, "%ucm ", alarm_distance);lcd1602_display_string(sizeof("Alarm:") - 1, 1, display_buf);
}
/*---------------------------------------------------------------------------*/
/**
*@brief 告警查询
*
*
*@param none
*
*@return
*
*
*@note
*
*/
static void alarm_loop(void)
{if(distance < alarm_distance){beep_pin = BEEP_ON;}else{beep_pin = BEEP_OFF;}
}
/*---------------------------------------------------------------------------*/
/**
*@brief 程序入口
*
*
*@param none
*
*@return
*
*
*@note 程序入口函数main
*
*/
void main(void)
{beep_pin = BEEP_OFF;uart_init();printf("Init...\r\n");lcd1602_init();ultrasonic_drv_init();timer0_mode1_init();__enable_irq();display_fix_string();get_distance_data();time_event_start(key_loop);while(1){time_event_loop(key_loop, key_loop_handle, 20);time_event_loop(get_distance, get_distance_data, 1000);display_loop();alarm_loop();}
}/*---------------------------------------------------------------------------*/
void timer0_irq(void)
{++clock_ticks;
}
/*---------------------------------------------------------------------------*/
/**
*@brief 串口接收中断处理
*
*
*@param ch 串口接收到的字符
*
*@return
*
*
*@note
*
*/
void uart_rx_irq(uint8_t ch)
{ch = ch;//uart_put_char(ch);
}
/*---------------------------------------------------------------------------*/
/**
*@brief 串口发送中断处理
*
*
*@param none
*
*@return
*
*
*@note
*
*/
void uart_tx_irq(void)
{}
四、结论
超声波测距所使用的原理非常简单,即利用超声波收发模块作为传感器,以51系列单片机作为核芯计算机,测定超声波的传播时间来计算出传播距离,然后在显示器(数码管显示器并不是给使用者观看,更多的是给开发者以便利和蜂鸣器上显示出来。实际上本设计所制作的超声导盲系统测定的是从一个“点”到反射面的距离,对于在“线”(例如半空中的钢丝、电线等)以及“点”(例如悬挂的小号霓虹灯)等更小的物体难以进行有效的测量,关于这方面的测定,还需要更复杂的系统来进行检测。
五、 文章目录
目录
1前言 1
1.1研究背景与意义 1
1.2在国内外的发展概况及分析 2
1.2.1导盲杖 2
1.2.2导盲眼镜 3
1.2.3触觉鞋与智能手机 3
1.2.4现状分析 4
1.3本设计应解决的主要问题 6
2本设计 7
2.1本设计设计原理 7
2.1.1单片机基本介绍 7
2.1.2引脚功能介绍 8
2.1.3超声波测距和光学测距的分析对比 9
2.2本设计方案选择 12
2.2.1硬件部分 12
2.2.2Keil软件 15
2.2.3软件程序主要部分及编写思路 16
2.2.4测试数据 20
3.结论 22
4参考文献 24
5谢辞 25
6附录 26
相关文章:

基于单片机的智能拐杖软件设计
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、整体设计方案2.1本设计设计原理2.1.1单片机基本介绍 二、本设计方案选择三、软件设计AD原理图:原理图…...

小程序如何设置自动预约快递
小程序通过设置自动预约功能,可以实现自动将订单信息发送给快递公司,快递公司可以自动上门取件。下面具体介绍如何设置。 在小程序管理员后台->配送设置处,选择首选配送公司。为了能够支持自动预约快递,请选择正常的快递公司&…...

STM32-HAL库08-TIM的输出比较模式(输出PWM的另一种方式)
STM32-HAL库08-TIM的输出比较模式(输出PWM的另一种方式) 一、所用材料: STM32F103C6T6最小系统板 STM32CUBEMX(HAL库软件) MDK5 示波器或者逻辑分析仪 二、所学内容: 通过定时器TIM的输出比较模式得到预…...

【数据结构】深入浅出讲解计数排序【图文详解,搞懂计数排序这一篇就够了】
计数排序 前言一、计数排序算法核心思路映射 概念补充绝对映射相对映射 二、计数排序算法核心实现步骤三、码源详解四、效率分析(1)时间复杂度 — O(Max(N,range))(2)空间…...

Canvas制作喷泉效果示例
Canvas能制作出很多动画效果,下面是一个制作喷泉效果的示例 效果图 源代码 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <meta name"viewport" content"widthdevice-width, initial-scale1 ,user-…...

什么是NPM(Node Package Manager)?它的作用是什么?
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

oracle如果不适用toad或者plsql工具如何获取索引建表语句
select dbms_lob.substr(dbms_metadata.get_ddl(INDEX,INDEX_NAME,DIXON))||; from dba_indexes where ownerDIXON这个语句可以获取dixon用户的所有索引创建语句,sql脚本形式呈现 点开一个语句查看 如果不使用dbms_lob.substr这个函数最后得到是一个clob selec…...

某大厂伺服驱动器量产方案
本文介一款大厂量产伺服驱动器方案!带2500线省线式编码器,17位增量编码器,20位绝对值编码器!标配CANopen、高精度运动控制,高速总线通讯,主芯片28335FPGA,已验证过,带can和485通讯&a…...

【计算机网络】网络层:数据平面
一.网络层概述 每台路由器的数据平面的主要功能时从其输入链路向其输出链路转发数据报,控制平面的主要功能是协调这些本地的每路由转发动作,使得数据报沿着源和目的地主机之间的路由器路径最终进行端到端传送。 网络层不运行运输层和应用层协议。 转发是…...

Path with “WEB-INF“ or “META-INF“: [webapp/WEB-INF/NewFile.html]
2023-11-04 01:03:14.523 WARN 10896 --- [nio-8072-exec-6] o.s.w.s.r.ResourceHttpRequestHandler : Path with "WEB-INF" or "META-INF": [webapp/WEB-INFNewFile.html] spring.mvc.view.prefix:/webapp/WEB-INF/...
百度OCR 接口调用 提示 216101:param image not exist 问题解决
百度提供的文档并没有描述如何解决,例子也是,用工具请求可以通 axios 请求 需要用FormData 传参 let token await getAccessToken() //官网案例那个 请求token// console.log(token, "token");var formData new FormData();// imageBase64 :Base64 图片数据formD…...
1-10 HTML中input属性
HTML中input属性 text:用于接受单行文本输入password:用于密码输入,输入字符会被掩盖radio:用于单选按钮,用户可以在一组选项中选择一个checkbox:用于复选框,用户可以选择多个选项number&#…...

共焦显微镜使用
x.1 细胞培养 x.2 样品制备 以细菌为例,我们使用荧光染色细菌,静置15分钟。 15分钟后我们使用实验室的专用培养皿,选择吸收100uL的溶液滴在在培养皿中心。 x.3 显微镜使用 我们按照1, 2, 3, 4的顺序打开显微镜, 打开电脑&…...

windows + Mingw32-make 编译 PoDoFo库,openssl, libjpeg, Msys2工具的使用
参考: https://blog.csdn.net/sspdfn/article/details/104244306 https://blog.csdn.net/yaoyuanyylyy/article/details/17436303 https://blog.csdn.net/wxlfreewind/article/details/106492253 前期进行了各种摸索,由于Podofo依赖库比较多,…...

C++中图的存储
文章目录 0. 实例图1. 邻接矩阵2. 邻接矩阵2.1 链表数组2.2 链式前向星 3. 参考 0. 实例图 考虑下面这样一个图 1. 邻接矩阵 vis[i][j] 表示从i 到j有一条边。直接用二维数组就可以了。 using namespace std; int vertex_num 5; vector<vector<int>> graph(v…...
西瓜书读书笔记整理(七)—— 第七章 贝叶斯分类器
第七章 贝叶斯分类器 7.1 贝叶斯决策论(Bayesian Decision Theory)7.1.1 先验概率(Prior Probability)7.1.2 后验概率(Posterior Probability)7.1.3 似然度(Likelihood)7.1.4 决策规…...
C#WPF嵌套布局实例
本文演示C#WPF嵌套布局实例。演示了不同布局的简单用法,便于快速应用和掌握。 <Windowx:Class="LayoutDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/x…...

Spring和SpringMVC总结
一、Spring IoC(Inversion of Control)中文名称:控制反转(对象的创建交给Spring管理)。DI(dependency injection )依赖注入。容器(Container):放置所有被管理的对象。beans:容器中所有被管理的对…...

C++标准模板(STL)- 类型支持 (类型属性,is_abstract,is_signed,is_unsigned)
类型特性 类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实例…...
前端复制带上版权信息
前端复制带上版权信息 当用户复制内容时,自动添加版权信息。 HTML内容 <body><h1 inputmode"text">复制我</h1> </body>Js内容 document.addEventListener("copy", (event) > {event.preventDefault(); // 阻止…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...