赞
踩
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式
导盲设备的研发一直是各国科研的一个重点,不仅是因为它有重大的社会意义,还因为它对于机器人视觉等多个研究领域有着不小的研究意义,能够给人类提供道路信息的导盲设备,在自动化机器人上也能起到同样的效果。有许多研究已经有了成功的案例。
本设计采用STC89C51单片机作为主控板,HC-SR04超声测距传感器作为探测装置,达到导盲的效果。这款仪器结构简单,功能可靠,它可以对前方的障碍物进行探测,在达到预设范围时蜂鸣器会提醒使用者小心障碍物,从而达到智能导盲的效果。
关键词:STC89C51单片机 HC-SR04超声测距传感器 智能拐杖
主控板- 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元器件清单
下图是该硬件部分的原理图,每一个模块所对应的管脚所对应的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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。