Files
ultrasonic_cmake_vscode/Src/ultrasonic_analog.c

163 lines
5.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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) {
// TODO
rcu_periph_clock_enable(RCU_GPIOA);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
gpio_bit_reset(GPIOA, GPIO_PIN_0);
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, 2);
}
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_enable(US_TX_TIMER);
// TODO 启动后续回波计时器
// 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);
// exti_interrupt_enable(EXTI_0);
}
void ultrasonic_echo_timer_config(void) {
// 使能TIMER16时钟
rcu_periph_clock_enable(US_ECHO_RCU);
// 复位定时器到默认状态
timer_deinit(US_ECHO_TIMER);
// 配置基本定时器参数
timer_parameter_struct timer_initpara;
timer_struct_para_init(&timer_initpara);
// 设置分频器72MHz ÷ 72 = 1MHz每个计数 = 1us
timer_initpara.prescaler = 71; // (72-1)实际分频比为72
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
// 设置周期999 (0-999共1000个计数) = 1000us = 1ms最大计时
timer_initpara.period = 999; // 1000us重装载周期
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
// 初始化定时器基本参数
timer_init(US_ECHO_TIMER, &timer_initpara);
// 配置通道0用于240us比较中断不是PWM输出仅用于比较
timer_oc_parameter_struct timer_oc_initpara;
timer_channel_output_struct_para_init(&timer_oc_initpara);
// 禁用输出,仅用于内部比较中断
timer_oc_initpara.outputstate = TIMER_CCX_DISABLE;
timer_oc_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_channel_output_config(US_ECHO_TIMER, US_ECHO_CH, &timer_oc_initpara);
// 设置比较模式为时间比较不是PWM模式
timer_channel_output_mode_config(US_ECHO_TIMER, US_ECHO_CH, TIMER_OC_MODE_TIMING);
// 设置240us时触发比较中断计数值239因为从0开始计数
timer_channel_output_pulse_value_config(US_ECHO_TIMER, US_ECHO_CH, 239);
// 启用比较中断CH0和重装载中断UP
timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_CH0); // 240us比较中断
timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_UP); // 1000us重装载中断
// 配置NVIC中断优先级设置为较高优先级1确保及时响应
nvic_irq_enable(TIMER16_IRQn, 1);
// 注意定时器配置完成但不启动需要在其他地方调用timer_enable()启动
}
void ultrasonic_config(void) {
ultrasonic_tx_init();
// ultrasonic_transmit_debounce_delay(TIME_CORRECTION_US);
// ultrasonic_receive_exti_config();
ultrasonic_echo_timer_config();
}
// uint16_t ultrasonic_calc_distance(void) {
// // while (!ultrasonicMeasurementDone);
// // uint32_t us_value = timer_channel_capture_value_register_read(US_ECHO_TIMER, US_ECHO_CH);
// uint16_t distance = (TIME_CORRECTION_US + g_capture_value) * 17;
// /*
// * (TIME_CORRECTION_US + us_value) * 340 m/s
// * -----------------------------------------
// * 1000 000
// * ----------------------------------------------
// * 2
// */
// return distance;
// }