Compare commits

..

6 Commits

Author SHA1 Message Date
576d32adb1 适配bootloader 2025-09-20 01:40:24 +08:00
d2519f4cf7 bootloader 2025-09-19 17:56:03 +08:00
5ac3d5afa7 添加M999命令发送版本号 2025-09-16 16:26:14 +08:00
14fa262d35 注释异常命令回包 2025-09-16 14:58:33 +08:00
70b8e3a602 add data err type 2025-08-25 20:35:54 +08:00
f5cfeb53d2 test 2025-08-25 17:33:32 +08:00
6 changed files with 48 additions and 16 deletions

View File

@@ -39,6 +39,14 @@ void usart1_irq_handler(void);
/******************************************************************************/ /******************************************************************************/
#define MCU_CODE 23u
#define FW_VERSION_MAJOR 0
#define FW_VERSION_MINOR 0
#define FW_VERSION_PATCH 3
/******************************************************************************/
#define RCU_GPIO_I2C RCU_GPIOF #define RCU_GPIO_I2C RCU_GPIOF
#define RCU_I2C RCU_I2C0 #define RCU_I2C RCU_I2C0
#define I2C_SCL_PORT GPIOF #define I2C_SCL_PORT GPIOF

View File

@@ -10,7 +10,7 @@ extern volatile bool g_ultrasonic_measure_done;
#define ULTRASONIC_TX_CYCLES 5U /* 发送5个PWM周期驱动换能器 */ #define ULTRASONIC_TX_CYCLES 5U /* 发送5个PWM周期驱动换能器 */
#define ULTRASONIC_TX_RINGDOWN_RELOAD 240U // 240us #define ULTRASONIC_TX_RINGDOWN_RELOAD 240U // 240us
#define ULTRASONIC_MAX_TOF_RELOAD 1000U // 1000us #define ULTRASONIC_MAX_TOF_RELOAD 2000U // 1000us
/**************************************************************************************************/ /**************************************************************************************************/

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 = 0x08002000, LENGTH = 32K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
} }
/* Sections */ /* Sections */

View File

@@ -17,6 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include "board_config.h" #include "board_config.h"
#include "gd32e23x_usart.h" #include "gd32e23x_usart.h"
#include "gd32e23x_misc.h"
#include "ultrasonic_analog.h" #include "ultrasonic_analog.h"
#include "systick.h" #include "systick.h"
@@ -72,6 +73,7 @@
#define RESP_TYPE_HEADER_ERR 0xF2 /**< 包头错误 */ #define RESP_TYPE_HEADER_ERR 0xF2 /**< 包头错误 */
#define RESP_TYPE_TYPE_ERR 0xF3 /**< 类型错误 */ #define RESP_TYPE_TYPE_ERR 0xF3 /**< 类型错误 */
#define RESP_TYPE_LEN_ERR 0xF4 /**< 长度错误 */ #define RESP_TYPE_LEN_ERR 0xF4 /**< 长度错误 */
#define RESP_TYPE_DATA_ERR 0xF5 /**< 数据错误 */
/** @} */ /** @} */
/* ============================================================================ /* ============================================================================
@@ -225,7 +227,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
// 命令必须以 'M' 开头 // 命令必须以 'M' 开头
if (cmd[0] != 'M'){ if (cmd[0] != 'M'){
send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err)); // send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err));
return; return;
} }
@@ -237,7 +239,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
if (used_base_cmd == 0) if (used_base_cmd == 0)
{ {
// 'M' 后没有数字,格式错误 // 'M' 后没有数字,格式错误
send_response(RESP_TYPE_LEN_ERR, s_report_status_err, sizeof(s_report_status_err)); // send_response(RESP_TYPE_LEN_ERR, s_report_status_err, sizeof(s_report_status_err));
return; return;
} }
@@ -251,7 +253,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
// 启动超声波PWM发送 // 启动超声波PWM发送
ultrasonic_pwm_out_cycles(); ultrasonic_pwm_out_cycles();
uint16_t timeout_count = 0; uint16_t timeout_count = 0;
const uint16_t max_timeout = 150; const uint16_t max_timeout = 250;
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
@@ -263,7 +265,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
ultrasonic_distance_raw_value_report(); ultrasonic_distance_raw_value_report();
} else { } else {
static const uint8_t timeout_error_data[] = {0xFF, 0xFF }; static const uint8_t timeout_error_data[] = {0xFF, 0xFF };
send_response(RESP_TYPE_OK, timeout_error_data, sizeof(timeout_error_data)); send_response(RESP_TYPE_DATA_ERR, timeout_error_data, sizeof(timeout_error_data));
} }
return; return;
@@ -283,6 +285,19 @@ 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));
// return; // return;
case 999u: //M999: 输出固件版本号vMCU_CODE.FW_VERSION_MAJOR.FW_VERSION_MINOR.FW_VERSION_PATCH
char version_str[16];
int n = snprintf(version_str, sizeof(version_str), "v%u.%u.%u.%u", MCU_CODE, FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_PATCH);
send_response(RESP_TYPE_OK, (uint8_t *)version_str, (uint8_t)n);
// send_response(RESP_TYPE_OK, (uint8_t *)"v23.0.0.3", 9);
return;
case 9999u:
// M9999: 重启系统
__disable_irq(); // 关闭全局中断GD32E230 CMSIS标准函数
nvic_system_reset(); // 系统复位GD32E230标准库函数
break;
default: default:
// 其它无参数命令在此扩展示例M100处理逻辑该如何待定 // 其它无参数命令在此扩展示例M100处理逻辑该如何待定
// 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));
@@ -290,7 +305,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
break; break;
} }
// 未在处理列表的无参数基础命令,回复错误 // 未在处理列表的无参数基础命令,回复错误
send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err)); // send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err));
return; return;
} }
@@ -301,7 +316,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
const uint8_t used_param_cmd = parse_uint_dec(&cmd[cmd_index], (uint8_t)(cmd_len - cmd_index), &param_value); const uint8_t used_param_cmd = parse_uint_dec(&cmd[cmd_index], (uint8_t)(cmd_len - cmd_index), &param_value);
if (used_param_cmd == 0) { if (used_param_cmd == 0) {
// 'S' 后没有数字,格式错误 // 'S' 后没有数字,格式错误
send_response(RESP_TYPE_LEN_ERR, s_report_status_err, sizeof(s_report_status_err)); // send_response(RESP_TYPE_LEN_ERR, s_report_status_err, sizeof(s_report_status_err));
return; return;
} }
@@ -314,7 +329,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
default: default:
break; break;
} }
send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err)); // send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err));
} }
} }
@@ -394,14 +409,14 @@ void command_process(void) {
#endif #endif
if (verification_status && cmd_buf[1] != PROTOCOL_BOARD_TYPE) { if (verification_status && cmd_buf[1] != PROTOCOL_BOARD_TYPE) {
send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err)); // send_response(RESP_TYPE_TYPE_ERR, s_report_status_err, sizeof(s_report_status_err));
verification_status = false; verification_status = false;
} }
if (verification_status) { if (verification_status) {
uint8_t crc_calc = command_sum_crc_calc(cmd_buf, expected_cmd_len); uint8_t crc_calc = command_sum_crc_calc(cmd_buf, expected_cmd_len);
uint8_t crc_recv = cmd_buf[expected_cmd_len - 1]; uint8_t crc_recv = cmd_buf[expected_cmd_len - 1];
if (crc_calc != crc_recv) { if (crc_calc != crc_recv) {
send_response(RESP_TYPE_CRC_ERR, s_report_status_err, sizeof(s_report_status_err)); // send_response(RESP_TYPE_CRC_ERR, s_report_status_err, sizeof(s_report_status_err));
verification_status = false; verification_status = false;
} }
} }
@@ -432,6 +447,12 @@ void ultrasonic_distance_raw_value_report(void) {
// 读取定时器计数值(微秒) // 读取定时器计数值(微秒)
uint16_t timer_count_us = timer_counter_read(US_ECHO_TIMER); uint16_t timer_count_us = timer_counter_read(US_ECHO_TIMER);
if (timer_count_us < ULTRASONIC_TX_RINGDOWN_RELOAD) {
// 超出最大计时范围,返回错误
send_response(RESP_TYPE_DATA_ERR, s_report_status_err, sizeof(s_report_status_err));
return;
}
// 计算距离:定时器计数值 * 17 = 距离(0.1mm) // 计算距离:定时器计数值 * 17 = 距离(0.1mm)
// 声速340m/s往返距离时间单位us // 声速340m/s往返距离时间单位us
// 距离(mm) = (timer_count_us * 340) / (2 * 1000) = timer_count_us * 0.17 // 距离(mm) = (timer_count_us * 340) / (2 * 1000) = timer_count_us * 0.17
@@ -444,4 +465,5 @@ void ultrasonic_distance_raw_value_report(void) {
// 发送响应包 // 发送响应包
send_response(RESP_TYPE_OK, raw_result, sizeof(raw_result)); send_response(RESP_TYPE_OK, raw_result, sizeof(raw_result));
return;
} }

View File

@@ -51,6 +51,8 @@ OF SUCH DAMAGE.
*/ */
int main(void) int main(void)
{ {
nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x2000); // 设置向量表偏移地址为0x2000
led_init(); led_init();
mcu_detect_and_config(); mcu_detect_and_config();
@@ -63,7 +65,7 @@ int main(void)
ultrasonic_config(); ultrasonic_config();
ultrasonic_pwm_out_cycles(); ultrasonic_pwm_out_cycles();
printf("Flash size: %d Kbytes\n", get_flash_size()); // printf("Flash size: %d Kbytes\n", get_flash_size());
#ifdef DEBUG_VERBOSE #ifdef DEBUG_VERBOSE
char hello_world[] = {"Hello World!\r\n"}; char hello_world[] = {"Hello World!\r\n"};

View File

@@ -1,8 +1,8 @@
# Project basic info # Project basic info
set(PROJECT_NAME "ultrasonic-analog") set(PROJECT_NAME "ultrasonic-analog")
set(VERSION_MAJOR 1) set(VERSION_MAJOR 0)
set(VERSION_MINOR 0) set(VERSION_MINOR 0)
set(VERSION_PATCH 0) set(VERSION_PATCH 3)
set(VERSION "V${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") set(VERSION "V${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
string(TIMESTAMP BUILD_DATE "%Y-%m-%d") string(TIMESTAMP BUILD_DATE "%Y-%m-%d")