dev #1

Merged
hulk merged 7 commits from dev into main 2025-08-25 17:32:31 +08:00
8 changed files with 98 additions and 136 deletions
Showing only changes of commit 2d752eed5e - Show all commits

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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));
}

View File

@@ -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时设置
}
}

View File

@@ -38,10 +38,11 @@ OF SUCH DAMAGE.
#include "led.h"
#include "command.h"
#include <stdio.h>
#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);
}
}

View File

@@ -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;
// }