功能介绍:
0.本系统采用STC89C52作为单片机
1.导盲仗的上部和底部分别设置超声波传感器,利用超声波测距原理分别测得盲人面部和脚底离障碍物的距离,并将障碍信息通过语音播报传递给盲人
2.导盲杖设有光照传感器,利用光敏电阻测量环境光照,光照强度小于某个阈值时,自动打开导盲杖的照明LED灯带。以便引起行人及车辆注意。
3.在导盲杖的底部安装积水探测传感器,来检测积水,如果有积水则进行蜂鸣器报警,进而提醒盲人躲避积水。
4.导盲杖设有温度传感器,按键可语音播报当前温度,为盲人增添衣物提供参考。
5.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB:
主程序:
#include "main.h"
/*******************变量定义*********************/
sbit TRIG_1 = P2^4; //接口定义
sbit ECHO_1 = P2^5; //接口定义
sbit TRIG_2 = P1^1; //接口定义
sbit ECHO_2 = P1^0; //接口定义
float f_distance1 = 0; //距离1
float f_distance2 = 0; //距离2
int tempBuf = 0; //读取温度值
float temperature; //实际温度值
bit refreshFlag = 0;
bit sendFlag = 0;
unsigned int lightValue;
unsigned int waterValue;
char dis[32];
/********************************************************
函数名称:void mian()
函数作用:主函数
参数说明:
********************************************************/
void main()
{
BUZZER = ON;
LED = ON;
DelayS(1);
BUZZER = OFF;
LED = OFF;
TRIG_1 = 0;
TRIG_2 = 0;
Timer0_Init(); //初始化定时器0
Timer1_Init(); //初始化定时器1
UART_Init(); //初始化串口
DS18B20_Start();
DS18B20_GetTemp(&tempBuf);
temperature = (float)tempBuf * 0.0625; //温度值转换
while (1) //死循环
{
if (refreshFlag == 1)
{
refreshFlag = 0;
Measuring();
TR1 = 0;
if (f_distance1 <= 1500) //上方探测小于1500mm
{
UART_SendStr("注意前方障碍物\r\n", 16); //发送数据
DelayS(3);
}
if (f_distance2 <= 1500) //下方探测小于1500mm
{
UART_SendStr("注意脚下障碍物\r\n", 16); //发送数据
DelayS(3);
}
TR1 = 1;
if (lightValue < 40) //环境光低于40%
{
LED = ON;
}
else
{
LED = OFF;
}
if (waterValue > 10) //前方有积水
{
BUZZER = ON;
}
else
{
BUZZER = OFF;
}
}
if (KEY_TEMP == 0) //语音播报温度按键按下
{
DelayMs(20);
if (KEY_TEMP == 0)
{
TR1 = 0;
DS18B20_Start();
DS18B20_GetTemp(&tempBuf);
temperature = (float)tempBuf * 0.0625; //温度值转换
sprintf(dis, "当前温度%4.1f摄氏度\r\n", temperature); //打印温度值
UART_SendStr(dis, 20);
DelayS(2);
TR1 = 1;
}
while (!KEY_TEMP)
;
}
}
}
/************************* 定时器0初始化 *************************/
void Timer0_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = 0;
TL0 = 0;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 0; //定时器开关关闭
}
/************************* 定时器0中断 *************************/
void Timer0_Interrupt(void) interrupt 1
{
}
/************************* 定时器1初始化 *************************/
void Timer1_Init(void)
{
TMOD |= 0x10; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1 = (65536 - 9216) / 256; //重新赋值 10ms
TL1 = (65536 - 9216) % 256;
EA = 1; //总中断打开
ET1 = 1; //定时器中断打开
TR1 = 1; //定时器开关打开
}
/************************* 定时器1中断 *************************/
void Timer1_Interrupt(void) interrupt 3
{
static unsigned int time50ms = 0;
TL1 = 0x00; //设置定时初始值
TH1 = 0x4C; //设置定时初始值 50ms
time50ms++;
if (time50ms > 20)
{
refreshFlag = 1; //显示标志
time50ms = 0;
}
}
void Measuring(void)
{
static long cnt = 0; //定时器计数
TR1 = 0;
TRIG_1 = 1; //启动一次模块 //不可以使用其他终端 容易造成死循环
DelayUs10x(1);
TRIG_1 = 0;
while (!ECHO_1)
; //当RX为零时等待
TR0 = 1; //开启计数
while (ECHO_1)
; //当RX为1计数并等待
TR0 = 0;
cnt = (long)(TH0 * 256 + TL0);
TH0 = 0;
TL0 = 0;
f_distance1 = (float)cnt * 17 / 100.0 * 1.102; //算出来是mm (g_cnt * 340 / 2) / 1000.0 * 1.102;系数
cnt = 0;
TRIG_2 = 1; //启动一次模块 //不可以使用其他终端 容易造成死循环
DelayUs10x(1);
TRIG_2 = 0;
while (!ECHO_2)
; //当RX为零时等待
TR0 = 1; //开启计数
while (ECHO_2)
; //当RX为1计数并等待
TR0 = 0;
cnt = (long)(TH0 * 256 + TL0);
TH0 = 0;
TL0 = 0;
f_distance2 = (float)cnt * 17 / 100.0 * 1.102; //算出来是mm (g_cnt * 340 / 2) / 1000.0 * 1.102;系数
cnt = 0;
TR1 = 1;
lightValue = 100 - 100 * ReadADC(AIN0_GND) / 255; //光照强度
waterValue = 100 - 100 * ReadADC(AIN1_GND) / 255; //水滴值
}
/************************* 串口配置 *************************/
void UART_Init(void)
{
SCON = 0x50;
TH2 = 0xFF;
TL2 = 0xDB;
RCAP2H = 0xFF; //(65536-(FOSC/32/BAUD)) BAUD = 9600 FOSC = 11059200
RCAP2L = 0xDB;
/*****************/
TCLK = 1;
RCLK = 1;
C_T2 = 0;
EXEN2 = 0;
/*****************/
TR2 = 1;
ES = 1; //打开串口中断
EA = 1; //打开总中断
}
/************************* 串口发送字节 *************************/
void UART_SendByte(unsigned char dat) //串口发送单字节数据
{
unsigned char time_out;
time_out = 0;
SBUF = dat; //将数据放入SBUF中
while ((!TI) && (time_out < 100)) //检测是否发送出去
{
time_out++;
DelayUs10x(2);
} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
/************************* 串口发送字符串 *************************/
void UART_SendStr(unsigned char *s, unsigned char length)
{
unsigned char num;
num = 0x00;
while (num < length) //发送长度对比
{
UART_SendByte(*s); //放松单字节数据
s++; //指针++
num++; //下一个++
}
}
/************************* 串口中断 *************************/
void UART_Interrupt(void) interrupt 4 //串行中断服务程序
{
if (RI)//判断是接收中断产生
{
RI = 0; //标志位清零
}
}