Rewrite the M1 command to send the drive signal after receiving the M1 command, and turn on TIMER16 at the same time. Set the measurement completion flag after 240us, and turn off TIMER16 after the maximum TOF timing.

This commit is contained in:
2025-08-20 00:25:03 +08:00
parent 70a6311425
commit 16c5a31a63
4 changed files with 59 additions and 83 deletions

View File

@@ -58,11 +58,6 @@
/******************************************************************************/ /******************************************************************************/
#define US_TX_DELAY_RCU RCU_TIMER15
#define US_TX_DELAY_TIMER TIMER15
/******************************************************************************/
#define US_RX_GPIO_RCU RCU_GPIOB #define US_RX_GPIO_RCU RCU_GPIOB
#define US_RX_EXTI_RCU RCU_CFGCMP #define US_RX_EXTI_RCU RCU_CFGCMP
#define US_RX_GPIO_PORT GPIOA #define US_RX_GPIO_PORT GPIOA
@@ -76,6 +71,7 @@
#define US_ECHO_RCU RCU_TIMER16 #define US_ECHO_RCU RCU_TIMER16
#define US_ECHO_TIMER TIMER16 #define US_ECHO_TIMER TIMER16
#define US_ECHO_CH TIMER_CH_0 #define US_ECHO_CH TIMER_CH_0
#define US_ECHO_TIMER_IRQ TIMER16_IRQn
/******************************************************************************/ /******************************************************************************/

View File

@@ -260,10 +260,14 @@ void handle_command(const uint8_t *frame, uint8_t len) {
// 启动超声波PWM发送 // 启动超声波PWM发送
ultrasonic_pwm_out_cycles(); ultrasonic_pwm_out_cycles();
// 启动TIMER16用于240us精确计时
timer_counter_value_config(TIMER16, 0); // 复位计数器
timer_enable(TIMER16); // 启动定时器
// 等待超声测量完成最多等待1ms (100次 * 10us) // 等待超声测量完成最多等待1ms (100次 * 10us)
// PWM发送约需16.7us (5周期 × 3.33us),超时时间充足 // TIMER16将在240us时设置g_ultrasonic_measure_done = true
uint16_t timeout_count = 0; uint16_t timeout_count = 0;
const uint16_t max_timeout = 100; const uint16_t max_timeout = 150;
while (!g_ultrasonic_measure_done && timeout_count < max_timeout) { while (!g_ultrasonic_measure_done && timeout_count < max_timeout) {
delay_10us(1); // 延时 10us delay_10us(1); // 延时 10us
@@ -277,7 +281,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
// 测量完成,发送正常响应 // 测量完成,发送正常响应
send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
} else { } else {
// 超时,发送读取错误包(理论上不应该发生,因为PWM只需16.7us // 超时,发送读取错误包(理论上不应该发生,因为TIMER16会在240us时触发
static const uint8_t timeout_error_data[] = { 0xFF, 0xFF, 0xFF, 0xFF }; static const uint8_t timeout_error_data[] = { 0xFF, 0xFF, 0xFF, 0xFF };
send_response(RESP_TYPE_OK, timeout_error_data, sizeof(timeout_error_data)); send_response(RESP_TYPE_OK, timeout_error_data, sizeof(timeout_error_data));
} }

View File

@@ -102,39 +102,30 @@ void SysTick_Handler(void) {
delay_decrement(); delay_decrement();
} }
// /** void TIMER16_IRQHandler(void) {
// * @brief This function handles TIMER15 interrupt request. // 处理通道0比较中断240us时触发
// * @param[in] none if (timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_CH0)) {
// * @param[out] none timer_interrupt_flag_clear(TIMER16, TIMER_INT_FLAG_CH0);
// * @retval None
// */
// void TIMER15_IRQHandler(void) {
// if (timer_interrupt_flag_get(US_TX_DELAY_TIMER, TIMER_INT_FLAG_UP) == SET)
// {
// timer_interrupt_flag_clear(US_TX_DELAY_TIMER, TIMER_INT_FLAG_UP);
// exti_interrupt_enable(US_RX_GPIO_EXTI); // turn on hardware external input interrupt
// timer_counter_value_config(US_ECHO_TIMER, 0);
// timer_enable(US_ECHO_TIMER); // turn on timer to calculate the first ultrasonic echo time
// timer_disable(US_TX_DELAY_TIMER);
// }
// }
void TIMER15_IRQHandler(void) { // 在240us时执行的操作
if (timer_interrupt_flag_get(TIMER15, TIMER_INT_FLAG_CH1)) { g_ultrasonic_measure_done = true; // 设置测量完成标志
timer_interrupt_flag_clear(TIMER15, TIMER_INT_FLAG_CH1);
// g_ultrasonic_measure_done = true; // TODO 测距命令发送回报标识位,最终不应在这里 // TODO: 在这里可以执行其他240us时需要的操作
gpio_bit_set(GPIOA, GPIO_PIN_0); // TODO waiting for delete // 例如启动其他定时器、设置GPIO、记录时间戳等
} }
if (timer_interrupt_flag_get(TIMER15, TIMER_INT_FLAG_UP)) { // 处理重装载中断1000us时触发即超时
timer_interrupt_flag_clear(TIMER15, TIMER_INT_FLAG_UP); if (timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_UP)) {
timer_disable(TIMER15); timer_interrupt_flag_clear(TIMER16, TIMER_INT_FLAG_UP);
}
// 达到最大时间1ms自动关闭定时器
timer_disable(TIMER16);
// TODO: 超时处理逻辑
// 如果需要,可以在这里设置超时标志或执行其他清理操作
}
} }
/** /**
* @brief This function handles external lines 0 to 1 interrupt request * @brief This function handles external lines 0 to 1 interrupt request
* @param[in] none * @param[in] none
@@ -165,7 +156,7 @@ void TIMER13_IRQHandler(void)
if(pwm_cycle_count >= (ULTRASONIC_TX_CYCLES)) { if(pwm_cycle_count >= (ULTRASONIC_TX_CYCLES)) {
timer_disable(TIMER13); timer_disable(TIMER13);
pwm_cycle_count = 0; pwm_cycle_count = 0;
g_ultrasonic_measure_done = true; // TODO 测距命令发送回报标识位,最终不应在这里 // g_ultrasonic_measure_done = true; // 注释掉现在由TIMER16在240us时设置
} }
} }

View File

@@ -74,29 +74,10 @@ void ultrasonic_pwm_out_cycles(void) {
timer_enable(US_TX_TIMER); timer_enable(US_TX_TIMER);
// TODO 启动后续回波计时器 // TODO 启动后续回波计时器
// timer_enable(TIMER15); // timer_enable(US_ECHO_TIMER);
} }
// void ultrasonic_transmit_debounce_delay(const uint16_t micro_second) {
// rcu_periph_clock_enable(US_TX_DELAY_RCU);
// timer_deinit(US_TX_DELAY_TIMER);
// timer_parameter_struct timer_initpara;
// timer_struct_para_init(&timer_initpara);
// timer_initpara.prescaler = 71;
// timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
// timer_initpara.counterdirection = TIMER_COUNTER_UP;
// timer_initpara.period = micro_second - 1;
// timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
// timer_initpara.repetitioncounter = 0;
// timer_init(US_TX_DELAY_TIMER, &timer_initpara);
// timer_auto_reload_shadow_enable(US_TX_DELAY_TIMER);
// timer_interrupt_enable(US_TX_DELAY_TIMER, TIMER_INT_UP);
// nvic_irq_enable(TIMER15_IRQn, 1U);
// }
void ultrasonic_receive_exti_config(void) { void ultrasonic_receive_exti_config(void) {
rcu_periph_clock_enable(US_RX_GPIO_RCU); rcu_periph_clock_enable(US_RX_GPIO_RCU);
rcu_periph_clock_enable(US_RX_EXTI_RCU); rcu_periph_clock_enable(US_RX_EXTI_RCU);
@@ -112,47 +93,51 @@ void ultrasonic_receive_exti_config(void) {
} }
void ultrasonic_echo_timer_config(void) { void ultrasonic_echo_timer_config(void) {
// 使能TIMER16时钟
rcu_periph_clock_enable(US_ECHO_RCU); rcu_periph_clock_enable(US_ECHO_RCU);
// 复位定时器到默认状态
timer_deinit(US_ECHO_TIMER); timer_deinit(US_ECHO_TIMER);
// 配置基本定时器参数
timer_parameter_struct timer_initpara; timer_parameter_struct timer_initpara;
timer_struct_para_init(&timer_initpara); timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = 71;
// 设置分频器72MHz ÷ 72 = 1MHz每个计数 = 1us
timer_initpara.prescaler = 71; // (72-1)实际分频比为72
timer_initpara.alignedmode = TIMER_COUNTER_EDGE; timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP; timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = ULTRASONIC_MAX_TOF_RELOAD - 1;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER15, &timer_initpara);
// 设置周期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_oc_parameter_struct timer_oc_initpara;
timer_channel_output_struct_para_init(&timer_oc_initpara); timer_channel_output_struct_para_init(&timer_oc_initpara);
timer_oc_initpara.outputstate = TIMER_CCX_ENABLE;
// 禁用输出,仅用于内部比较中断
timer_oc_initpara.outputstate = TIMER_CCX_DISABLE;
timer_oc_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH; timer_oc_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_channel_output_config(TIMER15, TIMER_CH_1,&timer_oc_initpara); timer_channel_output_config(US_ECHO_TIMER, US_ECHO_CH, &timer_oc_initpara);
timer_interrupt_enable(TIMER15, TIMER_INT_CH1 | TIMER_INT_UP); // 设置比较模式为时间比较不是PWM模式
nvic_irq_enable(TIMER15_IRQn, 0); 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);
// timer_parameter_struct timer_initpara; // 启用比较中断CH0和重装载中断UP
// timer_struct_para_init(&timer_initpara); timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_CH0); // 240us比较中断
// timer_initpara.prescaler = 71; timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_UP); // 1000us重装载中断
// timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
// timer_initpara.counterdirection = TIMER_COUNTER_UP;
// timer_initpara.period = ULTRASONIC_MAX_TOF_RELOAD;
// timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
// timer_initpara.repetitioncounter = 0;
// timer_init(US_ECHO_TIMER, &timer_initpara);
// timer_ic_parameter_struct timer_icinitpara;
// timer_channel_input_struct_para_init(&timer_icinitpara);
// timer_icinitpara.icpolarity = TIMER_IC_POLARITY_BOTH_EDGE;
// timer_icinitpara.icselection = TIMER_IC_SELECTION_INDIRECTTI;
// timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
// timer_icinitpara.icfilter = 0x03;
// timer_input_capture_config(US_ECHO_TIMER, US_ECHO_CH, &timer_icinitpara);
// 配置NVIC中断优先级设置为较高优先级1确保及时响应
nvic_irq_enable(TIMER16_IRQn, 1);
// 注意定时器配置完成但不启动需要在其他地方调用timer_enable()启动
} }
void ultrasonic_config(void) { void ultrasonic_config(void) {