Compare commits

..

5 Commits

7 changed files with 90 additions and 102 deletions

View File

@@ -36,15 +36,15 @@
/******************************************************************************/ /******************************************************************************/
#define RS485_RCU RCU_USART0 #define RS485_RCU RCU_USART1
#define RS485_GPIO_RCU RCU_GPIOA #define RS485_GPIO_RCU RCU_GPIOA
#define RS485_GPIO_PORT GPIOA #define RS485_GPIO_PORT GPIOA
#define RS485_TX_PIN GPIO_PIN_2 #define RS485_TX_PIN GPIO_PIN_2
#define RS485_RX_PIN GPIO_PIN_3 #define RS485_RX_PIN GPIO_PIN_3
#define RS485_PHY USART0 #define RS485_PHY USART1
#define RS485_BAUDRATE 115200U #define RS485_BAUDRATE 115200U
#define RS485_EN_PIN GPIO_PIN_1 #define RS485_EN_PIN GPIO_PIN_1
#define RS485_IRQ USART0_IRQn #define RS485_IRQ USART1_IRQn
/******************************************************************************/ /******************************************************************************/
@@ -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

@@ -12,8 +12,8 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */ /* Memories definition */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
} }
/* Sections */ /* Sections */

View File

@@ -18,6 +18,7 @@
#include "board_config.h" #include "board_config.h"
#include "gd32e23x_usart.h" #include "gd32e23x_usart.h"
#include "ultrasonic_analog.h" #include "ultrasonic_analog.h"
#include "systick.h"
/* ============================================================================ /* ============================================================================
* 协议格式说明 * 协议格式说明
@@ -254,19 +255,37 @@ void handle_command(const uint8_t *frame, uint8_t len) {
// 仅基础命令,如 M1, M2, M3 // 仅基础命令,如 M1, M2, M3
switch (base_cmd) { switch (base_cmd) {
case 1u: // M1: enable sensor report case 1u: // M1: enable sensor report
// g_ultrasonic_measure_done = false;
ultrasonic_pwm_out_cycles();
gpio_bit_toggle(GPIOA, GPIO_PIN_0); gpio_bit_toggle(GPIOA, GPIO_PIN_0);
while (g_ultrasonic_measure_done) // 启动超声波PWM发送
{ ultrasonic_pwm_out_cycles();
g_ultrasonic_measure_done = false;
send_response(RESP_TYPE_OK, s_report_status_err, sizeof(s_report_status_err)); // 启动TIMER16用于240us精确计时
return; 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;
while (!g_ultrasonic_measure_done && timeout_count < max_timeout) {
delay_10us(1); // 延时 10us
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));
} else {
// 超时发送读取错误包理论上不应该发生因为TIMER16会在240us时触发
static const uint8_t timeout_error_data[] = { 0xFF, 0xFF, 0xFF, 0xFF };
send_response(RESP_TYPE_OK, timeout_error_data, sizeof(timeout_error_data));
}
return;
case 2u: // M2: disable sensor report case 2u: // M2: disable sensor report
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));

View File

@@ -39,8 +39,6 @@ OF SUCH DAMAGE.
#include "led.h" #include "led.h"
#include "ultrasonic_analog.h" #include "ultrasonic_analog.h"
extern uint16_t g_capture_value;
/*! /*!
\brief this function handles NMI exception \brief this function handles NMI exception
\param[in] none \param[in] none
@@ -104,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
@@ -147,7 +136,7 @@ void EXTI0_1_IRQHandler(void) {
if (exti_interrupt_flag_get(US_RX_GPIO_EXTI) == SET) if (exti_interrupt_flag_get(US_RX_GPIO_EXTI) == SET)
{ {
exti_interrupt_flag_clear(US_RX_GPIO_EXTI); exti_interrupt_flag_clear(US_RX_GPIO_EXTI);
g_capture_value = timer_channel_capture_value_register_read(US_ECHO_TIMER, US_ECHO_CH); // g_capture_value = timer_channel_capture_value_register_read(US_ECHO_TIMER, US_ECHO_CH);
timer_disable(US_ECHO_TIMER); timer_disable(US_ECHO_TIMER);
exti_interrupt_disable(US_RX_GPIO_EXTI); exti_interrupt_disable(US_RX_GPIO_EXTI);
@@ -167,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

@@ -42,8 +42,6 @@ OF SUCH DAMAGE.
#include "board_config.h" #include "board_config.h"
#include "ultrasonic_analog.h" #include "ultrasonic_analog.h"
volatile uint16_t g_capture_value;
/*! /*!
\brief main function \brief main function
\param[in] none \param[in] none

View File

@@ -6,7 +6,6 @@
#include "systick.h" #include "systick.h"
volatile bool g_ultrasonic_measure_done = false; volatile bool g_ultrasonic_measure_done = false;
extern uint32_t g_capture_value;
void ultrasonic_tx_init(void) { void ultrasonic_tx_init(void) {
@@ -73,29 +72,12 @@ void ultrasonic_pwm_out_cycles(void) {
timer_channel_output_state_config(TIMER13, TIMER_CH_0, TIMER_CCX_ENABLE); timer_channel_output_state_config(TIMER13, TIMER_CH_0, TIMER_CCX_ENABLE);
timer_enable(US_TX_TIMER); timer_enable(US_TX_TIMER);
timer_enable(TIMER15);
// TODO 启动后续回波计时器
// 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);
@@ -111,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) {

View File

@@ -1,5 +1,5 @@
# Project basic info # Project basic info
set(PROJECT_NAME "gd32e23x") set(PROJECT_NAME "ultrasonic-analog")
set(VERSION_MAJOR 1) set(VERSION_MAJOR 1)
set(VERSION_MINOR 0) set(VERSION_MINOR 0)
set(VERSION_PATCH 0) set(VERSION_PATCH 0)
@@ -8,7 +8,7 @@ string(TIMESTAMP BUILD_DATE "%Y-%m-%d")
# 编译条件如IIC类型等 # 编译条件如IIC类型等
# set(IIC_TYPE "AutoDetectDriveCurrent") # set(IIC_TYPE "AutoDetectDriveCurrent")
set(IIC_TYPE "HW-IIC") set(IIC_TYPE "24V")
# 其它自定义宏 # 其它自定义宏
add_definitions(-DIIC_TYPE=${IIC_TYPE}) add_definitions(-DIIC_TYPE=${IIC_TYPE})