Simplify the use of timers, timer13 sends ultrasonic waves, timer16 counts (debounce time and flight time)

The ultrasonic transducer is driven only after each command is issued.
This commit is contained in:
2025-08-25 17:05:47 +08:00
parent 16c5a31a63
commit 2d752eed5e
8 changed files with 98 additions and 136 deletions

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