学习目标
- 了解超声波测距原理
- 掌握逻辑分析仪使用
- 掌握驱动编写
学习内容
原理图
传感器
驱动编写
定时器代码
#include "bsp_timer.h"
#include <stdio.h>
uint32_t timer_ms = 0;
void bsp_timer_init(void){
// 开启时钟
rcu_periph_clock_enable(RCU_TIMER5);
// 开启倍频
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
// 定义结构
timer_parameter_struct timer_initpara;
// 复位定时器
timer_deinit(TIMER5);
timer_struct_para_init(&timer_initpara);
// 定时器配置
timer_initpara.period = 1000 - 1; // 定时1ms
timer_initpara.prescaler = 240 - 1;
// 定时器初始化
timer_init(TIMER5, &timer_initpara);
// 配置中断优先级
nvic_irq_enable(TIMER5_DAC_IRQn,1,1);
// 使能中断. 更新事件
timer_interrupt_enable(TIMER5,TIMER_INT_UP);
// 使能定时器
timer_enable(TIMER5);
}
void bsp_timer_open(void){
// 清空计数器
timer_counter_value_config(TIMER5,0);
timer_ms = 0;
timer_enable(TIMER5);
}
void bsp_timer_close(void){
timer_disable(TIMER5);
}
void TIMER5_DAC_IRQHandler(void)
{
static int i = 0;
if( timer_interrupt_flag_get(TIMER5, TIMER_INT_UP) != RESET )
{
timer_ms++;
timer_interrupt_flag_clear(TIMER5,TIMER_INT_UP);
}
}
uint32_t bsp_timer_get(){
uint32_t t = 0;
t = timer_ms*1000;
t += timer_counter_read(TIMER5);
return t;
}
超声波驱动
#ifndef __BSP_ultrasonic_H
#define __BSP_ultrasonic_H
#include "gd32f4xx.h"
#include "systick.h"
#include <stdint.h>
void bsp_ultrasonic_init(void);
float bsp_ultrasonic_get(void);
#endif /* __BSP_LED_H */
#include "bsp_ultrasonic.h"
#include <stdio.h>
#include "bsp_timer.h"
// 定义TRIG
#define RCU_TRIG RCU_GPIOB
#define PORT_TRIG GPIOB
#define GPIO_TRIG GPIO_PIN_14
// 定义ECHO
#define RCU_ECHO RCU_GPIOB
#define PORT_ECHO GPIOB
#define GPIO_ECHO GPIO_PIN_13
void bsp_ultrasonic_gpio_init(){
// 开启IO时钟
rcu_periph_clock_enable(RCU_TRIG);
rcu_periph_clock_enable(RCU_ECHO);
// 设置TRIG引脚
gpio_mode_set(PORT_TRIG,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_TRIG);
gpio_output_options_set(PORT_TRIG,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_TRIG);
gpio_bit_write(PORT_TRIG,GPIO_TRIG,RESET);
// 设置ECHO引脚
gpio_mode_set(PORT_ECHO,GPIO_MODE_INPUT,GPIO_PUPD_NONE,GPIO_ECHO);
gpio_bit_write(PORT_ECHO,GPIO_ECHO,RESET);
}
void bsp_ultrasonic_init(void){
bsp_ultrasonic_gpio_init();
}
float bsp_ultrasonic_get(){
// 连续测量5次 取平均值
float distance = 0;
uint8_t i = 0;
uint8_t count = 5;
while(i<count){
// 先将trig 拉高 10us以上
gpio_bit_write(PORT_TRIG,GPIO_TRIG,SET);
// 持续10us以上
delay_1us(20);
// 再拉低,超声波就发射出去了,同时Echo引脚的电平又0变为1
gpio_bit_write(PORT_TRIG,GPIO_TRIG,RESET);
// 当超声波发送出去之后,ECHO由0变为1
while(gpio_input_bit_get(PORT_ECHO,GPIO_ECHO) == RESET);
// 发送成功
bsp_timer_open();
// 当超声波返回时, ECHO由1变为0
while(gpio_input_bit_get(PORT_ECHO,GPIO_ECHO) == SET);
// 关闭定时器
bsp_timer_close();
// 获取高电平的时长
uint32_t time = bsp_timer_get(); // 单位us
/** 计算距离
* 声音在空气中的传播速度是343m/s
* 34300cm/1000ms
* 34300cm/1000 000us
* 0.0343cm/us
*/
distance += 0.0343*time/2;
// 延时10ms
delay_1ms(10);
i++;
}
return distance/5;
}
练习题
- 实现超声波测距驱动