generated from hulk/gd32e23x_template_cmake_vscode
163 lines
5.8 KiB
C
163 lines
5.8 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) {
|
||
|
||
// 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;
|
||
// }
|