diff --git a/Inc/board_config.h b/Inc/board_config.h index 46b6709..9c42b2d 100644 --- a/Inc/board_config.h +++ b/Inc/board_config.h @@ -36,15 +36,15 @@ /******************************************************************************/ -#define RS485_RCU RCU_USART1 +#define RS485_RCU RCU_USART0 #define RS485_GPIO_RCU RCU_GPIOA #define RS485_GPIO_PORT GPIOA #define RS485_TX_PIN GPIO_PIN_2 #define RS485_RX_PIN GPIO_PIN_3 -#define RS485_PHY USART1 +#define RS485_PHY USART0 #define RS485_BAUDRATE 115200U #define RS485_EN_PIN GPIO_PIN_1 -#define RS485_IRQ USART1_IRQn +#define RS485_IRQ USART0_IRQn /******************************************************************************/ @@ -58,6 +58,11 @@ /******************************************************************************/ +#define US_TX_DELAY_RCU RCU_TIMER15 +#define US_TX_DELAY_TIMER TIMER15 + +/******************************************************************************/ + #define US_RX_GPIO_RCU RCU_GPIOB #define US_RX_EXTI_RCU RCU_CFGCMP #define US_RX_GPIO_PORT GPIOA @@ -68,6 +73,7 @@ /******************************************************************************/ +// 修改为TIMER15相关定义 #define US_ECHO_RCU RCU_TIMER16 #define US_ECHO_TIMER TIMER16 #define US_ECHO_CH TIMER_CH_0 @@ -75,9 +81,4 @@ /******************************************************************************/ -#define TIME_CORRECTION_US 230U -#define CAPTURE_VALUE_MAX 550U - -/******************************************************************************/ - #endif //BOARD_CONFIG_H diff --git a/Inc/command.h b/Inc/command.h index d5b56f1..514347d 100644 --- a/Inc/command.h +++ b/Inc/command.h @@ -81,6 +81,8 @@ void command_process(void); */ void handle_command(const uint8_t *cmd, uint8_t len); +void ultrasonic_distance_raw_value_report(void); + /** @} */ // end of Command group #endif // COMMAND_H diff --git a/Inc/ultrasonic_analog.h b/Inc/ultrasonic_analog.h index ed6af7e..5aa0140 100644 --- a/Inc/ultrasonic_analog.h +++ b/Inc/ultrasonic_analog.h @@ -9,23 +9,13 @@ extern volatile bool g_ultrasonic_measure_done; /**************************************************************************************************/ #define ULTRASONIC_TX_CYCLES 5U /* 发送5个PWM周期驱动换能器 */ -#define ULTRASONIC_TX_TIME 498U // ms -#define ULTRASONIC_MAX_TOF_RELOAD 1000U //us +#define ULTRASONIC_TX_RINGDOWN_RELOAD 240U // 240us +#define ULTRASONIC_MAX_TOF_RELOAD 1000U // 1000us /**************************************************************************************************/ -void ultrasonic_tx_init(void); - void ultrasonic_pwm_out_cycles(void); -// void ultrasonic_transmit_delay(const uint16_t micro_second); - -// void ultrasonic_rece_exti_config(void); - -void ultrasonic_echo_timer_config(void); - void ultrasonic_config(void); -// uint16_t ultrasonic_calc_distance(void); - -#endif // UART_H +#endif // ULTRASONIC_ANALOG_H diff --git a/LD/gd32e23x_flash.ld b/LD/gd32e23x_flash.ld index f48d452..405de65 100644 --- a/LD/gd32e23x_flash.ld +++ b/LD/gd32e23x_flash.ld @@ -12,8 +12,8 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K } /* Sections */ diff --git a/Src/command.c b/Src/command.c index 9ef1150..18b9721 100644 --- a/Src/command.c +++ b/Src/command.c @@ -30,7 +30,7 @@ * @details * Host -> Device 命令帧格式: * [0] HEADER = 0xD5 // 包头标识 - * [1] BOARD_TYPE = 0x03 // 板卡类型标识 + * [1] BOARD_TYPE = 0x04 // 板卡类型标识 * [2] LEN = 数据区字节数 // 有效载荷长度 * [3..(3+LEN-1)] 数据 // 命令数据,如 "M1", "M2S123" * [last] CRC = 校验码 // 从索引1到(last-1)的累加和低8位 @@ -155,13 +155,6 @@ static void send_response(uint8_t type, const uint8_t *payload, uint8_t len) // 等待发送完成 while (usart_flag_get(RS485_PHY, USART_FLAG_TC) == RESET) {} - // // 使用printf发送(通过重定向到串口) - // for (uint8_t i = 0; i < buf_len; i++) { - // printf("%c", buf[i]); - // } - - // // 刷新缓冲区 - // fflush(stdout); } /** @@ -254,18 +247,9 @@ void handle_command(const uint8_t *frame, uint8_t len) { if (cmd_index == cmd_len) { // 仅基础命令,如 M1, M2, M3 switch (base_cmd) { - case 1u: // M1: enable sensor report - gpio_bit_toggle(GPIOA, GPIO_PIN_0); - + case 1u: // M1: send ultrasonic driver single and respon raw data // 启动超声波PWM发送 ultrasonic_pwm_out_cycles(); - - // 启动TIMER16用于240us精确计时 - timer_counter_value_config(TIMER16, 0); // 复位计数器 - timer_enable(TIMER16); // 启动定时器 - - // 等待超声测量完成,最多等待1ms (100次 * 10us) - // TIMER16将在240us时设置g_ultrasonic_measure_done = true uint16_t timeout_count = 0; const uint16_t max_timeout = 150; @@ -274,15 +258,11 @@ void handle_command(const uint8_t *frame, uint8_t len) { timeout_count++; } - gpio_bit_toggle(GPIOA, GPIO_PIN_0); - // 根据等待结果发送不同的响应 if (g_ultrasonic_measure_done) { - // 测量完成,发送正常响应 - send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); + ultrasonic_distance_raw_value_report(); } else { - // 超时,发送读取错误包(理论上不应该发生,因为TIMER16会在240us时触发) - static const uint8_t timeout_error_data[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + static const uint8_t timeout_error_data[] = {0xFF, 0xFF }; send_response(RESP_TYPE_OK, timeout_error_data, sizeof(timeout_error_data)); } return; @@ -329,7 +309,6 @@ void handle_command(const uint8_t *frame, uint8_t len) { { // case 100u: // // set_pwm(param_value); - // printf("Set PWM to %u\n", param_value); // return; default: @@ -437,3 +416,32 @@ void command_process(void) { } } } + +/** + * @brief 超声波测距原始值上报函数 + * @details 读取超声波测距的定时器计数值,计算距离并按协议格式发送响应包 + * 距离计算公式:距离(0.1mm) = 定时器计数值(us) * 17 + * 响应数据格式:4字节32位无符号整数,单位为0.1mm + * @note 定时器配置为1us计数,最大计时2000us,对应距离340mm + * @ingroup Command + */ +void ultrasonic_distance_raw_value_report(void) { + uint8_t raw_result[2]; + uint16_t raw_distance = 0; + + // 读取定时器计数值(微秒) + uint16_t timer_count_us = timer_counter_read(US_ECHO_TIMER); + + // 计算距离:定时器计数值 * 17 = 距离(0.1mm) + // 声速340m/s,往返距离,时间单位us + // 距离(mm) = (timer_count_us * 340) / (2 * 1000) = timer_count_us * 0.17 + // 距离(0.1mm) = timer_count_us * 1.7 ≈ timer_count_us * 17 / 10 + raw_distance = (uint16_t)timer_count_us * 17; + + // 将16位距离值分解为2个字节(大端序) + raw_result[0] = (uint8_t)(raw_distance >> 8); + raw_result[1] = (uint8_t)(raw_distance & 0xFF); + + // 发送响应包 + send_response(RESP_TYPE_OK, raw_result, sizeof(raw_result)); +} diff --git a/Src/gd32e23x_it.c b/Src/gd32e23x_it.c index 2544d72..8effe16 100644 --- a/Src/gd32e23x_it.c +++ b/Src/gd32e23x_it.c @@ -102,27 +102,18 @@ void SysTick_Handler(void) { delay_decrement(); } -void TIMER16_IRQHandler(void) { - // 处理通道0比较中断(240us时触发) - if (timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_CH0)) { +void TIMER16_IRQHandler(void) +{ + // CH0比较中断 (ULTRASONIC_TX_RINGDOWN_RELOAD) + if(timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_CH0) != RESET) { timer_interrupt_flag_clear(TIMER16, TIMER_INT_FLAG_CH0); - - // 在240us时执行的操作 - g_ultrasonic_measure_done = true; // 设置测量完成标志 - - // TODO: 在这里可以执行其他240us时需要的操作 - // 例如:启动其他定时器、设置GPIO、记录时间戳等 + exti_interrupt_enable(US_RX_GPIO_EXTI); } - - // 处理重装载中断(1000us时触发,即超时) - if (timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_UP)) { + + // UP更新中断 (ULTRASONIC_MAX_TOF_RELOAD) + if(timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_UP) != RESET) { timer_interrupt_flag_clear(TIMER16, TIMER_INT_FLAG_UP); - - // 达到最大时间(1ms),自动关闭定时器 - timer_disable(TIMER16); - - // TODO: 超时处理逻辑 - // 如果需要,可以在这里设置超时标志或执行其他清理操作 + timer_disable(US_ECHO_TIMER); } } @@ -136,14 +127,12 @@ void EXTI0_1_IRQHandler(void) { if (exti_interrupt_flag_get(US_RX_GPIO_EXTI) == SET) { exti_interrupt_flag_clear(US_RX_GPIO_EXTI); - // g_capture_value = timer_channel_capture_value_register_read(US_ECHO_TIMER, US_ECHO_CH); - timer_disable(US_ECHO_TIMER); + g_ultrasonic_measure_done = true; // 超声转换完成,置位flag后有命令处理部分回包 exti_interrupt_disable(US_RX_GPIO_EXTI); } } - /* PWM周期计数器 - 使用ULTRASONIC_TX_CYCLES宏 */ volatile uint8_t pwm_cycle_count = 0; @@ -156,7 +145,6 @@ void TIMER13_IRQHandler(void) if(pwm_cycle_count >= (ULTRASONIC_TX_CYCLES)) { timer_disable(TIMER13); pwm_cycle_count = 0; - // g_ultrasonic_measure_done = true; // 注释掉,现在由TIMER16在240us时设置 } } diff --git a/Src/main.c b/Src/main.c index 8ddfe26..3343769 100644 --- a/Src/main.c +++ b/Src/main.c @@ -38,10 +38,11 @@ OF SUCH DAMAGE. #include "led.h" #include "command.h" #include -#include "i2c.h" #include "board_config.h" #include "ultrasonic_analog.h" +// #define FLASH_SIZE_ADDR (*(const uint16_t *)0x1FFFF7E0) + /*! \brief main function \param[in] none @@ -58,6 +59,7 @@ int main(void) led_init(); ultrasonic_config(); + ultrasonic_pwm_out_cycles(); #ifdef DEBUG_VERBOSE char hello_world[] = {"Hello World!\r\n"}; @@ -73,14 +75,7 @@ int main(void) while(1){ - - // ultrasonic_pwm_out_cycles(); - - // delay_ms(10); command_process(); delay_ms(10); - // uint16_t ultrasonic_value = ultrasonic_calc_distance(); - // printf("ultrasonic value: %d", ultrasonic_value); - // delay_ms(10); } } diff --git a/Src/ultrasonic_analog.c b/Src/ultrasonic_analog.c index b67aeb2..1cb0fd7 100644 --- a/Src/ultrasonic_analog.c +++ b/Src/ultrasonic_analog.c @@ -9,13 +9,6 @@ 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); @@ -59,23 +52,32 @@ void ultrasonic_tx_init(void) { timer_counter_value_config(US_TX_TIMER, 0); timer_interrupt_enable(US_TX_TIMER, TIMER_INT_UP); - nvic_irq_enable(TIMER13_IRQn, 2); + 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); - // TODO 启动后续回波计时器 - // timer_enable(US_ECHO_TIMER); - + // 启动回波计时器 + timer_enable(US_ECHO_TIMER); } void ultrasonic_receive_exti_config(void) { @@ -88,75 +90,51 @@ void ultrasonic_receive_exti_config(void) { 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.prescaler = 71; // 72MHz/72 = 1MHz (1us per count) 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.period = (ULTRASONIC_MAX_TOF_RELOAD - 1); timer_initpara.clockdivision = TIMER_CKDIV_DIV1; - - // 初始化定时器基本参数 timer_init(US_ECHO_TIMER, &timer_initpara); - // 配置通道0用于240us比较中断(不是PWM输出,仅用于比较) + 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_DISABLE; + timer_oc_initpara.outputstate = TIMER_CCX_ENABLE; timer_oc_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH; - timer_channel_output_config(US_ECHO_TIMER, US_ECHO_CH, &timer_oc_initpara); + timer_channel_output_config(US_ECHO_TIMER, TIMER_CH_0, &timer_oc_initpara); - // 设置比较模式为时间比较(不是PWM模式) - timer_channel_output_mode_config(US_ECHO_TIMER, US_ECHO_CH, TIMER_OC_MODE_TIMING); + // 配置输出比较模式 + timer_channel_output_mode_config(US_ECHO_TIMER, TIMER_CH_0, TIMER_OC_MODE_TIMING); - // 设置240us时触发比较中断(计数值239,因为从0开始计数) - timer_channel_output_pulse_value_config(US_ECHO_TIMER, US_ECHO_CH, 239); + // 设置比较值 + timer_channel_output_pulse_value_config(US_ECHO_TIMER, TIMER_CH_0, (ULTRASONIC_TX_RINGDOWN_RELOAD - 1)); - // 启用比较中断(CH0)和重装载中断(UP) - timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_CH0); // 240us比较中断 - timer_interrupt_enable(US_ECHO_TIMER, TIMER_INT_UP); // 1000us重装载中断 + // 清除中断标志 + 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中断优先级(设置为较高优先级1,确保及时响应) - nvic_irq_enable(TIMER16_IRQn, 1); + nvic_irq_enable(US_ECHO_TIMER_IRQ, 1U); - // 注意:定时器配置完成但不启动,需要在其他地方调用timer_enable()启动 + // timer_single_pulse_mode_config(US_ECHO_TIMER, TIMER_SP_MODE_SINGLE); } void ultrasonic_config(void) { ultrasonic_tx_init(); - // ultrasonic_transmit_debounce_delay(TIME_CORRECTION_US); - // ultrasonic_receive_exti_config(); + 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; -// }