基于单片机的智能拐杖软件设计
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 技术交流认准下方 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(); // 阻止…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...