2 摄 像 头 在 距 离 人 眼 4 7 ~ 5 0 c m 时,成 功 率 大 概 为 9 6 % 左 右 光 线...

16
1 防疲劳驾驶及辅助系统 尹炳斐 201758502340 黄亭 201758502306 赵仁正 201758502328 第一部分 设计概述 1.1设计目的 高速公路迅猛发展,是经济发展的必然要求,同时也对公安交通管理工作提 出了更高的要求,带来前有的压力和挑战。驾驶员在疲劳时,其对周围环境的感 知能力、形势判断能力和对车辆的操控能力都有不同程度的下降,因此非常容易 产生交通事故。根据交通部门的资料显示,由于疲劳驾驶造成的交通事故所占比 重很大,应对这一重大安全隐患,我们设计了防疲劳驾驶及辅助系统。 1.2应用领域 我们的项目主要应用于高速公路驾驶。在高速公路上,司机一般驾驶时间较 长,并且路况和环境较为单一,容易引起疲劳。另外从车的角度讲,特别是大车 遇到长上坡时车速骤降,对于后方车辆形成了巨大的流动障碍。这时如若后车处 于疲劳状态,很可能无法采取有效的避让措施导致追尾。 本作品通过面部识别技术、眨眼监测技术,判断司机是否疲劳驾驶,若为疲 劳驾驶,会发出能够引起司机警惕的自动警示播报,同时汽车会开启辅助驾驶功 能以保持安全车距和防止车道偏移等。本作品整合了疲劳预警和半自动驾驶技术, 保障高速公路行车安全。 1.3主要技术特点 OpenMV摄像头可以处理 Haar模板进行通用对象检测,并配有内置的 FrontalFace模板和EyeHaar模板来检测人脸和眼睛。首先使用 image.find _features()和 Haar算子 frontalface来搜索某人面部。然后使用 image.find_ features和Haar算子find_eye在面部搜索眼睛。最后,在调用image.find _features函数后返回的每个眼睛ROI上调用这一方法,定位瞳孔。Stm32f103 捕获眨眼的次数,计算出眼睑闭合时间占一段时间的百分比,来作为生理疲劳的 测量指标。得到的指标通过 HC-05蓝牙模块发送至 STNUCLEO-F411RE主控 板,确定车辆是否开启辅助驾驶功能。 1.4关键性能指标

Upload: others

Post on 20-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

  • 1

    防疲劳驾驶及辅助系统尹炳斐 201758502340

    黄亭 201758502306

    赵仁正 201758502328

    第一部分 设计概述

    1.1设计目的

    高速公路迅猛发展,是经济发展的必然要求,同时也对公安交通管理工作提

    出了更高的要求,带来前有的压力和挑战。驾驶员在疲劳时,其对周围环境的感

    知能力、形势判断能力和对车辆的操控能力都有不同程度的下降,因此非常容易

    产生交通事故。根据交通部门的资料显示,由于疲劳驾驶造成的交通事故所占比

    重很大,应对这一重大安全隐患,我们设计了防疲劳驾驶及辅助系统。

    1.2应用领域

    我们的项目主要应用于高速公路驾驶。在高速公路上,司机一般驾驶时间较

    长,并且路况和环境较为单一,容易引起疲劳。另外从车的角度讲,特别是大车

    遇到长上坡时车速骤降,对于后方车辆形成了巨大的流动障碍。这时如若后车处

    于疲劳状态,很可能无法采取有效的避让措施导致追尾。

    本作品通过面部识别技术、眨眼监测技术,判断司机是否疲劳驾驶,若为疲

    劳驾驶,会发出能够引起司机警惕的自动警示播报,同时汽车会开启辅助驾驶功

    能以保持安全车距和防止车道偏移等。本作品整合了疲劳预警和半自动驾驶技术,

    保障高速公路行车安全。

    1.3主要技术特点

    OpenMV摄像头可以处理 Haar模板进行通用对象检测,并配有内置的

    Frontal Face 模板和 Eye Haar模板来检测人脸和眼睛。首先使用 image.find

    _features()和 Haar算子 frontalface来搜索某人面部。然后使用 image.find_

    features和 Haar算子 find_eye在面部搜索眼睛。最后,在调用 image.find

    _features函数后返回的每个眼睛ROI上调用这一方法,定位瞳孔。Stm32f103

    捕获眨眼的次数,计算出眼睑闭合时间占一段时间的百分比,来作为生理疲劳的

    测量指标。得到的指标通过HC-05蓝牙模块发送至STNUCLEO-F411RE主控

    板,确定车辆是否开启辅助驾驶功能。

    1.4关键性能指标

  • 2

    摄像头在距离人眼47~50cm时,成功率大概为96%左右,光线良好的情

    况下,识别效果最佳。threshold是浮点数(0.0-1.0) ,其中较小的值在提高检测

    速率同时增加误报率。相反,较高的值会降低检测速率,同时降低误报率。通过

    比对我们设置threshold值为0.5。scale是一个必须大于1.0的浮点数。较高

    的比例因子运行更快,但其图像匹配相应较差。理想值介于1.35-1.5之间。通

    过比对,我们设置scale值为2。

    第二部分 系统组成及功能说明

    2.1整体介绍

    1

    OpenMV先通过人眼识别找到人眼,然后利用find_eye函数找到瞳孔,捕

    获眨眼次数,将“眼睑闭合时间占一段时间的百分比”作为生理疲劳的测量指标。

    OpenMV和Stm32f103通信,将测量指标通过串口发送给Stm32f103进行数

    据处理,处理完成的数据通过HC-05蓝牙模块发送至STNUCLEO-F411RE。

    STNUCLEO-F411RE作为主控模块,对返回结果进行识别,进而控制小车的运

    动状态;同时,HC-SR04超声波模块检测前后车距,TCRT5000循迹模块探测

    车道,得到的数据传给STNUCLEO-F411RE。

    2.2方案选择与论证

    2.2.1摄像头模块

    方案一:采用ov7725摄像头,进行平均值阈值分割,求全图黑色像素个数,

    当做瞳孔面积。根据圆形面积公式换算出半径R,从(0,0)为起点做滑动窗口,

    检测每个窗口中黑色像素数量,最大的为瞳孔中心。

    图1系统整体框图

  • 3

    方案二:采用OpenMV摄像头,可以处理Haar模板进行通用对象检测,并配

    有内置的Frontal Face 模板和Eye Haar模板来检测人脸和眼睛。

    基于数据处理的简便性及算法的优化程度,采用方案二。

    2.2.2路面白线探测模块(车道偏移报警)

    方案一:采用摄像头把道路的信息收集起来再用STNUCLEO-F411RE对其

    分析,此种方法信息处理准确,但成本较高,对硬件和软件的的要求都非常高,

    所以此种方案不大可取。

    方案二:可见光发光二极管与光敏二极管组成的发射-接收模块。这种方案的

    缺点在于其他环境光源会对光敏二极管的工作产生很大干扰,一旦外界光亮条件

    改变,很可能造成误判和漏判。

    方案二:脉冲调制的反射式红外线发射-接收器。考虑到环境干扰主要是直流

    分量,如果采用带有交流分量的调制信号,则可以大幅度减少外界干扰;另外,

    红外线发射管的最大工作电流取决于平均电流,如果使用占空比小的调制信号,

    在平均电流不变的情况下,瞬间电流可以很大(50~100mA),这样也大大提高了

    信噪比。

    综上我们采用两侧各一个脉冲调制的反射式红外线发射-接收器对路面的白

    线进行探测。

    2.2.3避障模块

    方案一:采用红外传感器,价格成本比较低,测距比较精准,而且反应灵敏,

    红外传感器主要是利用光反射的原理,对于透明的障碍物就会有影响。

    方案二:采用超声波传感器,因为声波遇到障碍物会反射,而声波的速度已

    知,所以只需要知道发射到接收的时间差,就能计算出测量距离,再结合发射器

    和接收器的距离,就能算出障碍物的实际距离,进行避障。

    由于超声波模块的抗干扰能力更强,故选择超声波模块。

    2.3各模块介绍

    2.3.1STNUCLEO-F411RE微控制器

    STM32F411微控制器提供了动态功耗(运行模式)和处理性能之间的最佳

    平衡,同时在3 x 3 mm的小封装内集成了大量的增值特性。STM32F411新的

    批量数据获取模式(BAM),对数据批处理进行了功耗优化,将

    Dynamic Efficiency提升到了一个新的水平。此BAM可通过通信外设进行批量

    数据交换,同时器件的其它部分(包括CPU)可处于省电模式。

  • 4

    性能:在100 MHz频率下,从Flash存储器执行时,STM32F411单片机

    能够提供 125 DMIPS/339 CoreMark性能,并且利用意法半导体的ART加速

    器实现了FLASH零等待状态。DSP指令和浮点运算单元扩大了产品的应用范围。

    功效:该系列产品采用意法半导体90 nm工艺和ART加速器,具有动态功

    耗调整功能,能够在从Flash存储器执行时实现低至100 µA/MHz的电流消耗。

    停机模式下,功耗低至10 µA。

    集成度:STM32F411单片机具有高达256至512 KB的Flash存储器和高

    达128 KB的SRAM。提供从49到100引脚多种封装。

      • 3路USART,速度高达12.5 Mbit/s,

      • 5路SPI(I2S复用),速度高达50 Mbit/s,

      • 3路I²C,高达1Mbps

      • 1x SDIO,频率高达48MHz,且所有封装均提供,

      • 1个USB 2.0 OTG(全速),

      • 2路全双工I²S,高达32位/192KHz,

      • 3路单工I²S,高达32位/192KHz,

      • 速度高达2.4 MSPS的12位ADC,

      • 11个频率高达100 MHz的16和32位定时器

    2.3.2瞳孔识别模块

    OpenMV摄像头是一款小巧,低功耗,低成本的电路板,STM32F765VI

    ARMCortexM7处理器,216 MHz,512KBRAM,2 MBflash.所有的 I/O

    引脚输出3.3V并且5V耐受。OV7725感光元件在80 FPS下可以处理640×480

    8-bit灰度图或者320×24016-bitRGB565彩色图像;当分辨率低于320×240

  • 5

    可以达到120FPS。OpenMV摄像头可以处理Haar模板进行通用对象检测,并

    配有内置的FrontalFace模板和EyeHaar模板来检测人脸和眼睛。OpenMV

    和微控制器通信,将测量指标通过串口发送给微控制器进行数据处理。

    2.3.3蓝牙通信模块

    ATK-HC05-V11是一款高性能的主从一体蓝牙串口模块,可以同各种带蓝

    牙功能的电脑、蓝牙主机、手机、PDA、PSP等智能终端配对,该模块支持非

    常宽的波特率范围:4800~1382400,并且模块兼容 5V或 3.3V单片机系统,

    使用非常灵活、方便。模块与单片机连接最少只需要 4根线即可:VCC、GND、

    TXD、RXD,VCC和 GND用于给模块供电,模块 TXD和 RXD则连接单片

    机的 RXD和 TXD即可。

    图2蓝牙串口模块原理图

    图3ATK-HC05模块与单片机系统连接示意图

  • 6

    2.3.4避障模块

    避障模块采用HC-SR04超声波模块该模块。具有四个引脚,分别为VCC、

    GND、TRIG、ECHO,其中VCC、GND为供电脚,TRIG为测距触发引脚,ECHO

    为测距输入引脚。该模块的驱动模式为:控制口发一个 10US 以上的高电平,就

    可以在接收口等待高电平输出。一有输出就可以开定时器计时,当此口变为低电

    平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离。如此不断

    的周期测,就可以达到移动测量的值。

    2.3.5防车道偏移模块

    防车道偏移模块采用了TCRT5000红外循迹模块。检测原理是:当检测到

    反射率不高的物品时,三极管 T2截止而输出高电平。当检测到反射率较高的

    物品,三极管 T2饱和而输出低电平,从而实现了白线的检测。555构成了施

    密特触发器,用于去除反射性光耦产生的噪声和波形的整形。简单的说就是当红

    外寻迹模板遇见黑线时会产生一个高电平,遇见白线时会返回一个低电平。

    TCRT5000寻迹模块的电路如图5所示

    2.3.6电机驱动模块

    系统采用电机驱动芯片L289N。该芯片采用15脚封装。主要特点是:工作

    电压高,最高工作电压可达46V;输出电流大,瞬间峰值电流可达3A,持续工

    作电流为2A;额定功率25W。内含两个H桥的高电压大电流全桥式驱动器,

    可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用标准逻辑

    电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止

    器件工作有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外

    图4TCRT5000寻迹模块的电路图

  • 7

    接检测电阻,将变化量反馈给控制电路。使用L298N芯片驱动电机,该芯片可

    以驱动一台两相步进电机或四相步进电机,也可以驱动两台直流电机。

    第三部分 完成情况及性能参数

    第四部分 总结

    2 4.1主要创新点

    (1)有效减少误报,更加智能化

    国内现有蓝牙耳机式疲劳驾驶报警器,它佩戴在驾驶员耳朵上,一旦产生睡

    意,头部向前倾斜,或向后仰到一定角度,该装置便会发出警报声,唤醒驾驶员

    引起警觉。但这种会因驾驶员在等红绿灯等非行驶情况下低头,而造成误报。

    而我们的作品能够在车速低于20km/h的时候自动停止报警,包括停车等红

    绿灯时、路边停车时都会自动停止报警,更加智能化。

    (2)主动监测预警,让司机注意力更集中

    国外现有被动疲劳预警防疲劳驾驶技术,需要司机每隔一段时间和系统进行

    瞳孔识别距离(cm) 38 41 44 47 50 53 56

    成功率(%) 71 83 94 97 96 82 75

    瞳孔识别距离(cm) 59 62 65 68 71 74 77

    成功率(%) 67 54 31 10 4 1 1

    图5电机驱动电路图

  • 8

    交互,以证明自己仍处于清醒状态,具体的应用例如防瞌睡方向盘,如果司机超

    过了设定时间,没有触碰方向盘上的按钮,则系统就会发出报警。

    而我们的作品无需司机采用被动方式向系统输入信号,系统就可以采用瞳孔

    监测技术,主动获取司机信息,用于司机疲劳程度判断。

    (3)减少监控人力,增大监控力度

    在车联网领域,目前国内外已经有多种手段来监控车辆,但是却没有较好的技术

    手段来监控驾驶员疲劳状态。当前常用的手段是定时得给驾驶员拍摄快照,然后

    传输到监控平台上。这种方法对监控人员的责任心和体力都有很高要求,且预防

    疲劳效率低。

    而我们的产品既能够记录驾驶员驾驶行为,又能够自动识别其疲劳程度,并

    在发出警告的同时能够和车载终端通信,从而补充完善现有车联网技术的不足,

    全面充分保障驾驶员、乘客的生命及财产安全。

    4.2可扩展之处

    (1)舵机云台模块

    加入舵机云台模块,将摄像头安装在云台上,使用OpenMV的关键点功能

    来跟踪一个被Haar Cascade 检测到的人脸,脚本的第一部分使用前

    Haar Cascad在图像中找到用户的脸之后,脚本使用关键点功能自动学习用户

    的脸并跟踪它。

    舵机云台可以改变上臂下臂的旋转角度,让人脸尽可能在画面的正中间。

    (2)优化算法

    当用户戴眼镜时,阳光干扰可能会影响OpenMV的瞳孔识别,可以运用阳光

    算法,解决阳光问题。

    4.3心得体会

    从开发板和方案的确定,到编写程序,硬件搭构,我们团队遇到了各种各样

    的问题,比如PWM频率问题导致L298n一直滴滴响;最初调串口时一直乱码,

    最后才发现是串口助手数据位的问题;OpenMV识别瞳孔一直不稳定,通过调

    试找到scale、threshold等浮点数的合适数值…

    之前没有学过STNUCLEO-F411RE,一直用的stm32f103。现在发现f4

    更好用,因为f4是HAL固件库,和之前的标准固件库比,HAL库可以轻松实

    现从一个STM32产品移植到另一个不同的STM32系列产品;并且串口下载和

    调试很方便,集成度高;我们还发现了CubeMX这个可以大大减轻开发工作,

  • 9

    提高效率的工具,在CubeMX上,通过傻瓜化的操作便能实现相关配置,能够

    直接生成C语言代码。

    通过这次竞赛,我们发现比赛是一个考验自己,考验团队的过程。在赛前那

    段时间,要兼顾常规课程和项目制作,每天都非常忙碌;在准备过程中,还会碰

    到各种各样的问题,如整个系统的构想、整体外观的设计搭建、软件流程的设计

    和软硬件的协同配合等等。当中最关键的,还是时间的紧迫和知识储备的不足。

    尽管比赛最后顺利完成了,但整个过程让我们认识到自己的不足,也总结了

    很多经验教训。感谢竞赛为我们打开了一扇新的知识的大门,日后我们会为了变

    为优秀的电子工程师而更加努力!

    第五部分 参考文献

    [1]李丽荣.51单片机应用设计[M].北京:北京理工大学出版社,2012.08

    [2]周国中.基于瞳孔特征的真实情感识别与应用研究,2016.12

    [3]星瞳科技OpenMV官方中文文档

    第六部分 附录

    #include"main.h"

    #include"tim.h"

    #include"usart.h"

    #include"gpio.h"

    voidSystemClock_Config(void);

    voidUSART_CharReception_Callback(void);

    TIM_HandleTypeDef TimHandle;

    TIM_IC_InitTypeDef sConfig;

    TIM_SlaveConfigTypeDef sSlaveConfig;

    __IOuint32_t uwIC2Value=0;

    __IOuint32_t uwDutyCycle=0;

    __IOuint32_t uwFrequency=0;

    uint32_tj=0,len;

    uint8_trecive[100];

    __IOuint8_treceived_char;

    uint32_tdistance;

    intmain(void)

    {

    /*USERCODEBEGIN1*/

  • 10

    TimHandle.Instance=TIMx;

    TimHandle.Init.Period=0xFFFF;

    TimHandle.Init.Prescaler=0;

    TimHandle.Init.ClockDivision=0;

    TimHandle.Init.CounterMode=TIM_COUNTERMODE_UP;

    TimHandle.Init.AutoReloadPreload =

    TIM_AUTORELOAD_PRELOAD_DISABLE;

    if(HAL_TIM_IC_Init(&TimHandle)!=HAL_OK)

    {

    Error_Handler();

    }

    sConfig.ICPrescaler=TIM_ICPSC_DIV1;

    sConfig.ICFilter=0;

    sConfig.ICPolarity=TIM_ICPOLARITY_FALLING;

    sConfig.ICSelection=TIM_ICSELECTION_INDIRECTTI;

    if(HAL_TIM_IC_ConfigChannel(&TimHandle, &sConfig,

    TIM_CHANNEL_1)!=HAL_OK)

    {

    Error_Handler();

    }

    sConfig.ICPolarity=TIM_ICPOLARITY_RISING;

    sConfig.ICSelection=TIM_ICSELECTION_DIRECTTI;

    if(HAL_TIM_IC_ConfigChannel(&TimHandle, &sConfig,

    TIM_CHANNEL_2)!=HAL_OK)

    {

    Error_Handler();

    }

    sSlaveConfig.SlaveMode =TIM_SLAVEMODE_RESET;

    sSlaveConfig.InputTrigger =TIM_TS_TI2FP2;

    if(HAL_TIM_SlaveConfigSynchronization(&TimHandle,&sSlaveConfig)!=

    HAL_OK)

    {

    Error_Handler();

    }

    if(HAL_TIM_IC_Start_IT(&TimHandle,TIM_CHANNEL_2)!=HAL_OK)

    {

    Error_Handler();

    }

    /*USERCODEEND1*/

    HAL_Init();

    SystemClock_Config();

  • 11

    MX_GPIO_Init();

    MX_TIM3_Init();

    MX_USART1_UART_Init();

    /*USERCODEBEGIN2*/

    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);

    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);

    inti=0;

    USART_CharReception_Callback();

    /*USERCODEEND2*/

    /*Infiniteloop*/

    /*USERCODEBEGINWHILE*/

    while(1)

    {

    /*USERCODEENDWHILE*/

    /*USERCODEBEGIN3*/

    for(i=0;i30)

    {

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

    KEY1_Pin)==0&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==0)

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,140);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,140);

    }

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

  • 12

    KEY1_Pin)==1&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==1)

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,140);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,140);

    }

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

    KEY1_Pin)==1&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==0)

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,0);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,300);

    }

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

    KEY1_Pin)==0&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==1)

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,300);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,0);

    }

    }

    if(received_char==1&&distance10)

    {

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

    KEY1_Pin)==0&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==0)

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,95);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,95);

    }

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

    KEY1_Pin)==1&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==1)

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,95);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,95);

    }

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

    KEY1_Pin)==1&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==0)

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,0);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,150);

    }

    if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,

    KEY1_Pin)==0&&HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==1)

  • 13

    {

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,150);

    __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,0);

    }

    }

    if(received_char==1&&distance

  • 14

    RCC_ClkInitStruct.ClockType =

    RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

    RCC_ClkInitStruct.SYSCLKSource=RCC_SYSCLKSOURCE_HSI;

    RCC_ClkInitStruct.AHBCLKDivider=RCC_SYSCLK_DIV1;

    RCC_ClkInitStruct.APB1CLKDivider=RCC_HCLK_DIV1;

    RCC_ClkInitStruct.APB2CLKDivider=RCC_HCLK_DIV1;

    if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct,FLASH_LATENCY_0)!=

    HAL_OK)

    {

    Error_Handler();

    }

    }

    /*USERCODEBEGIN4*/

    voidUSART_CharReception_Callback(void)

    {

    HAL_UART_Receive(&huart1,&received_char,len,20);

    if(received_char!='\r'&&received_char!='\n')

    {

    recive[j]=received_char;

    j++;

    }

    else

    {

    len=j;

    j=0;

    }

    //LL_USART_TransmitData8(USARTx_INSTANCE,received_char);

    }

    voidHAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef*htim)

    {

    if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)

    {

    uwIC2Value=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);

    if(uwIC2Value!=0)

    {

  • 15

    uwDutyCycle = ((HAL_TIM_ReadCapturedValue(htim,

    TIM_CHANNEL_1))*100)/uwIC2Value;

    uwFrequency=(HAL_RCC_GetHCLKFreq())/uwIC2Value;

    }

    else

    {

    distance=(uwFrequency/100000000+uwDutyCycle*0.01)*340/2;

    uwDutyCycle=0;

    uwFrequency=0;

    }

    }

    }

    /*USERCODEEND4*/

    /**

    *@brief Thisfunctionisexecutedincaseoferroroccurrence.

    *@retvalNone

    */

    voidError_Handler(void)

    {

    /*USERCODEBEGINError_Handler_Debug*/

    /*UsercanaddhisownimplementationtoreporttheHALerrorreturn

    state*/

    /*USERCODEENDError_Handler_Debug*/

    }

    #ifdef USE_FULL_ASSERT

    /**

    *@brief Reportsthenameofthesourcefileandthesourcelinenumber

    * wheretheassert_paramerrorhasoccurred.

    *@param file:pointertothesourcefilename

    *@param line:assert_paramerrorlinesourcenumber

    *@retvalNone

    */

    voidassert_failed(uint8_t*file,uint32_tline)

    {

    /*USERCODEBEGIN6*/

    /*Usercanaddhisownimplementationtoreportthefilenameandline

    number,

    tex:printf("Wrongparametersvalue:file%sonline%d\r\n",file,line)

    */

    /*USERCODEEND6*/

  • 16

    }

    #endif/*USE_FULL_ASSERT*/