Files
ultrasonic_cmake_vscode/Src/ultrasonic_analog.c
2025-08-25 17:05:47 +08:00

141 lines
4.9 KiB
C

#include "ultrasonic_analog.h"
#include "gd32e23x_usart.h"
#include "gd32e23x_rcu.h"
#include "gd32e23x_gpio.h"
#include "board_config.h"
#include "systick.h"
volatile bool g_ultrasonic_measure_done = false;
void ultrasonic_tx_init(void) {
rcu_periph_clock_enable(US_TX_GPIO_RCU);
gpio_mode_set(US_TX_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, US_TX_GPIO_PIN);
gpio_output_options_set(US_TX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, US_TX_GPIO_PIN);
gpio_af_set(US_TX_GPIO_PORT, US_TX_GPIO_AF, US_TX_GPIO_PIN);
timer_oc_parameter_struct timer_ocinitpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(US_TX_TIMER_RCU);
timer_deinit(US_TX_TIMER);
timer_struct_para_init(&timer_initpara);
/* 配置为300kHz PWM输出 (72MHz/240) */
timer_initpara.prescaler = 0; // 不分频
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 239; // 72MHz/300kHz - 1
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(US_TX_TIMER, &timer_initpara);
timer_channel_output_struct_para_init(&timer_ocinitpara);
timer_ocinitpara.outputstate = TIMER_CCX_DISABLE;
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(US_TX_TIMER, US_TX_TIMER_CH, &timer_ocinitpara);
/* config timer channel output mode */
timer_channel_output_mode_config(US_TX_TIMER, US_TX_TIMER_CH, TIMER_OC_MODE_PWM0);
/* config channel output pluse value (50% duty) */
timer_channel_output_pulse_value_config(US_TX_TIMER, US_TX_TIMER_CH, 120);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(US_TX_TIMER);
timer_counter_value_config(US_TX_TIMER, 0);
timer_interrupt_enable(US_TX_TIMER, TIMER_INT_UP);
nvic_irq_enable(TIMER13_IRQn, 2U);
}
void ultrasonic_pwm_out_cycles(void) {
g_ultrasonic_measure_done = false;
// 停止发射定时器
timer_disable(TIMER13);
timer_channel_output_state_config(TIMER13, TIMER_CH_0, TIMER_CCX_ENABLE);
// 重置并启动回波计时器
timer_disable(US_ECHO_TIMER);
// 重要:清除所有中断标志
// timer_interrupt_flag_clear(US_ECHO_TIMER, TIMER_INT_FLAG_CH0);
// timer_interrupt_flag_clear(US_ECHO_TIMER, TIMER_INT_FLAG_UP);
// 重置计数器
timer_counter_value_config(US_ECHO_TIMER, 0);
// 启动发射PWM
timer_enable(US_TX_TIMER);
// 启动回波计时器
timer_enable(US_ECHO_TIMER);
}
void ultrasonic_receive_exti_config(void) {
rcu_periph_clock_enable(US_RX_GPIO_RCU);
rcu_periph_clock_enable(US_RX_EXTI_RCU);
gpio_mode_set(US_RX_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, US_RX_GPIO_PIN);
nvic_irq_enable(US_RX_EXTI_IRQ, 0U);
syscfg_exti_line_config(EXTI_SOURCE_GPIOA, US_RX_EXTI_LINE);
exti_init(US_RX_GPIO_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_flag_clear(US_RX_GPIO_EXTI);
}
void ultrasonic_echo_timer_config(void) {
rcu_periph_clock_enable(US_ECHO_RCU);
timer_deinit(US_ECHO_TIMER);
timer_parameter_struct timer_initpara;
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = 71; // 72MHz/72 = 1MHz (1us per count)
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = (ULTRASONIC_MAX_TOF_RELOAD - 1);
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(US_ECHO_TIMER, &timer_initpara);
timer_auto_reload_shadow_disable(US_ECHO_TIMER);
// 配置输出比较通道0
timer_oc_parameter_struct timer_oc_initpara;
timer_channel_output_struct_para_init(&timer_oc_initpara);
timer_oc_initpara.outputstate = TIMER_CCX_ENABLE;
timer_oc_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_channel_output_config(US_ECHO_TIMER, TIMER_CH_0, &timer_oc_initpara);
// 配置输出比较模式
timer_channel_output_mode_config(US_ECHO_TIMER, TIMER_CH_0, TIMER_OC_MODE_TIMING);
// 设置比较值
timer_channel_output_pulse_value_config(US_ECHO_TIMER, TIMER_CH_0, (ULTRASONIC_TX_RINGDOWN_RELOAD - 1));
// 清除中断标志
timer_interrupt_flag_clear(US_ECHO_TIMER, TIMER_INT_FLAG_CH0);
timer_interrupt_flag_clear(US_ECHO_TIMER, TIMER_INT_FLAG_UP);
// 使能中断
timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_UP); // UP中断
timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_CH0); // CH0中断
nvic_irq_enable(US_ECHO_TIMER_IRQ, 1U);
// timer_single_pulse_mode_config(US_ECHO_TIMER, TIMER_SP_MODE_SINGLE);
}
void ultrasonic_config(void) {
ultrasonic_tx_init();
ultrasonic_receive_exti_config();
ultrasonic_echo_timer_config();
}