generated from hulk/gd32e23x_template_cmake_vscode
feat(VL53L4CD): 支持透过玻璃串扰补偿、串口校准命令与校准数据Flash存储
This commit is contained in:
+136
-28
@@ -1,35 +1,35 @@
|
||||
/*!
|
||||
\file main.c
|
||||
\brief running LED
|
||||
|
||||
|
||||
\version 2025-02-10, V2.4.0, demo for GD32E23x
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gd32e23x.h"
|
||||
@@ -38,10 +38,100 @@ OF SUCH DAMAGE.
|
||||
#include "uart_ring_buffer.h"
|
||||
#include "led.h"
|
||||
#include "command.h"
|
||||
#include <stdio.h>
|
||||
#include "i2c.h"
|
||||
#include "board_config.h"
|
||||
#include "VL53L4CD_Driver.h"
|
||||
#include "calib_store.h"
|
||||
|
||||
/*!
|
||||
\brief 向测距串口发送一个字节
|
||||
\param[in] byte: 待发送字节
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
static void uart_put_byte(uint8_t byte)
|
||||
{
|
||||
while (usart_flag_get(UART_PHY, USART_FLAG_TBE) == RESET) {}
|
||||
usart_data_transmit(UART_PHY, byte);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 向测距串口发送以 NUL 结尾的字符串
|
||||
\param[in] s: 字符串指针
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
static void uart_write_str(const char *s)
|
||||
{
|
||||
while (*s != '\0') {
|
||||
uart_put_byte((uint8_t)*s++);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 以十进制输出无符号整数(替代 printf,节省 libc 体积)
|
||||
\param[in] value: 待输出的数值
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
static void uart_write_u32(uint32_t value)
|
||||
{
|
||||
char temp[10];
|
||||
uint8_t i = 0U;
|
||||
|
||||
if (value == 0U) {
|
||||
uart_put_byte('0');
|
||||
return;
|
||||
}
|
||||
while (value > 0U) {
|
||||
temp[i++] = (char)('0' + (value % 10U));
|
||||
value /= 10U;
|
||||
}
|
||||
while (i > 0U) {
|
||||
uart_put_byte((uint8_t)temp[--i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 以十进制输出有符号整数
|
||||
\param[in] value: 待输出的数值
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
static void uart_write_i32(int32_t value) __attribute__((unused));
|
||||
static void uart_write_i32(int32_t value)
|
||||
{
|
||||
uint32_t magnitude;
|
||||
|
||||
if (value < 0) {
|
||||
uart_put_byte('-');
|
||||
magnitude = (uint32_t)(-value);
|
||||
} else {
|
||||
magnitude = (uint32_t)value;
|
||||
}
|
||||
uart_write_u32(magnitude);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 输出一帧测距结果,格式与原 printf 版本逐字节一致
|
||||
\param[in] r: 测距结果指针
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
static void report_result(const vl53l4cd_result_t *r)
|
||||
{
|
||||
uart_write_str("Distance: ");
|
||||
uart_write_u32(r->distance_mm);
|
||||
uart_write_str(" mm | status: ");
|
||||
uart_write_u32(r->range_status);
|
||||
uart_write_str(" | signal: ");
|
||||
uart_write_u32(r->signal_rate_kcps);
|
||||
uart_write_str(" kcps | ambient: ");
|
||||
uart_write_u32(r->ambient_rate_kcps);
|
||||
uart_write_str(" kcps | sigma: ");
|
||||
uart_write_u32(r->sigma_mm);
|
||||
uart_write_str(" mm\r\n");
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief main function
|
||||
@@ -84,21 +174,41 @@ int main(void)
|
||||
if (vl53l4cd_calibrate_offset(VL53L4CD_CALIB_TARGET_MM,
|
||||
VL53L4CD_CALIB_SAMPLES,
|
||||
&cal_offset)) {
|
||||
printf("VL53L4CD offset calibrated: %d mm\r\n", cal_offset);
|
||||
uart_write_str("VL53L4CD offset calibrated: ");
|
||||
uart_write_i32(cal_offset);
|
||||
uart_write_str(" mm\r\n");
|
||||
} else {
|
||||
printf("VL53L4CD offset calibration failed\r\n");
|
||||
uart_write_str("VL53L4CD offset calibration failed\r\n");
|
||||
}
|
||||
#else
|
||||
(void)vl53l4cd_set_offset(VL53L4CD_CALIB_OFFSET_MM);
|
||||
int16_t stored_offset = 0;
|
||||
uint16_t stored_xtalk = 0;
|
||||
bool applied = false;
|
||||
|
||||
#if VL53L4CD_PERSIST_CALIB == CFG_ENABLE
|
||||
/* Flash 末页有有效校准数据时优先生效(M105 保存 / M107 擦除) */
|
||||
if (calib_store_load(&stored_offset, &stored_xtalk)) {
|
||||
vl53l4cd_set_offset(stored_offset);
|
||||
vl53l4cd_set_xtalk(stored_xtalk);
|
||||
applied = true;
|
||||
}
|
||||
#endif
|
||||
if (!applied) {
|
||||
vl53l4cd_set_offset(VL53L4CD_CALIB_OFFSET_MM);
|
||||
#if VL53L4CD_GLASS_XTALK == CFG_ENABLE
|
||||
/* 透过玻璃安装:写入编译期固定串扰补偿 */
|
||||
vl53l4cd_set_xtalk(VL53L4CD_GLASS_XTALK_KCPS);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
vl53l4cd_start_ranging();
|
||||
printf("VL53L4CD ready\r\n");
|
||||
uart_write_str("VL53L4CD ready\r\n");
|
||||
} else {
|
||||
printf("VL53L4CD init failed\r\n");
|
||||
uart_write_str("VL53L4CD init failed\r\n");
|
||||
}
|
||||
|
||||
/* ========== Command Testing ========== */
|
||||
|
||||
|
||||
/* ========== */
|
||||
|
||||
while(1){
|
||||
@@ -109,12 +219,10 @@ int main(void)
|
||||
|
||||
vl53l4cd_clear_interrupt();
|
||||
if (vl53l4cd_get_result(&result)) {
|
||||
printf("Distance: %u mm | status: %u | signal: %lu kcps | ambient: %lu kcps | sigma: %u mm\r\n",
|
||||
result.distance_mm,
|
||||
result.range_status,
|
||||
(unsigned long)result.signal_rate_kcps,
|
||||
(unsigned long)result.ambient_rate_kcps,
|
||||
result.sigma_mm);
|
||||
command_set_last_result(&result); /* 供 M3 命令查询 */
|
||||
if (get_sensor_report_enabled()) {
|
||||
report_result(&result);
|
||||
}
|
||||
}
|
||||
delay_ms(500);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user