基于STM32的超声波倒车检测装置
一、前言
????这里是为了完成学校嵌入式系统及应用实验而做的一个作业,硬件资源使用的是STM32F103VBT6开发板、HC-SR04超声波模块,蜂鸣器和数码管开发板上以及集成了。 ????完成了如下功能:1.使用外设超声波模块达到测距功能;2.通过串口发送指令,使整个装置进行倒车检测工作;3.可通过串口实时查看车辆距离障碍物的距离;4.同时数码管也可实时显示当前车辆距离障碍物的距离;5.当车辆距离障碍物距离小于10cm,蜂鸣器开始报警,串口输出WARNING!!!警告驾驶者距离过近。
二、基本原理
1.超声波测距原理
????HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。 基本工作原理: (1)采用IO口TRIG触发测距,给至少10us 的高电平信号; (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
2.超声波时序图
????以上时序图表明你只需要提供一个10uS 以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式: uS/58=厘米或者uS/148=英寸;或是:距离=高电平时间*声速(340M/S)/2;建议测量周期为60ms 以上,以防止发射信号对回响信号的影响。
3.串口通信原理
(1)接口通过三个引脚与其他设备连接在一起。任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。 这个之前博文有详细说过,这里不在赘述STM32串口通信
4.数码管原理
????数码管动态显示原理:动态显示的特点是将所有数码管的段选并联在一起,有位选控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余晖和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。动态显示的亮度比静态显示要差一些,所有在选择限流电阻时应略小于静态显示电路中的。
5.蜂鸣器原理
????本装置中控制蜂鸣器的方式采用I/O 口定时翻转电平驱动蜂鸣器。使用I/O 口定时翻转电平驱动蜂鸣器方式的设置比较简单,只需要对波形分析一下。由于驱动的信号刚好为周期500μs,占空比为1/2duty 的方波,只需要每250μs 进行一次电平翻转,就可以得到驱动蜂鸣器的方波信号。
6.GPIO原理
????根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成多种模式。①输入浮空 ②输入上拉 ③ 输入下拉 ④ 模拟输入 ⑥ 开漏输出 ⑦ 推挽式输出 ⑧ 推挽式复用功能 ⑨ 开漏复用功能,本装置采用的超声波模块,则复用了发送电平引脚PA0设置为推挽输出,返回电平引脚PA1设置为浮空输入。之前博文也有说到,这里不在赘述STM32GPIO
三、子模块设计以及代码
1.超声波测距模块
????HC-SR04超声波模块有VCC供5V电源,GND为地线,TRIG触发控制信号输入,ECHO回响信号输出等四支线。刚好利用开发板EXT区的四个引脚,只需要复用GPIO实现输出输入功能即可。 超声波模块的关键代码如下: ultrasonic.c
#include "ultrasonic.h"
#include"delay.h"
//超声波硬件模块初始化
void Ultran_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
//发送电平引脚PA0设置成推挽输出
//返回电平引脚PAl设置成浮空输入
GPIOA->CRL&=0XFFFFFF00;
GPIOA->CRL|=0X00000083;
}
//超声波测距,均值5次,实际测量过程发现测量静态的比较稳定,动态的不稳定,3米范围内比较稳定
u32 Ultra_Ranging(void)
{
//u8 i;
u32 j=0;
u32 Ultr_Temp;
//for(i=0;i<5;i++)
{
TRIG=1;
delay_ms(10);
TRIG=0;
while(!ECHO);
while(ECHO)
{
delay_us(10);
j++;
}
Ultr_Temp=j*340/200;//每次延时10us//把us转成s *10/2 / 1000= /200
//delay ms (60);//防止发射信号对回响信号的影响
}
return Ultr_Temp;
}
u32 Ultrasonic(void)
{
unsigned int E;
u32 distance=0;
TRIG=1;//给超声波一个信号
delay_ms(11);;
TRIG=0;
while(ECHO==0);//等待低电
while(ECHO==1)
++distance;
delay_ms(6);
E=distance/24;
return E;
}
ultrasonic.h
#ifndef _ultrasonic_H
#define _ultrasonic_H
#include "sys.h"
#include "stm32f10x_type.h"
//-----------------------------移植修改区----------------------------------
#define TRIG PAout(0)
#define ECHO PAin(1)
//---------------------------------------------------------------
void Ultran_Init(void);
u32 Ultra_Ranging(void);
u32 Ultrasonic(void);
#endif
2.蜂鸣器模块
????利用板载蜂鸣器模块完成蜂鸣提醒的功能,通过查看原理图得知控制蜂鸣器的引脚PE5,只需要复用PE5的GPIO为输出模式,通过给PE5高电平使蜂鸣器发声,低电平使蜂鸣器不发声,类似于NPN三极管作为开关,当超声波测的车辆距离小于10cm时,发出报警。关键代码如下: beep.c
#include "beep.h"
#include "delay.h"
//蜂鸣器初始化
void BEEP_Init(void)
{
RCC->APB2ENR|=1<<6; //使能PORTE时钟
GPIOE->CRL&= 0x00;
GPIOE->CRL|=0x44344444; //初始化PE.5输出模式
GPIOE->ODR|=1<<5; //
}
//蜂鸣器开关
void beep_on(void)
{
//蜂鸣器由NPN三极管作为开关
// PE5高电平开关close蜂鸣器发声
//PE5 低电平开关open蜂鸣器不发声
GPIOE->ODR &= ~(1<<5);
delay_ms(5);
GPIOE->ODR |= 1<<5;
delay_ms(5);
}
beep.h
#ifndef __BEEP_H__
#define __BEEP_H__
#include "sys.h"
//蜂鸣器初始化
void BEEP_Init(void);
//
void beep_on(void);
#define BEEP PEout(5)
#endif /*__BEEP_H__*/
3.数码管以及串口显示模块
(1)对于八段数码管,需要显示当前车辆距离障碍的距离,因为超声波模块的最大范围是3米,精确度是毫米级,所以我们使用四位数码管显示距离即可,这里为了使用者查看方便,以厘米为单位,小数点显示在第二位数下方。 (2)对于串口显示,需要利用串口通信,打印当前车辆距离障碍物的距离,可以打印超声波模块的发射距离以及接收距离,以毫米为单位,同时如果距离小于10cm,串口会打印WRANING!!!,进一步提醒使用者。 主要代码如下: led.c
#include "led.h"
/***************************数码管段选***************************/
u8 segTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
u8 segTablePortation[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
/****************************************************
*初始化二极管LED灯的引脚端口
******************************************************/
void LED_Init()
{
RCC->APB2ENR|=1<<0; //使能AFIO
RCC->APB2ENR|=1<<3; //使能PORTB时钟
RCC->APB2ENR|=1<<6; //使能PORTE时钟
AFIO->MAPR|=0x02000000;//复用口设置设置PB.3为I/O口可用,且可以sw仿真
GPIOB->CRL &= 0xFFFF0000;
GPIOB->CRL |= 0x00003333; //PB.3推挽输出
GPIOB->ODR |= 0x000000FF; //PB.3输出高
GPIOE->CRH&=0X00000000;
GPIOE->CRH|=0X33333333; //PE.8-15推挽输出
GPIOE->ODR|=0x0000FF00; //PE.8-15输出高
}
/***************************************
*数码管显示不带小数点的数值
*参数w:显示的位置,即位选,左-右:0-7
*value:要显示的数值
****************************************/
void SetLed(u8 w, u8 value)
{
SEL0 = w%2;
SEL1 = w/2%2;
SEL2 = w/4;
LedValue(segTable[value]);
}
/***************************************
*数码管显示带小数点的数值
*参数w:显示的位置,即位选,左-右:0-7
*value:要显示的数值
****************************************/
void PortationDisplay(u8 w, u8 value)
{
SEL0 = w%2;
SEL1 = w/2%2;
SEL2 = w/4;
LedValue( segTablePortation[value] );
}
led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//LED端口定义
#define LED_SEL PBout(3) //PB3 显示位置选择
//位选
#define SEL0 PBout(0)
#define SEL1 PBout(1)
#define SEL2 PBout(2)
//段选
#define LED0 PEout(8)
#define LED1 PEout(9)
#define LED2 PEout(10)
#define LED3 PEout(11)
#define LED4 PEout(12)
#define LED5 PEout(13)
#define LED6 PEout(14)
#define LED7 PEout(15)
void LED_Init(void);//初始化
void LedValue( u8 value ); //设置数码管E-A的值;流水灯L7-L0的值
void SetLed(u8 w, u8 value); //设置数码管哪位显示什么数字
void PortationDisplay(u8 w, u8 value); //数码管显示带小数点的数值
#endif
功能函数主要代码
//数码管显示和串口打印距离数值
void Ultrasonic_on()
{
u8 i;
u32 d0 = 0;
u32 d1 = 0;
d0 = Ultrasonic();
d1 = Ultra_Ranging();
//′打印发射距离和接收距离
printf("D0 = %ld mm \t D1 = %ld mm\n\r",d0,d1);
//距离小于100mm,蜂鸣器报警
if(d1/100%10==0)
{
beep_on();
printf("\n WARNING!!!\n\r");
}
//数码管显示接收距离
for(i=0;i<100;i++)
{
SetLed(7, d1%10);
delay_ms(1);
PortationDisplay(6, d1/10%10);//第二位数需要带上小数点,单位为cm
delay_ms(1);
SetLed(5, d1/100%10);
delay_ms(1);
SetLed(4, d1/1000%10);
delay_ms(1);
/*
SetLed(3, d0%10);
delay_ms(1);
PortationDisplay(2, d0/10%10);
delay_ms(1);
SetLed(1, d0/100%10);
delay_ms(1);
SetLed(0, d0/1000%10);
delay_ms(1);
*/
}
}
4.主程序控制模块
????各个外设以及功能函数已经完成封装,在主程序来完成对蜂鸣器、超声波模块、八段数码管各个外设的初始化以及控制,同时主程序需要检测串口指令的收发,来驱动整个倒车检测装置的运行。关键代码如下:
int main( void )
{
u8 t;
u8 len;
u8 flag;
Stm32_Clock_Init(6); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口初始化为9600
LED_Init(); //初始化与LED连接的硬件接口
LED_SEL = 0;
Ultran_Init(); //初始化与超声波连接的硬件接口
BEEP_Init(); //初始化与蜂鸣器连接的硬件接口
while(1)
{
//delay_ms(2);
//delay_ms(2000);
//LED0=!LED0;//闪烁LED,提示系统正在运行.
//delay_ms(10);
if(USART_RX_STA&0x80)
{
u32 num = 0;
len=USART_RX_STA&0x3f;//得到此次接收到的数据长度
printf("\n Your MSG: \n");
for(t=0;t<len;t++)
{
num *= 10;
num += USART_RX_BUF[t]-'0';
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);//等待发送结束
}
flag=USART_RX_BUF[0]-'0';
switch(flag)
{
case 67 :
Ultrasonic_on();
printf("\n do Ultrasonic now\n");
break;
default :
printf("\n command error \n");
USART_RX_STA=0;
break;
}
printf("\n\n");//插入换行
//USART_RX_STA=0;
}
}
}
四、效果展示
1.装置非工作状态 2.串口发送start指令启动装置 3.倒车检测装置正常运行,当前距离为36cm 4.检测到障碍物,当前距离为3.5厘米,蜂鸣器报警 5.距离小于10cm,串口打印WARNING!!!,进行报警,同时蜂鸣器进行报警
|