sync: 合并内网 LDC1612_last_version 代码变更

- 覆盖 Src/Inc/SDK/LD/doc 等源码文件
- 保留 cmake 构建配置和 Git 历史不变
- 来源: 内网 LDC1612_last_version
This commit is contained in:
2026-06-30 09:46:25 +08:00
parent 1d7afaa382
commit b280589e71
97 changed files with 55304 additions and 56365 deletions
+86 -92
View File
@@ -1,92 +1,86 @@
#ifndef BOARD_CONFIG_H
#define BOARD_CONFIG_H
#include "version.h"
#define GD32E23XF4 0x10
#define GD32E23XF6 0x20
#define GD32E23XF8 0x40
/* >>>>>>>>>>>>>>>>>>>>[RS485 PHY DEFINE]<<<<<<<<<<<<<<<<<<<< */
// #define RS485_MAX13487 // RS485 PHY : MAX13487 (AutoDir)
#undef RS485_MAX13487 // RS485 PHY : SP3487 (no AutoDir)
/* >>>>>>>>>>>>>>>>>>>>[IIC TYPE DEFINE]<<<<<<<<<<<<<<<<<<<< */
// #define SOFTWARE_IIC // IIC Type : Software IIC
#undef SOFTWARE_IIC // IIC Type : Hardware IIC
/* >>>>>>>>>>>>>>>>>>>>[DEBUG ASSERTIONS DEFINE]<<<<<<<<<<<<<<<<<<<< */
// #define DEBUG_VERBOSE // Debug Assertions Status : Debug Verbose Information
#undef DEBUG_VERBOSE // Debug Assertions Status : No Debug Verbose Information
/* >>>>>>>>>>>>>>>>>>>>[EDDY DRIVE CURRENT DETECTION]<<<<<<<<<<<<<<<<<<<< */
// #define EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Enable
#undef EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Disable
/* >>>>>>>>>>>>>>>>>>>>[COMMAND DEBUG]<<<<<<<<<<<<<<<<<<<< */
// #define COM_DEBUG // Enable Command Debug Information
#undef COM_DEBUG // Disable Command Debug Information
/* >>>>>>>>>>>>>>>>>>>>>[LDC1612 DEBUG]<<<<<<<<<<<<<<<<<<<< */
// #define LDC_DEBUG // LDC1612 Driver Debug : Enable
#undef LDC_DEBUG // LDC1612 Driver Debug : Disable
/******************************************************************************/
/* Dynamic USART Configuration Structure */
typedef struct {
uint32_t rcu_usart;
uint32_t usart_periph;
IRQn_Type irq_type;
void (*irq_handler)(void); // 函数指针:指向中断处理函数
} usart_config_t;
extern usart_config_t g_usart_config;
extern uint8_t g_mcu_flash_size;
/* USART中断处理函数声明 */
void usart0_irq_handler(void);
void usart1_irq_handler(void);
/******************************************************************************/
#define RCU_GPIO_I2C RCU_GPIOF
#define RCU_I2C RCU_I2C0
#define I2C_SCL_PORT GPIOF
#define I2C_SCL_PIN GPIO_PIN_1
#define I2C_SDA_PORT GPIOF
#define I2C_SDA_PIN GPIO_PIN_0
#define I2C_GPIO_AF GPIO_AF_1
#define I2C_DEBUG_UART USART0
/******************************************************************************/
#define LED_RCU RCU_GPIOA
#define LED_PORT GPIOA
#define LED_PIN GPIO_PIN_7
/******************************************************************************/
#define RS485_RCU (g_usart_config.rcu_usart)
#define RS485_PHY (g_usart_config.usart_periph)
#define RS485_IRQ (g_usart_config.irq_type)
#define RS485_GPIO_RCU RCU_GPIOA
#define RS485_GPIO_PORT GPIOA
#define RS485_EN_PIN GPIO_PIN_1
#define RS485_TX_PIN GPIO_PIN_2
#define RS485_RX_PIN GPIO_PIN_3
#define RS485_BAUDRATE 115200U
/******************************************************************************/
void mcu_detect_and_config(void);
uint8_t get_flash_size(void);
#endif //BOARD_CONFIG_H
#ifndef BOARD_CONFIG_H
#define BOARD_CONFIG_H
#define GD32E23XF4 0x10
#define GD32E23XF6 0x20
#define GD32E23XF8 0x40
/* >>>>>>>>>>>>>>>>>>>>[RS485 PHY DEFINE]<<<<<<<<<<<<<<<<<<<< */
// #define RS485_MAX13487 // RS485 PHY : MAX13487 (AutoDir)
#undef RS485_MAX13487 // RS485 PHY : SP3487 (no AutoDir)
/* >>>>>>>>>>>>>>>>>>>>[IIC TYPE DEFINE]<<<<<<<<<<<<<<<<<<<< */
// #define SOFTWARE_IIC // IIC Type : Software IIC
#undef SOFTWARE_IIC // IIC Type : Hardware IIC
/* >>>>>>>>>>>>>>>>>>>>[DEBUG ASSERTIONS DEFINE]<<<<<<<<<<<<<<<<<<<< */
// #define DEBUG_VERBOSE // Debug Assertions Status : Debug Verbose Information
#undef DEBUG_VERBOSE // Debug Assertions Status : No Debug Verbose Information
/* >>>>>>>>>>>>>>>>>>>>[EDDY DRIVE CURRENT DETECTION]<<<<<<<<<<<<<<<<<<<< */
// #define EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Enable
#undef EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Disable
/******************************************************************************/
#define MCU_CODE 24U
#define FW_VERSION_MAJOR 1
#define FW_VERSION_MINOR 1
#define FW_VERSION_PATCH 3
/* Dynamic USART Configuration Structure */
typedef struct {
uint32_t rcu_usart;
uint32_t usart_periph;
IRQn_Type irq_type;
void (*irq_handler)(void); // 函数指针:指向中断处理函数
} usart_config_t;
extern usart_config_t g_usart_config;
extern uint8_t g_mcu_flash_size;
/* USART中断处理函数声明 */
void usart0_irq_handler(void);
void usart1_irq_handler(void);
/******************************************************************************/
#define RCU_GPIO_I2C RCU_GPIOF
#define RCU_I2C RCU_I2C0
#define I2C_SCL_PORT GPIOF
#define I2C_SCL_PIN GPIO_PIN_1
#define I2C_SDA_PORT GPIOF
#define I2C_SDA_PIN GPIO_PIN_0
#define I2C_GPIO_AF GPIO_AF_1
#define I2C_DEBUG_UART USART0
/******************************************************************************/
#define LED_RCU RCU_GPIOA
#define LED_PORT GPIOA
#define LED_PIN GPIO_PIN_7
/******************************************************************************/
#define RS485_RCU (g_usart_config.rcu_usart)
#define RS485_PHY (g_usart_config.usart_periph)
#define RS485_IRQ (g_usart_config.irq_type)
#define RS485_GPIO_RCU RCU_GPIOA
#define RS485_GPIO_PORT GPIOA
#define RS485_EN_PIN GPIO_PIN_1
#define RS485_TX_PIN GPIO_PIN_2
#define RS485_RX_PIN GPIO_PIN_3
#define RS485_BAUDRATE 115200U
/******************************************************************************/
void mcu_detect_and_config(void);
uint8_t get_flash_size(void);
#endif //BOARD_CONFIG_H
+108 -112
View File
@@ -1,112 +1,108 @@
/**
* @file command.h
* @brief 串口命令解析与处理模块接口声明。
* @details 提供基于环形缓冲区的串口协议解析、命令处理及状态管理功能,
* 支持格式为 D5 03 LEN [cmd] CRC 的命令帧解析与响应。
*/
#ifndef COMMAND_H
#define COMMAND_H
#include <stdint.h>
#include <stdbool.h>
/**
* @defgroup Command 命令处理模块
* @brief 串口命令解析与处理
* @{
*/
/** @brief 传感器周期上报使能标志 */
extern volatile bool g_eddy_current_sensor_report_enabled;
/**
* @section Command_Protocol 协议格式
* 接收命令帧格式:
* @code
* [0] HEADER = 0xD5 // 包头标识
* [1] BOARD_TYPE = 0x03 // 板卡类型标识
* [2] LEN = 数据区字节数 // 有效载荷长度
* [3..(3+LEN-1)] 数据 // 命令数据
* [last] CRC // 校验码(从索引1累加到len-2的低8位)
* @endcode
*
* 响应帧格式:
* @code
* [0] HEADER = 0xB5 // 响应包头
* [1] TYPE // 响应类型(0xF0=成功,0xF1..=错误类型)
* [2] LEN // 响应数据长度
* [3..(3+LEN-1)] 数据 // 响应数据
* [last] CRC // 校验码
* @endcode
*
* @section Command_Usage 使用说明
* 1) 初始化环形缓冲区:
* @code{.c}
* uart_ring_buffer_init();
* @endcode
*
* 2) 在主循环中调用命令处理:
* @code{.c}
* while(1) {
* command_process(); // 处理接收到的命令
* // 其他业务逻辑
* }
* @endcode
*
* 3) 查询传感器上报状态:
* @code{.c}
* if(get_sensor_report_enabled()) {
* // 执行传感器数据上报
* }
* @endcode
*/
/**
* @brief 获取电涡流传感器周期上报使能状态。
* @return bool 上报状态。
* @retval true 传感器周期上报已启用。
* @retval false 传感器周期上报已禁用。
* @ingroup Command
*/
bool get_eddy_sensor_report_enabled(void);
/**
* @brief 设置电涡流传感器周期上报使能状态。
* @param enabled 上报使能标志。
* @arg true 启用传感器周期上报。
* @arg false 禁用传感器周期上报。
* @note 推荐通过此函数修改状态,便于后续功能扩展。
* @ingroup Command
*/
void set_eddy_sensor_report_status(bool enabled);
/**
* @brief 处理串口环形缓冲区中的命令数据。
* @details 基于状态机的非阻塞协议解析器,处理完整的命令帧并自动响应。
* 每次调用处理缓冲区中所有可用数据,遇到错误时自动重置状态机。
* @note 使用静态变量维护解析状态,函数不可重入。
* @warning 依赖环形缓冲区正确实现,建议在主循环中周期调用。
* @ingroup Command
*/
void command_process(void);
/**
* @brief 解析并处理完整的命令帧。
* @param cmd 指向完整命令帧的缓冲区(从包头0xD5开始)。
* @param len 命令帧总长度(字节)。
* @note 内部函数,由 command_process() 调用,一般不直接使用。
* @ingroup Command
*/
void handle_command(const uint8_t *cmd, uint8_t len);
/** @} */ // end of Command group
void eddy_current_report(void);
void temperature_raw_value_report(void);
void eddy_current_compensated_report(void);
void calibration_data_report(void);
#endif // COMMAND_H
/**
* @file command.h
* @brief 串口命令解析与处理模块接口声明。
* @details 提供基于环形缓冲区的串口协议解析、命令处理及状态管理功能,
* 支持格式为 D5 03 LEN [cmd] CRC 的命令帧解析与响应。
*/
#ifndef COMMAND_H
#define COMMAND_H
#include <stdint.h>
#include <stdbool.h>
/**
* @defgroup Command 命令处理模块
* @brief 串口命令解析与处理
* @{
*/
/** @brief 传感器周期上报使能标志 */
extern volatile bool g_eddy_current_sensor_report_enabled;
/**
* @section Command_Protocol 协议格式
* 接收命令帧格式:
* @code
* [0] HEADER = 0xD5 // 包头标识
* [1] BOARD_TYPE = 0x03 // 板卡类型标识
* [2] LEN = 数据区字节数 // 有效载荷长度
* [3..(3+LEN-1)] 数据 // 命令数据
* [last] CRC // 校验码(从索引1累加到len-2的低8位)
* @endcode
*
* 响应帧格式:
* @code
* [0] HEADER = 0xB5 // 响应包头
* [1] TYPE // 响应类型(0xF0=成功,0xF1..=错误类型)
* [2] LEN // 响应数据长度
* [3..(3+LEN-1)] 数据 // 响应数据
* [last] CRC // 校验码
* @endcode
*
* @section Command_Usage 使用说明
* 1) 初始化环形缓冲区:
* @code{.c}
* uart_ring_buffer_init();
* @endcode
*
* 2) 在主循环中调用命令处理:
* @code{.c}
* while(1) {
* command_process(); // 处理接收到的命令
* // 其他业务逻辑
* }
* @endcode
*
* 3) 查询传感器上报状态:
* @code{.c}
* if(get_sensor_report_enabled()) {
* // 执行传感器数据上报
* }
* @endcode
*/
/**
* @brief 获取电涡流传感器周期上报使能状态。
* @return bool 上报状态。
* @retval true 传感器周期上报已启用。
* @retval false 传感器周期上报已禁用。
* @ingroup Command
*/
bool get_eddy_sensor_report_enabled(void);
/**
* @brief 设置电涡流传感器周期上报使能状态。
* @param enabled 上报使能标志。
* @arg true 启用传感器周期上报。
* @arg false 禁用传感器周期上报。
* @note 推荐通过此函数修改状态,便于后续功能扩展。
* @ingroup Command
*/
void set_eddy_sensor_report_status(bool enabled);
/**
* @brief 处理串口环形缓冲区中的命令数据。
* @details 基于状态机的非阻塞协议解析器,处理完整的命令帧并自动响应。
* 每次调用处理缓冲区中所有可用数据,遇到错误时自动重置状态机。
* @note 使用静态变量维护解析状态,函数不可重入。
* @warning 依赖环形缓冲区正确实现,建议在主循环中周期调用。
* @ingroup Command
*/
void command_process(void);
/**
* @brief 解析并处理完整的命令帧。
* @param cmd 指向完整命令帧的缓冲区(从包头0xD5开始)。
* @param len 命令帧总长度(字节)。
* @note 内部函数,由 command_process() 调用,一般不直接使用。
* @ingroup Command
*/
void handle_command(const uint8_t *cmd, uint8_t len);
/** @} */ // end of Command group
void eddy_current_report(void);
void temperature_raw_value_report(void);
#endif // COMMAND_H
+52 -52
View File
@@ -1,52 +1,52 @@
/*!
\file gd32e23x_it.h
\brief the header file of the ISR
\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,
are permitted provided that the following conditions are met:
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
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
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.
*/
#ifndef GD32E23X_IT_H
#define GD32E23X_IT_H
#include "gd32e23x.h"
/* function declarations */
/* this function handles NMI exception */
void NMI_Handler(void);
/* this function handles HardFault exception */
void HardFault_Handler(void);
/* this function handles SVC exception */
void SVC_Handler(void);
/* this function handles PendSV exception */
void PendSV_Handler(void);
/* this function handles SysTick exception */
void SysTick_Handler(void);
#endif /* GD32E23X_IT_H */
/*!
\file gd32e23x_it.h
\brief the header file of the ISR
\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,
are permitted provided that the following conditions are met:
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
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
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.
*/
#ifndef GD32E23X_IT_H
#define GD32E23X_IT_H
#include "gd32e23x.h"
/* function declarations */
/* this function handles NMI exception */
void NMI_Handler(void);
/* this function handles HardFault exception */
void HardFault_Handler(void);
/* this function handles SVC exception */
void SVC_Handler(void);
/* this function handles PendSV exception */
void PendSV_Handler(void);
/* this function handles SysTick exception */
void SysTick_Handler(void);
#endif /* GD32E23X_IT_H */
+58 -58
View File
@@ -1,58 +1,58 @@
/*!
\file gd32e23x_libopt.h
\brief library optional for gd32e23x
\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,
are permitted provided that the following conditions are met:
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
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
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.
*/
#ifndef GD32E23X_LIBOPT_H
#define GD32E23X_LIBOPT_H
#include "gd32e23x_adc.h"
#include "gd32e23x_crc.h"
#include "gd32e23x_dbg.h"
#include "gd32e23x_dma.h"
#include "gd32e23x_exti.h"
#include "gd32e23x_fmc.h"
#include "gd32e23x_gpio.h"
#include "gd32e23x_syscfg.h"
#include "gd32e23x_i2c.h"
#include "gd32e23x_fwdgt.h"
#include "gd32e23x_pmu.h"
#include "gd32e23x_rcu.h"
#include "gd32e23x_rtc.h"
#include "gd32e23x_spi.h"
#include "gd32e23x_timer.h"
#include "gd32e23x_usart.h"
#include "gd32e23x_wwdgt.h"
#include "gd32e23x_misc.h"
#include "gd32e23x_cmp.h"
#endif /* GD32E23X_LIBOPT_H */
/*!
\file gd32e23x_libopt.h
\brief library optional for gd32e23x
\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,
are permitted provided that the following conditions are met:
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
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
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.
*/
#ifndef GD32E23X_LIBOPT_H
#define GD32E23X_LIBOPT_H
#include "gd32e23x_adc.h"
#include "gd32e23x_crc.h"
#include "gd32e23x_dbg.h"
#include "gd32e23x_dma.h"
#include "gd32e23x_exti.h"
#include "gd32e23x_fmc.h"
#include "gd32e23x_gpio.h"
#include "gd32e23x_syscfg.h"
#include "gd32e23x_i2c.h"
#include "gd32e23x_fwdgt.h"
#include "gd32e23x_pmu.h"
#include "gd32e23x_rcu.h"
#include "gd32e23x_rtc.h"
#include "gd32e23x_spi.h"
#include "gd32e23x_timer.h"
#include "gd32e23x_usart.h"
#include "gd32e23x_wwdgt.h"
#include "gd32e23x_misc.h"
#include "gd32e23x_cmp.h"
#endif /* GD32E23X_LIBOPT_H */
+127 -189
View File
@@ -1,189 +1,127 @@
//
// Created by dell on 24-12-20.
//
#ifndef I2C_H
#define I2C_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "board_config.h"
/******************************************************************************/
#define I2C_SPEED 100000U /* 100kHz */
#define I2C_TIME_OUT 5000U /* 5000 loops timeout */
#define I2C_MAX_RETRY 3U /* Maximum retry attempts */
#define I2C_DELAY_10US 10U /* Delay in microseconds for bus reset */
#define I2C_RECOVERY_CLOCKS 9U /* Clock pulses for bus recovery */
#define I2C_MASTER_ADDRESS 0x00U /* Master address (not used) */
/* Legacy compatibility */
#define I2C_OK 1
#define I2C_FAIL 0
#define I2C_END 1
/******************************************************************************/
/* I2C result enumeration */
typedef enum {
I2C_RESULT_SUCCESS = 0, /* Operation successful */
I2C_RESULT_TIMEOUT, /* Timeout occurred */
I2C_RESULT_NACK, /* No acknowledge received */
I2C_RESULT_BUS_BUSY, /* Bus is busy */
I2C_RESULT_ERROR, /* General error */
I2C_RESULT_INVALID_PARAM, /* Invalid parameter */
I2C_RECOVERY_OK,
I2C_RECOVERY_SDA_STUCK_LOW,
I2C_RECOVERY_SCL_STUCK_LOW
} i2c_result_t;
/* I2C state machine enumeration */
typedef enum {
I2C_STATE_IDLE = 0, /* Idle state */
I2C_STATE_START, /* Generate start condition */
I2C_STATE_SEND_ADDRESS, /* Send slave address */
I2C_STATE_CLEAR_ADDRESS, /* Clear address flag */
I2C_STATE_TRANSMIT_REG, /* Transmit register address */
I2C_STATE_TRANSMIT_DATA, /* Transmit data */
I2C_STATE_RESTART, /* Generate restart condition */
I2C_STATE_RECEIVE_DATA, /* Receive data */
I2C_STATE_STOP, /* Generate stop condition */
I2C_STATE_ERROR, /* Error state */
I2C_STATE_END
} i2c_state_t;
/******************************************************************************/
/* Function declarations */
/*!
\brief configure the I2C interface
\param[in] none
\param[out] none
\retval i2c_result_t
*/
i2c_result_t i2c_config(void);
/*!
\brief reset I2C bus with proper recovery
\param[in] none
\param[out] none
\retval i2c_result_t
*/
i2c_result_t i2c_bus_reset(void);
/*!
\brief scan I2C bus for devices
\param[in] none
\param[out] none
\retval none
*/
void i2c_scan(void);
/*!
\brief write 16-bit data to I2C device
\param[in] slave_addr: 7-bit slave address
\param[in] reg_addr: register address
\param[in] data: pointer to 2-byte data array
\param[out] none
\retval i2c_result_t
*/
i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
/*!
\brief read 16-bit data from I2C device
\param[in] slave_addr: 7-bit slave address
\param[in] reg_addr: register address
\param[out] data: pointer to 2-byte data buffer
\retval i2c_result_t
*/
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
/* Generic read/write functions with configurable length */
/*!
\brief write data to I2C device with configurable length
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address
\param[in] data: pointer to data buffer
\param[in] length: number of bytes to write (1-255)
\param[out] none
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
/*!
\brief read data from I2C device with configurable length
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address
\param[out] data: pointer to data buffer
\param[in] length: number of bytes to read (1-255)
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
/* Convenience functions for common operations */
/*!
\brief write single byte to I2C device
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address
\param[in] data: data byte to write
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_write_8bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data);
/*!
\brief read single byte from I2C device
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address
\param[out] data: pointer to data byte
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_read_8bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
/*!
\brief write 32-bit data to I2C device
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address
\param[in] data: pointer to 4-byte data array
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_write_32bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[4]);
/*!
\brief read 32-bit data from I2C device
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address
\param[out] data: pointer to 4-byte data buffer
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_read_32bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
/*!
\brief read display panel parameters (multi-byte)
\param[in] slave_addr: slave device address (7-bit)
\param[in] reg_addr: register address
\param[out] data: pointer to data buffer
\param[in] length: number of bytes to read (1-13)
\retval i2c_result_t: operation result
*/
i2c_result_t i2c_read_display_params(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
#ifdef DEBUG_VERBOSE
/*!
\brief get status string for debugging
\param[in] status: i2c_result_t value
\param[out] none
\retval const char* status string
*/
const char* i2c_get_status_string(i2c_result_t status);
#endif
#endif //I2C_H
//
// Created by dell on 24-12-20.
//
#ifndef I2C_H
#define I2C_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "board_config.h"
/******************************************************************************/
#define I2C_SPEED 100000U /* 100kHz */
#define I2C_TIME_OUT 5000U /* 5000 loops timeout */
#define I2C_MAX_RETRY 3U /* Maximum retry attempts */
#define I2C_DELAY_10US 10U /* Delay in microseconds for bus reset */
#define I2C_RECOVERY_CLOCKS 9U /* Clock pulses for bus recovery */
#define I2C_MASTER_ADDRESS 0x00U /* Master address (not used) */
/* Legacy compatibility */
#define I2C_OK 1
#define I2C_FAIL 0
#define I2C_END 1
/******************************************************************************/
/* I2C result enumeration */
typedef enum {
I2C_RESULT_SUCCESS = 0, /* Operation successful */
I2C_RESULT_TIMEOUT, /* Timeout occurred */
I2C_RESULT_NACK, /* No acknowledge received */
I2C_RESULT_BUS_BUSY, /* Bus is busy */
I2C_RESULT_ERROR, /* General error */
I2C_RESULT_INVALID_PARAM, /* Invalid parameter */
I2C_RECOVERY_OK,
I2C_RECOVERY_SDA_STUCK_LOW,
I2C_RECOVERY_SCL_STUCK_LOW
} i2c_result_t;
/* I2C state machine enumeration */
typedef enum {
I2C_STATE_IDLE = 0, /* Idle state */
I2C_STATE_START, /* Generate start condition */
I2C_STATE_SEND_ADDRESS, /* Send slave address */
I2C_STATE_CLEAR_ADDRESS, /* Clear address flag */
I2C_STATE_TRANSMIT_REG, /* Transmit register address */
I2C_STATE_TRANSMIT_DATA, /* Transmit data */
I2C_STATE_RESTART, /* Generate restart condition */
I2C_STATE_RECEIVE_DATA, /* Receive data */
I2C_STATE_STOP, /* Generate stop condition */
I2C_STATE_ERROR, /* Error state */
I2C_STATE_END
} i2c_state_t;
/******************************************************************************/
/* Function declarations */
/*!
\brief configure the I2C interface
\param[in] none
\param[out] none
\retval i2c_result_t
*/
i2c_result_t i2c_config(void);
/*!
\brief reset I2C bus with proper recovery
\param[in] none
\param[out] none
\retval i2c_result_t
*/
i2c_result_t i2c_bus_reset(void);
/*!
\brief scan I2C bus for devices
\param[in] none
\param[out] none
\retval none
*/
void i2c_scan(void);
/*!
\brief write 16-bit data to I2C device
\param[in] slave_addr: 7-bit slave address
\param[in] reg_addr: register address
\param[in] data: pointer to 2-byte data array
\param[out] none
\retval i2c_result_t
*/
i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
/*!
\brief read 16-bit data from I2C device
\param[in] slave_addr: 7-bit slave address
\param[in] reg_addr: register address
\param[out] data: pointer to 2-byte data buffer
\retval i2c_result_t
*/
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
/*!
\brief read 16-bit data from I2C device
\param[in] slave_addr: 7-bit slave address
\param[in] reg_addr: register address
\param[out] data: pointer to 2-byte data buffer
\retval i2c_result_t
*/
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
/*!
\brief get status string for debugging
\param[in] status: i2c_result_t value
\param[out] none
\retval const char* status string
*/
const char* i2c_get_status_string(i2c_result_t status);
#endif //I2C_H
+213 -488
View File
@@ -1,488 +1,213 @@
//
// Created by dell on 24-12-3.
//
#ifndef LDC1612_H
#define LDC1612_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "board_config.h"
#include "i2c.h"
/***************************************************************************/
/* IIC Interface Selection */
#ifdef SOFTWARE_IIC
#define LDC1612_IIC_WRITE_16BITS(addr, reg, data) soft_i2c_write_16bits(addr, reg, data)
#define LDC1612_IIC_READ_16BITS(addr, reg, data) soft_i2c_read_16bits(addr, reg, data)
#define LDC1612_IIC_TYPE_STR "Software IIC"
#else
#define LDC1612_IIC_WRITE_16BITS(addr, reg, data) i2c_write_16bits(addr, reg, data)
#define LDC1612_IIC_READ_16BITS(addr, reg, data) i2c_read_16bits(addr, reg, data)
#define LDC1612_IIC_TYPE_STR "Hardware IIC"
#endif
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>[EXT CLK(MHz)]<<<<<<<<<<<<<<<<<<<< */
#define LDC1612_EXT_CLK_MHZ 40
/***************************************************************************/
#define LDC1612_ADDR (0x2B)
/******************************************************************************/
#define COIL_L_UH 40.9
#define COIL_C_PF 180
/************************Register Addr***************************************/
#define CONVERSION_RESULT_REG_START 0X00
#define SET_CONVERSION_TIME_REG_START 0X08
#define SET_CONVERSION_OFFSET_REG_START 0X0C
#define SET_SETTLECOUNT_REG_START 0X10
#define SET_FREQ_REG_START 0X14
#define SENSOR_STATUS_REG 0X18
#define ERROR_CONFIG_REG 0X19
#define SENSOR_CONFIG_REG 0X1A
#define MUX_CONFIG_REG 0X1B
#define SENSOR_RESET_REG 0X1C
#define SET_DRIVER_CURRENT_REG 0X1E
#define READ_MANUFACTURER_ID 0X7E
#define READ_DEVICE_ID 0X7F
/**********************Sensor Channel****************************************/
#define CHANNEL_0 0
#define CHANNEL_1 1
/**************************DATA (0x00-0x03)*******************************************/
/*
* 作用: 存储28位的传感器转换结果。结果分为高字节(MSB)和低字节(LSB)两个寄存器。
*
* 结构说明:
* - DATA_CHx_MSB: 包含错误标志和数据的高12位 [27:16]。
* - DATA_CHx_LSB: 包含数据的低16位 [15:0]。
*
* MSB寄存器位域:
* [15] ERR_UR: 转换下溢错误标志 (1 = 发生错误)
* [14] ERR_OR: 转换上溢错误标志 (1 = 发生错误)
* [13] ERR_WD: 看门狗超时错误标志 (1 = 发生错误)
* [12] ERR_AE: 振幅错误标志 (高或低) (1 = 发生错误)
* [11:0] DATA[27:16]: 数据的高12位
*
* 注意:
* - 仅当ERROR_CONFIG寄存器中对应的ERR2OUT位置1时,这些错误标志才会在MSB寄存器中被设置。
* - 读取数据时,应先读取LSB,再读取MSB,以确保数据的一致性。
*/
/* --- 数据寄存器错误标志位掩码 --- */
#define LDC1612_DATA_ERR_UR (1 << 15)
#define LDC1612_DATA_ERR_OR (1 << 14)
#define LDC1612_DATA_ERR_WD (1 << 13)
#define LDC1612_DATA_ERR_AE (1 << 12)
#define LDC1612_DATA_ERR_MASK (0xF000)
#define LDC1612_DATA_MSB_MASK (0x0FFF)
/**************************RCOUNT (0x08, 0x09)****************************************/
/*
* 作用: 设置参考计数器值,决定了传感器的转换时间,从而影响测量分辨率。
*
* 位域说明:
* [15:0] RCOUNT: 参考计数值。
*
* 计算公式:
* t_CONVERSION = (RCOUNT * 16) / f_REF
*
* 注意:
* - RCOUNT值必须 ≥ 0x0004。
* - 该寄存器在复位后值为 0x0080。
*
* 配置建议:
* - 需要高采样率: 使用较小的RCOUNT值。
* - 需要高分辨率: 使用较大的RCOUNT值。
*/
/* --- 预设配置示例 --- */
// 高速采样配置 (分辨率较低)
#define LDC1612_RCOUNT_HIGH_SPEED (0x04D6) // 1238, 约 1kSPS @ 40MHz/2
// 平衡配置 (常用)
#define LDC1612_RCOUNT_BALANCED (0x1000) // 4096, 约 380SPS @ 40MHz/2
// 高分辨率配置 (采样率较低)
#define LDC1612_RCOUNT_HIGH_RESOLUTION (0xFFFF) // 65535, 约 24SPS @ 40MHz/2
// 默认配置
#define LDC1612_RCOUNT_TIME_CH0 LDC1612_RCOUNT_BALANCED // 0x1000=4096个时钟周期
/**************************OFFSET (0x0C, 0x0D)****************************************/
/*
* 作用: 设置一个16位的数字偏移量,该值会从原始转换结果中减去。
*
* 位域说明:
* [15:0] OFFSET: 数据偏移值。
*
* 计算公式:
* 最终数据 = 原始转换数据 - OFFSET
*
* 注意:
* - 如果减法结果为负,将触发下溢错误 (ERR_UR)。
* - 该寄存器在复位后值为 0x0000。
*
* 应用场景:
* - 消除传感器或环境的固有基线偏移。
* - 实现“去皮”(Tare)功能,将当前读数设为新的零点。
*/
// 默认配置: 不设置偏移
#define SET_CONVERSION_OFFSET_CH0 0x0000
/**************************SETTLECOUNT (0x10, 0x11)***********************************/
/*
* 作用: 设置传感器振荡器在开始转换前所需的建立时间。
*
* 位域说明:
* [15:0] SETTLECOUNT: 建立时间计数值。
*
* 计算公式:
* t_SETTLE 的计算方式取决于SETTLECOUNT的值:
* - 当 SETTLECOUNT = 0x0000 或 0x0001 时, t_SETTLE = 32 / f_REF
* - 当 SETTLECOUNT ≥ 0x0002 时, t_SETTLE = (SETTLECOUNT * 16) / f_REF
*
* 配置建议:
* - 传感器的Q值越高,所需的建立时间越短 (SETTLECOUNT值可以越小)。
* - 值过小可能导致传感器未充分稳定,数据不准确。
* - 值过大则会不必要地增加总转换时间,降低采样率。
* - 对于大多数应用,0x0100 (256) 是一个很好的起始值。
*/
/* --- 预设配置示例 --- */
// 适用于高Q值传感器 (建立时间短)
#define LDC1612_SETTLECOUNT_HIGH_Q (0x000A) // 约 4µs @ 40MHz/2
// 适用于中等Q值传感器 (通用)
#define LDC1612_SETTLECOUNT_MEDIUM_Q (0x0100) // 约 102µs @ 40MHz/2
// 适用于低Q值传感器 (建立时间长)
#define LDC1612_SETTLECOUNT_LOW_Q (0x0400) // 约 410µs @ 40MHz/2
// 默认配置
#define LDC1612_SETTLECOUNT_CH0 LDC1612_SETTLECOUNT_MEDIUM_Q
/**************************CLOCK_DIVIDER (0x14, 0x15)***********************************/
/*
* 作用: 配置传感器输入频率(f_sensor)和参考时钟(f_ref)的分频器。
*
* 位域说明:
* [15:12] FIN_DIVIDER: 传感器输入分频器。
* [11:10] RESERVED: 必须为00。
* [9:0] FREF_DIVIDER: 参考时钟分频器。
*
* 配置逻辑:
* 1. FIN_DIVIDER: 根据传感器的谐振频率 f_sensor 选择。
* - 目标是使 f_sensor / FIN_DIVIDER <= 8.75MHz。
* - 例如: 如果 f_sensor = 15MHz, 则 FIN_DIVIDER 必须 >= 2。
*
* 2. FREF_DIVIDER: 根据外部时钟 f_clk 和工作模式选择。
* - 目标是使 f_ref = f_clk / FREF_DIVIDER。
* - 单通道模式且 f_clk <= 35MHz: FREF_DIVIDER = 1。
* - 双通道模式或 f_clk > 35MHz: FREF_DIVIDER = 2。
*
* 最终寄存器值 = (FIN_DIVIDER << 12) | FREF_DIVIDER;
*/
/* --- 位域选项宏 --- */
// [15:12] Sensor Input Divider (FIN_DIVIDER)
#define LDC1612_FIN_DIV_1 (0x1 << 12) // for f_sensor <= 8.75MHz
#define LDC1612_FIN_DIV_2 (0x2 << 12) // for 8.75MHz < f_sensor <= 17.5MHz
#define LDC1612_FIN_DIV_4 (0x3 << 12) // for 17.5MHz < f_sensor <= 35MHz
// [9:0] Reference Clock Divider (FREF_DIVIDER)
#define LDC1612_FREF_DIV_1 (0x001)
#define LDC1612_FREF_DIV_2 (0x002)
/* --- 组合宏 --- */
#define LDC1612_CLOCK_DIVIDER_GEN(fin_div, fref_div) ((fin_div) | (fref_div))
/* --- 预设配置示例 (基于40MHz外部时钟) --- */
// 适用于 f_sensor <= 8.75MHz
#define LDC1612_CLOCK_DIVIDER_DEFAULT LDC1612_CLOCK_DIVIDER_GEN(LDC1612_FIN_DIV_1, LDC1612_FREF_DIV_2) // 0x1002
/**************************STATUS (0x18) MACROS****************************************
*
* 作用: 定义STATUS寄存器的位掩码,用于解析设备状态。
*
*/
#define LDC1612_STATUS_DRDY (1 << 6) // 数据就绪
#define LDC1612_STATUS_UNREAD_CH0 (1 << 3) // 通道0有未读数据
#define LDC1612_STATUS_UNREAD_CH1 (1 << 2) // 通道1有未读数据
#define LDC1612_STATUS_ERR_ZC (1 << 8) // 零计数错误
#define LDC1612_STATUS_ERR_ALE (1 << 9) // 振幅过低
#define LDC1612_STATUS_ERR_AHE (1 << 10) // 振幅过高
#define LDC1612_STATUS_ERR_WD (1 << 11) // 看门狗超时
#define LDC1612_STATUS_ERR_OR (1 << 12) // 转换上溢
#define LDC1612_STATUS_ERR_UR (1 << 13) // 转换下溢
#define LDC1612_STATUS_ERR_CHAN_MASK (3 << 14) // 错误通道掩码
/**************************ERROR_CONFIG (0x19)****************************************/
/*
* 作用: 配置状态或错误输出或者触发INTB引脚中断。
*
* 位域说明:
* [15] UR_ERR2OUT: 1 = 转换下溢错误输出到DATA_CHx寄存器
* [14] OR_ERR2OUT: 1 = 转换上溢错误输出到DATA_CHx寄存器
* [13] WD_ERR2OUT: 1 = 看门狗超时错误输出到DATA_CHx寄存器
* [12] AH_ERR2OUT: 1 = 振幅过高错误输出到DATA_CHx寄存器
* [11] AL_ERR2OUT: 1 = 振幅过低错误输出到DATA_CHx寄存器
* [10:8] RESERVED
* [7] UR_ERR2INT: 1 = 转换下溢错误触发INTB
* [6] OR_ERR2INT: 1 = 转换上溢错误触发INTB
* [5] WD_ERR2INT: 1 = 看门狗超时错误触发INTB
* [4] AH_ERR2INT: 1 = 振幅过高错误触发INTB
* [3] AL_ERR2INT: 1 = 振幅过低错误触发INTB
* [2] ZC_ERR2INT: 1 = 零计数错误触发INTB
* [1] RESERVED
* [0] DRDY_2INT: 1 = 数据就绪标志触发INTB
*/
/* --- 位域选项宏 --- */
// --- 中断触发 (ERR2INT) ---
#define LDC1612_ERR_CFG_DRDY_INT_EN (1 << 0) // 数据就绪中断使能
#define LDC1612_ERR_CFG_ZC_INT_EN (1 << 2) // 零计数错误中断使能
#define LDC1612_ERR_CFG_AL_INT_EN (1 << 3) // 振幅过低错误中断使能
#define LDC1612_ERR_CFG_AH_INT_EN (1 << 4) // 振幅过高错误中断使能
#define LDC1612_ERR_CFG_WD_INT_EN (1 << 5) // 看门狗超时中断使能
#define LDC1612_ERR_CFG_OR_INT_EN (1 << 6) // 转换上溢中断使能
#define LDC1612_ERR_CFG_UR_INT_EN (1 << 7) // 转换下溢中断使能
// --- 错误报告至数据寄存器 (ERR2OUT) ---
#define LDC1612_ERR_CFG_AL_OUT_EN (1 << 11) // 振幅过低错误报告使能
#define LDC1612_ERR_CFG_AH_OUT_EN (1 << 12) // 振幅过高错误报告使能
#define LDC1612_ERR_CFG_WD_OUT_EN (1 << 13) // 看门狗超时错误报告使能
#define LDC1612_ERR_CFG_OR_OUT_EN (1 << 14) // 转换上溢错误报告使能
#define LDC1612_ERR_CFG_UR_OUT_EN (1 << 15) // 转换下溢错误报告使能
// 常用配置: 仅使能 "数据就绪" 中断
#define LDC1612_ERROR_CONFIG_DRDY_ONLY (LDC1612_ERR_CFG_DRDY_INT_EN) // 结果: 0x0001
// 常用配置: 使能所有错误报告
#define LDC1612_ERROR_CONFIG_OUT_ONLY (LDC1612_ERR_CFG_AL_OUT_EN | \
LDC1612_ERR_CFG_AH_OUT_EN | \
LDC1612_ERR_CFG_WD_OUT_EN | \
LDC1612_ERR_CFG_OR_OUT_EN | \
LDC1612_ERR_CFG_UR_OUT_EN) // 结果: 0xF800
// 调试配置: 使能所有错误中断和错误报告
#define LDC1612_ERROR_CONFIG_DEBUG_ALL (LDC1612_ERR_CFG_DRDY_INT_EN | \
LDC1612_ERR_CFG_ZC_INT_EN | \
LDC1612_ERR_CFG_AL_INT_EN | \
LDC1612_ERR_CFG_AH_INT_EN | \
LDC1612_ERR_CFG_WD_INT_EN | \
LDC1612_ERR_CFG_OR_INT_EN | \
LDC1612_ERR_CFG_UR_INT_EN | \
LDC1612_ERR_CFG_AL_OUT_EN | \
LDC1612_ERR_CFG_AH_OUT_EN | \
LDC1612_ERR_CFG_WD_OUT_EN | \
LDC1612_ERR_CFG_OR_OUT_EN | \
LDC1612_ERR_CFG_UR_OUT_EN) // 结果: 0xF8FD
// 默认配置: 所有功能都禁用
#define LDC1612_ERROR_CONFIG_DEFAULT (0x0000)
/**************************SENSOR_CONFIG (0x1A) MACROS***************************************/
/*
* CONFIG寄存器位域宏定义,用于灵活组合生成配置值。
* 使用方法: LDC1612_CONFIG_GEN(ACTIVE_CHAN, SLEEP_MODE, RP_OVERRIDE, AUTO_AMP, CLK_SRC, INTB, CURRENT_DRV)
*
* 位域说明 (根据 LDC1612_REG_LIST.md):
* [15:14] ACTIVE_CHAN: 激活通道选择 (仅在 AUTOSCAN_EN=0 时有效)
* [13] SLEEP_MODE_EN: 1 = 睡眠模式使能
* [12] RP_OVERRIDE_EN: 1 = 禁用自动校准 (使用手动的IDRIVE设置)
* [11] SENSOR_ACTIVATE_SEL: 传感器激活电流选择 (0:低电流, 1:高电流)
* [10] AUTO_AMP_DIS: 1 = 禁用自动幅度校正
* [9] REF_CLK_SRC: 1 = 使用外部CLKIN时钟
* [8] RESERVED: 必须为0
* [7] INTB_DIS: 1 = 禁用INTB中断引脚
* [6] HIGH_CURRENT_DRV: 1 = 通道0高电流驱动模式
* [5:0] RESERVED: 必须写入 0x01
*/
/* --- 位域选项宏 --- */
// [15:14] Active Channel Selection
#define LDC1612_CONFIG_ACTIVE_CHAN_CH0 (0x00 << 14)
#define LDC1612_CONFIG_ACTIVE_CHAN_CH1 (0x01 << 14)
// [13] Sleep Mode Enable
#define LDC1612_CONFIG_SLEEP_MODE_DISABLE (0x00 << 13)
#define LDC1612_CONFIG_SLEEP_MODE_ENABLE (0x01 << 13)
// [12] RP Override Enable (Auto-Calibration Disable)
#define LDC1612_CONFIG_RP_OVERRIDE_DISABLE (0x00 << 12) // 启用自动校准
#define LDC1612_CONFIG_RP_OVERRIDE_ENABLE (0x01 << 12) // 禁用自动校准
// [11] Sensor Activation Current Selection
#define LDC1612_CONFIG_SENSOR_ACT_LOW_I (0x00 << 11) // 低电流激活
#define LDC1612_CONFIG_SENSOR_ACT_HIGH_I (0x01 << 11) // 高电流激活
// [10] Auto Amplitude Correction Disable
#define LDC1612_CONFIG_AUTO_AMP_ENABLE (0x00 << 10) // 启用自动幅度校正
#define LDC1612_CONFIG_AUTO_AMP_DISABLE (0x01 << 10) // 禁用自动幅度校正
// [9] Reference Clock Source
#define LDC1612_CONFIG_CLK_SRC_INTERNAL (0x00 << 9)
#define LDC1612_CONFIG_CLK_SRC_EXTERNAL (0x01 << 9)
// [7] INTB Pin Disable
#define LDC1612_CONFIG_INTB_ENABLE (0x00 << 7)
#define LDC1612_CONFIG_INTB_DISABLE (0x01 << 7)
// [6] High Current Drive (Channel 0)
#define LDC1612_CONFIG_HIGH_CURRENT_DISABLE (0x00 << 6)
#define LDC1612_CONFIG_HIGH_CURRENT_ENABLE (0x01 << 6)
/* --- 组合宏 --- */
// 将所有位域组合成一个16位值。注意,保留位0x01被固定添加。
#define LDC1612_CONFIG_GEN(active_chan, sleep, rp_override, sensor_act, auto_amp, clk_src, intb, high_current) \
( (active_chan) | (sleep) | (rp_override) | (sensor_act) | (auto_amp) | (clk_src) | (intb) | (high_current) | 0x0001 )
/* --- 预设配置示例 --- */
// CH0连续转换, 外部时钟, 高驱动电流, 禁用自动幅度修正(适用于电流检测)
#define LDC1612_SENSOR_CONFIG_CH0 LDC1612_CONFIG_GEN( \
LDC1612_CONFIG_ACTIVE_CHAN_CH0, \
LDC1612_CONFIG_SLEEP_MODE_DISABLE, \
LDC1612_CONFIG_RP_OVERRIDE_ENABLE, /* Rp覆盖开启 */ \
LDC1612_CONFIG_SENSOR_ACT_LOW_I, /* 低功耗启动 */ \
LDC1612_CONFIG_AUTO_AMP_DISABLE, /* 禁用自动幅度校正 */ \
LDC1612_CONFIG_CLK_SRC_EXTERNAL, /* 外部时钟 */ \
LDC1612_CONFIG_INTB_ENABLE, /* 启用INTB引脚 */ \
LDC1612_CONFIG_HIGH_CURRENT_ENABLE /* 大电流模式 */ ) // 结果: 0x1641
// TODO 对比1601的不同(大电流与标准电流)
// 睡眠模式, 外部时钟
#define LDC1612_SLEEP_MODE LDC1612_CONFIG_GEN( \
LDC1612_CONFIG_ACTIVE_CHAN_CH0, \
LDC1612_CONFIG_SLEEP_MODE_ENABLE, \
LDC1612_CONFIG_RP_OVERRIDE_DISABLE, \
LDC1612_CONFIG_SENSOR_ACT_HIGH_I, \
LDC1612_CONFIG_AUTO_AMP_ENABLE, \
LDC1612_CONFIG_CLK_SRC_INTERNAL, \
LDC1612_CONFIG_INTB_ENABLE, \
LDC1612_CONFIG_HIGH_CURRENT_DISABLE ) // 结果: 0x2801
/*************************MUX_CONFIG (0x1B) MACROS***************************************/
/*
* MUX_CONFIG寄存器位域宏定义,用于灵活组合生成配置值。
*
* 位域说明:
* [15] AUTOSCAN_EN: 1 = 自动顺序扫描模式使能
* [14:13] RR_SEQUENCE: 扫描序列 (00: CH0, CH1)
* [12:3] RESERVED: 必须写入 0x041
* [2:0] DEGLITCH: 输入消抖滤波器带宽
*/
/* --- 位域选项宏 --- */
// [15] Auto Scan Mode
#define LDC1612_MUX_AUTOSCAN_DISABLE (0x00 << 15) // 单通道连续模式
#define LDC1612_MUX_AUTOSCAN_ENABLE (0x01 << 15) // 自动扫描模式
// [14:13] Round Robin Sequence
#define LDC1612_MUX_RR_SEQ_CH0_CH1 (0x00 << 13) // 扫描 CH0, CH1
// [2:0] Deglitch Filter Bandwidth
#define LDC1612_MUX_DEGLITCH_1MHZ (0x01)
#define LDC1612_MUX_DEGLITCH_3_3MHZ (0x04)
#define LDC1612_MUX_DEGLITCH_10MHZ (0x05)
#define LDC1612_MUX_DEGLITCH_33MHZ (0x07)
/* --- 组合宏 --- */
// 将所有位域组合成一个16位值。注意,保留位0x0208 (0x041 << 3)被固定添加。
#define LDC1612_MUX_CONFIG_GEN(autoscan, sequence, deglitch) \
( (autoscan) | (sequence) | (deglitch) | 0x0208 )
/* --- 预设配置示例 --- */
// 单通道模式, 3.3MHz 滤波
#define LDC1612_MUX_CONFIG LDC1612_MUX_CONFIG_GEN( \
LDC1612_MUX_AUTOSCAN_DISABLE, \
LDC1612_MUX_RR_SEQ_CH0_CH1, /* 此模式下无效,但保持定义 */ \
LDC1612_MUX_DEGLITCH_3_3MHZ ) // 0x020C
/***********************RESET DEVICE (0x1C)***********************************/
/*
* 向RESET_DEV寄存器写入 LDC1612_RESET_CMD 会触发软件复位。
* 复位后,所有寄存器将恢复为默认值,设备进入睡眠模式。
* 需要大约10ms的稳定时间后才能重新配置。
*/
#define LDC1612_RESET_DEV 0x8000
/**************************DRIVE_CURRENT (0x1E, 0x1F)****************************************/
/*
* 作用: 设置传感器的驱动电流,以确保振荡幅度(Vosc)在1.2V到1.8V之间。
*
* 位域说明:
* [15:11] IDRIVE: 当前驱动电流设置值 (0-31)。
* [10:6] INIT_IDRIVE: 初始驱动电流设置值 (0-31)。
* [5:0] RESERVED: 必须为0。
*
* 配置建议:
* 1. 初始阶段可启用自动校准 (CONFIG.RP_OVERRIDE_EN = 0),让芯片自动寻找合适的IDRIVE值。
* 2. 读取DRIVE_CURRENT寄存器,获得自动校准后的IDRIVE值。
* 3. 在最终代码中,禁用自动校准 (CONFIG.RP_OVERRIDE_EN = 1),并手动写入这个调试好的IDRIVE值。
*
* CH_INIT_IDRIVE will update when every conversion systick ==>AutoAmpDis is 0
* CH_INIT_IDRIVE will store init drive current calculated ==> AutoAmpDis is 1
*/
/* --- 驱动电流值生成宏 --- */
// 参数 idrive: 0-31之间的整数
#define LDC1612_DRIVE_CURRENT_GEN(idrive) ( (uint16_t)(idrive) << 11 )
#define LDC1612_DRIVE_CURRENT LDC1612_DRIVE_CURRENT_GEN(18) // 0x9000
/**************************IDs (Read Only 0x7E 0x7F)***********************************/
#define LDC1612_MANUFACTURER_ID 0x5449
#define LDC1612_DEVICE_ID 0x3055
/******************************************************************************/
typedef enum {
LDC1612_STATUS_SUCCESS = 0,
LDC1612_STATUS_ERROR,
LDC1612_STATUS_TIMEOUT,
LDC1612_STATUS_INVALID_PARAM,
LDC1612_STATUS_NO_COIL,
LDC1612_STATUS_UNDER_RANGE,
LDC1612_STATUS_OVER_RANGE
} ldc1612_status_t;
/******************************************************************************/
ldc1612_status_t ldc1612_init(void);
ldc1612_status_t ldc1612_reset_sensor(void);
ldc1612_status_t ldc1612_config_single_channel(uint8_t channel);
uint16_t ldc1612_get_manufacturer_id(void);
uint16_t ldc1612_get_deveice_id(void);
uint32_t ldc1612_get_raw_channel_result(uint8_t channel);
void ldc1612_drvie_current_detect(uint8_t channel);
uint16_t ldc1612_get_sensor_status(void);
bool ldc1612_is_data_ready(uint8_t channel);
uint16_t ldc1612_check_status_and_log_errors(void);
#endif //LDC1612_H
//
// Created by dell on 24-12-3.
//
#ifndef LDC1612_H
#define LDC1612_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "board_config.h"
#include "i2c.h"
/***************************************************************************/
/* IIC Interface Selection */
#ifdef SOFTWARE_IIC
#define LDC1612_IIC_WRITE_16BITS(addr, reg, data) soft_i2c_write_16bits(addr, reg, data)
#define LDC1612_IIC_READ_16BITS(addr, reg, data) soft_i2c_read_16bits(addr, reg, data)
#define LDC1612_IIC_TYPE_STR "Software IIC"
#else
#define LDC1612_IIC_WRITE_16BITS(addr, reg, data) i2c_write_16bits(addr, reg, data)
#define LDC1612_IIC_READ_16BITS(addr, reg, data) i2c_read_16bits(addr, reg, data)
#define LDC1612_IIC_TYPE_STR "Hardware IIC"
#endif
/***************************************************************************/
#define LDC1612_ADDR (0x2B)
/************************Register Addr***************************************/
#define CONVERTION_RESULT_REG_START 0X00
#define SET_CONVERSION_TIME_REG_START 0X08
#define SET_CONVERSION_OFFSET_REG_START 0X0C
#define SET_SETTLECOUNT_REG_START 0X10
#define SET_FREQ_REG_START 0X14
#define SENSOR_STATUS_REG 0X18
#define ERROR_CONFIG_REG 0X19
#define SENSOR_CONFIG_REG 0X1A
#define MUX_CONFIG_REG 0X1B
#define SENSOR_RESET_REG 0X1C
#define SET_DRIVER_CURRENT_REG 0X1E
#define READ_MANUFACTURER_ID 0X7E
#define READ_DEVICE_ID 0X7F
/**********************Sensor Channel****************************************/
#define CHANNEL_0 0
#define CHANNEL_1 1
/*************************MUX_CONFIG********************************************
* 0x0209 AutoScanEN: 0 / RR_SEQ: 00 / RESERVED: 0 0010 0000 1 / Deglitch: 001( 1MHz)
* 0x020C AutoScanEN: 0 / RR_SEQ: 00 / RESERVED: 0 0010 0000 1 / Deglitch: 100(3.3MHz)
* 0x020D AutoScanEN: 0 / RR_SEQ: 00 / RESERVED: 0 0010 0000 1 / Deglitch: 100( 10MHz)
* 0x020F AutoScanEN: 0 / RR_SEQ: 00 / RESERVED: 0 0010 0000 1 / Deglitch: 100( 33MHz)
*/
#define LDC1612_MUX_CONFIG 0x020C
/***********************SENSOR_CONFIG********************************************
* 0x1601 Active CH0: 00 / SLEEP: 0 / OVERDRIVE: 1 / LowPowerMode: 0 / AutoAmpDis 1 / CLK(ext): 1 / RESERVED: 0 / INTB_Dis : 0 / HighCurrent: 0 / RESERVED: 00 0001
* 0x1201 Active CH0: 00 / SLEEP: 0 / OVERDRIVE: 1 / LowPowerMode: 0 / AutoAmpDis 0 / CLK(ext): 1 / RESERVED: 0 / INTB_Dis : 0 / HighCurrent: 0 / RESERVED: 00 0001
* 0x1641 Active CH0: 00 / SLEEP: 0 / OVERDRIVE: 1 / LowPowerMode: 0 / AutoAmpDis 1 / CLK(ext): 1 / RESERVED: 0 / INTB_Dis : 0 / HighCurrent: 1 / RESERVED: 00 0001
* 0x1241 Active CH0: 00 / SLEEP: 0 / OVERDRIVE: 1 / LowPowerMode: 0 / AutoAmpDis 0 / CLK(ext): 1 / RESERVED: 0 / INTB_Dis : 0 / HighCurrent: 1 / RESERVED: 00 0001
*/
#ifdef EDDY_DRIVE_CURRENT_DETECTION
#define LDC1612_SENSOR_CONFIG_CH0 0x1241
#else
#define LDC1612_SENSOR_CONFIG_CH0 0x1641
#endif
#define LDC1612_SLEEP_MODE 0x2801
/****************************CONVERSION_TIME************************************
* Freq_ref = 40MHz / CHx_FREF_DIVIDER
* ******RCOUNT_CHx*******
* Reference Count Conversion Interval Time
* 0x0005 ~ 0xFFFF
* default: 0x0080
* RCOUNT_CHx * 16 / Freq_ref = Conversion Interval Time
*
* ******SETTLECOUNT_CHx*******
* Conversion Settling Time
* 0x0000 ~ 0xFFFF
* default: 0x0000
* SETTLECOUNT_CHx * 16 / Freq_ref = Conversion Settling Time
* 0x1000 4096*16个时钟周期
* 0x0100 256*16个时钟周期
* 0x0000/0x0001 32*16个时钟周期
*
* ******RCOUNT_CHx*******
*/
#define LDC1612_RCOUNT_TIME_CH0 0x1000 // 0x1000=4096个时钟周期
#define LDC1612_SETTLECOUNT_CH0 0x0100
/**************************DRIVE_CURRENT****************************************
* 0xA000 CH_IDRIVE: 1010 0 / CH_INIT_IDRIVE: 000 00 / RESERVED: 00 0000
* 0x9000 CH_IDRIVE: 1001 0 / CH_INIT_IDRIVE: 000 00 / RESERVED: 00 0000
* CH_INIT_IDRIVE will update when every conversion systick ==>AutoAmpDis is 0
* CH_INIT_IDRIVE will store init drive current calculated ==> AutoAmpDis is 1
*/
#define LDC1612_DRIVE_CURRENT 0x9000
/**************************SENSOR_CONFIG***************************************/
/**************************ERROR_CONFIG****************************************
* [15] Under-Range ERR to OUT (DATA_CHx.CHx_ERR_UR)
* [14] Over-Range ERR to OUT (DATA_CHx.CHx_ERR_OR)
* [13] Watchdog-Timeout ERR to OUT (DATA_CHx.CHx_ERR_WD)
* [12] Amplitude-High-Error ERR to OUT (DATA_CHx.CHx_ERR_AE)
* [11] Amplitude-Low-Error ERR to OUT (DATA_CHx.CHx_ERR_AE)
* [10] RESERVED
* [ 9] RESERVED
* [ 8] RESERVED
* [ 7] Under-Range ERR to INTB (STATUS.ERR_UR)
* [ 6] Over-Range ERR to INTB (STATUS.ERR_OR)
* [ 5] Watchdog-Timeout ERR to INTB (STATUS.ERR_WD)
* [ 4] Amplitude-High-Error ERR to INTB (STATUS.ERR_AHE)
* [ 3] Amplitude-Low-Error ERR to INTB (STATUS.ERR_ALE)
* [ 2] Zero_Count_Error ERR to INTB (STATUS.ERR_ZC)
* [ 1] RESERVED
* [ 0] Data_Ready_Flag to INTB (STATUS.DRDY)
*
* 0x0000 No ERR to OUT or INTB
*/
#define LDC1612_ERROR_CONFIG 0x0000
/**************************STATUS****************************************
* [15]
* [14] Error Channel 0b00: CH0 / 0b01: CH1 / 0b10: CH2 / 0b11: CH3
* [13] Conversion Under-Range Error 0b0: No / 0b1: Yes
* [12] Conversion Over-Range Error 0b0: No / 0b1: Yes
* [11] Watchdog Timeout Error 0b0: No / 0b1: Yes
* [10] Amplitude High Error 0b0: No / 0b1: Yes
* [ 9] Amplitude Low Error 0b0: No / 0b1: Yes
* [ 8] Zero Count Error 0b0: No / 0b1: Yes
* [ 7] RESERVED
* [ 6] Ddata Ready Flag 0b0: No new results / 0b1: New results available
* [ 5] RESERVED
* [ 4] RESERVED
* [ 3] CH0 Unread Conversion Result 0b0: No / 0b1: Yes(DATA_CH0)
* [ 2] CH1 Unread Conversion Result 0b0: No / 0b1: Yes(DATA_CH1)
* [ 1] CH2 Unread Conversion Result 0b0: No / 0b1: Yes(DATA_CH2)
* [ 0] CH3 Unread Conversion Result 0b0: No / 0b1: Yes(DATA_CH3)
*
* 0x0000 No ERR to OUT or INTB
*/
/*****************CONVERSION_OFFSET_CONFIG****************************************/
#define SET_CONVERSION_OFFSET_CH0 0x0000
/***********************RESET DEVICE********************************************
0x8000 RESET_DEV: 1 / RESERVED: 000 0000 0000 0000
*/
#define LDC1612_RESET_DEV 0x8000 //[15:0] 0b1000 0000 0000 0000
/***********************IDs****************************************************/
#define LDC1612_MANUFACTURER_ID 0x5449
#define LDC1612_DEVICE_ID 0x3055
/******************************************************************************/
#define COIL_RP_KOM 7.2
#define COIL_L_UH 11.22
#define COIL_C_PF 150
#define COIL_Q_FACTOR 31.09
#define COIL_FREQ_HZ 5323770
/******************************************************************************/
typedef enum {
LDC1612_STATUS_SUCCESS = 0,
LDC1612_STATUS_ERROR,
LDC1612_STATUS_TIMEOUT,
LDC1612_STATUS_INVALID_PARAM,
LDC1612_STATUS_NO_COIL,
LDC1612_STATUS_UNDER_RANGE,
LDC1612_STATUS_OVER_RANGE
} ldc1612_status_t;
/******************************************************************************/
ldc1612_status_t ldc1612_init(void);
ldc1612_status_t ldc1612_reset_sensor(void);
ldc1612_status_t ldc1612_config_single_channel(uint8_t channel);
uint16_t ldc1612_get_manufacturer_id(void);
uint16_t ldc1612_get_deveice_id(void);
uint32_t ldc1612_get_raw_channel_result(uint8_t channel);
void ldc1612_drvie_current_detect(uint8_t channel);
uint16_t ldc1612_get_sensor_status(void);
bool ldc1612_is_data_ready(uint8_t channel);
#endif //LDC1612_H
+13 -13
View File
@@ -1,13 +1,13 @@
#ifndef LED_H
#define LED_H
#include "gd32e23x.h"
#include "board_config.h"
void led_init(void);
void led_on(void);
void led_off(void);
void led_toggle(void);
void led_heart_beat(void);
#endif // LED_H
#ifndef LED_H
#define LED_H
#include "gd32e23x.h"
#include "board_config.h"
void led_init(void);
void led_on(void);
void led_off(void);
void led_toggle(void);
void led_heart_beat(void);
#endif // LED_H
+52 -52
View File
@@ -1,52 +1,52 @@
//
// Created by dell on 24-12-28.
//
#ifndef SOFT_I2C_H
#define SOFT_I2C_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include "board_config.h"
/******************************************************************************/
#define I2C_SCL_HIGH() gpio_bit_set(I2C_SCL_PORT, I2C_SCL_PIN)
#define I2C_SCL_LOW() gpio_bit_reset(I2C_SCL_PORT, I2C_SCL_PIN)
#define I2C_SDA_HIGH() gpio_bit_set(I2C_SDA_PORT, I2C_SDA_PIN)
#define I2C_SDA_LOW() gpio_bit_reset(I2C_SDA_PORT, I2C_SDA_PIN)
#define I2C_SDA_READ() gpio_input_bit_get(I2C_SDA_PORT, I2C_SDA_PIN)
/******************************************************************************/
#define SOFT_I2C_OK 1
#define SOFT_I2C_FAIL 0
#define SOFT_I2C_END 1
/******************************************************************************/
void soft_i2c_delay(void);
void soft_i2c_config(void);
void soft_i2c_start(void);
void soft_i2c_stop(void);
void soft_i2c_send_ack(void);
void soft_i2c_send_nack(void);
uint8_t soft_i2c_wait_ack(void);
void soft_i2c_send_byte(uint8_t data);
uint8_t soft_i2c_receive_byte(uint8_t ack);
uint8_t soft_i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
uint8_t soft_i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
#endif //SOFT_I2C_H
//
// Created by dell on 24-12-28.
//
#ifndef SOFT_I2C_H
#define SOFT_I2C_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include "board_config.h"
/******************************************************************************/
#define I2C_SCL_HIGH() gpio_bit_set(I2C_SCL_PORT, I2C_SCL_PIN)
#define I2C_SCL_LOW() gpio_bit_reset(I2C_SCL_PORT, I2C_SCL_PIN)
#define I2C_SDA_HIGH() gpio_bit_set(I2C_SDA_PORT, I2C_SDA_PIN)
#define I2C_SDA_LOW() gpio_bit_reset(I2C_SDA_PORT, I2C_SDA_PIN)
#define I2C_SDA_READ() gpio_input_bit_get(I2C_SDA_PORT, I2C_SDA_PIN)
/******************************************************************************/
#define SOFT_I2C_OK 1
#define SOFT_I2C_FAIL 0
#define SOFT_I2C_END 1
/******************************************************************************/
void soft_i2c_delay(void);
void soft_i2c_config(void);
void soft_i2c_start(void);
void soft_i2c_stop(void);
void soft_i2c_send_ack(void);
void soft_i2c_send_nack(void);
uint8_t soft_i2c_wait_ack(void);
void soft_i2c_send_byte(uint8_t data);
uint8_t soft_i2c_receive_byte(uint8_t ack);
uint8_t soft_i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
uint8_t soft_i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
#endif //SOFT_I2C_H
+35 -35
View File
@@ -1,36 +1,36 @@
/**
* ************************************************************************
*
* @file systick.h
* @author GD32
* @brief
*
* ************************************************************************
* @copyright Copyright (c) 2024 GD32
* ************************************************************************
*/
#ifndef SYS_TICK_H
#define SYS_TICK_H
#include <stdint.h>
/* function declarations */
/* configure systick */
void systick_config(void);
/* delay a time in 10 microseconds */
void delay_10us(uint32_t count);
/* delay a time in milliseconds */
void delay_ms(uint32_t count);
/* decrement delay counters */
void delay_decrement(void);
// /* delay function that doesn't interfere with SysTick interrupt */
// void delay_ms_safe(uint32_t count);
// /* delay a time in microseconds (safe version) */
// void delay_us_safe(uint32_t count);
/**
* ************************************************************************
*
* @file systick.h
* @author GD32
* @brief
*
* ************************************************************************
* @copyright Copyright (c) 2024 GD32
* ************************************************************************
*/
#ifndef SYS_TICK_H
#define SYS_TICK_H
#include <stdint.h>
/* function declarations */
/* configure systick */
void systick_config(void);
/* delay a time in 10 microseconds */
void delay_10us(uint32_t count);
/* delay a time in milliseconds */
void delay_ms(uint32_t count);
/* decrement delay counters */
void delay_decrement(void);
// /* delay function that doesn't interfere with SysTick interrupt */
// void delay_ms_safe(uint32_t count);
// /* delay a time in microseconds (safe version) */
// void delay_us_safe(uint32_t count);
#endif /* SYS_TICK_H */
+157 -157
View File
@@ -1,157 +1,157 @@
//
// Created by dell on 24-12-20.
// TMP112A Temperature Sensor Driver Header
//
#ifndef TMP112_H
#define TMP112_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "board_config.h"
#include "i2c.h"
/******************************************************************************/
/* TMP112A I2C Address */
#define TMP112A_ADDR (0x49) // 7-bit address (ADD0=GND)
/* Register Addresses */
/******************************************************************************/
#define TMP112A_TEMP_REG 0x00 // 温度寄存器
#define TMP112A_CONFIG_REG 0x01 // 配置寄存器
#define TMP112A_TLOW_REG 0x02 // 低温阈值寄存器
#define TMP112A_THIGH_REG 0x03 // 高温阈值寄存器
/* Configuration Register Bits */
/******************************************************************************/
#define TMP112A_CONFIG_OS (1 << 15) // One-shot
#define TMP112A_CONFIG_R1 (1 << 14) // Converter resolution bit 1
#define TMP112A_CONFIG_R0 (1 << 13) // Converter resolution bit 0
#define TMP112A_CONFIG_F1 (1 << 12) // Fault queue bit 1
#define TMP112A_CONFIG_F0 (1 << 11) // Fault queue bit 0
#define TMP112A_CONFIG_POL (1 << 10) // Polarity
#define TMP112A_CONFIG_TM (1 << 9) // Thermostat mode
#define TMP112A_CONFIG_SD (1 << 8) // Shutdown
#define TMP112A_CONFIG_CR1 (1 << 7) // Conversion rate bit 1
#define TMP112A_CONFIG_CR0 (1 << 6) // Conversion rate bit 0
#define TMP112A_CONFIG_AL (1 << 5) // Alert
#define TMP112A_CONFIG_EM (1 << 4) // Extended mode
/* Resolution Settings */
/******************************************************************************/
#define TMP112A_RESOLUTION_9BIT 0x0000 // 9-bit (0.5°C)
#define TMP112A_RESOLUTION_10BIT 0x2000 // 10-bit (0.25°C)
#define TMP112A_RESOLUTION_11BIT 0x4000 // 11-bit (0.125°C)
#define TMP112A_RESOLUTION_12BIT 0x6000 // 12-bit (0.0625°C)
/* Conversion Rate Settings */
/******************************************************************************/
#define TMP112A_RATE_0_25HZ 0x0000 // 0.25 Hz (4s)
#define TMP112A_RATE_1HZ 0x0040 // 1 Hz (1s)
#define TMP112A_RATE_4HZ 0x0080 // 4 Hz (250ms)
#define TMP112A_RATE_8HZ 0x00C0 // 8 Hz (125ms)
/* Default Configuration */
/******************************************************************************/
#define TMP112A_CONFIG_DEFAULT (TMP112A_RESOLUTION_12BIT | TMP112A_RATE_8HZ)
/* Temperature Conversion Constants */
/******************************************************************************/
#define TMP112A_TEMP_RESOLUTION 0.0625f // 12-bit resolution (°C/LSB)
#define TMP112A_TEMP_MIN -55.0f // 最低温度 (°C)
#define TMP112A_TEMP_MAX 125.0f // 最高温度 (°C)
/* Status Definitions */
/******************************************************************************/
typedef enum {
TMP112A_STATUS_SUCCESS = 0,
TMP112A_STATUS_ERROR,
TMP112A_STATUS_TIMEOUT,
TMP112A_STATUS_INVALID_PARAM,
TMP112A_STATUS_OUT_OF_RANGE
} tmp112a_status_t;
typedef struct {
uint16_t raw_data;
float temperature_c;
float temperature_f;
bool alert_flag;
} tmp112a_result_t;
/******************************************************************************/
/* Function Declarations */
/*!
\brief 初始化TMP112A传感器
\param[in] none
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_init(void);
/*!
\brief 配置TMP112A传感器
\param[in] config: 配置值
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_config(uint16_t config);
/*!
\brief 读取温度
\param[in] none
\param[out] result: 结果结构体指针
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_read_temperature(tmp112a_result_t *result);
void tmp112a_get_raw_temperature_value(uint8_t *value);
/*!
\brief 设置温度阈值
\param[in] low_temp: 低温阈值 (°C)
\param[in] high_temp: 高温阈值 (°C)
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_set_thresholds(float low_temp, float high_temp);
/*!
\brief 进入关机模式
\param[in] none
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_shutdown(void);
/*!
\brief 退出关机模式
\param[in] none
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_wakeup(void);
/*!
\brief 单次转换
\param[in] none
\param[out] result: 结果结构体指针
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_one_shot(tmp112a_result_t *result);
/*!
\brief 获取状态字符串
\param[in] status: 状态码
\param[out] none
\retval const char* 状态字符串
*/
const char* tmp112a_get_status_string(tmp112a_status_t status);
#endif //TMP112_H
//
// Created by dell on 24-12-20.
// TMP112A Temperature Sensor Driver Header
//
#ifndef TMP112_H
#define TMP112_H
#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "board_config.h"
#include "i2c.h"
/******************************************************************************/
/* TMP112A I2C Address */
#define TMP112A_ADDR (0x49) // 7-bit address (ADD0=GND)
/* Register Addresses */
/******************************************************************************/
#define TMP112A_TEMP_REG 0x00 // 温度寄存器
#define TMP112A_CONFIG_REG 0x01 // 配置寄存器
#define TMP112A_TLOW_REG 0x02 // 低温阈值寄存器
#define TMP112A_THIGH_REG 0x03 // 高温阈值寄存器
/* Configuration Register Bits */
/******************************************************************************/
#define TMP112A_CONFIG_OS (1 << 15) // One-shot
#define TMP112A_CONFIG_R1 (1 << 14) // Converter resolution bit 1
#define TMP112A_CONFIG_R0 (1 << 13) // Converter resolution bit 0
#define TMP112A_CONFIG_F1 (1 << 12) // Fault queue bit 1
#define TMP112A_CONFIG_F0 (1 << 11) // Fault queue bit 0
#define TMP112A_CONFIG_POL (1 << 10) // Polarity
#define TMP112A_CONFIG_TM (1 << 9) // Thermostat mode
#define TMP112A_CONFIG_SD (1 << 8) // Shutdown
#define TMP112A_CONFIG_CR1 (1 << 7) // Conversion rate bit 1
#define TMP112A_CONFIG_CR0 (1 << 6) // Conversion rate bit 0
#define TMP112A_CONFIG_AL (1 << 5) // Alert
#define TMP112A_CONFIG_EM (1 << 4) // Extended mode
/* Resolution Settings */
/******************************************************************************/
#define TMP112A_RESOLUTION_9BIT 0x0000 // 9-bit (0.5°C)
#define TMP112A_RESOLUTION_10BIT 0x2000 // 10-bit (0.25°C)
#define TMP112A_RESOLUTION_11BIT 0x4000 // 11-bit (0.125°C)
#define TMP112A_RESOLUTION_12BIT 0x6000 // 12-bit (0.0625°C)
/* Conversion Rate Settings */
/******************************************************************************/
#define TMP112A_RATE_0_25HZ 0x0000 // 0.25 Hz (4s)
#define TMP112A_RATE_1HZ 0x0040 // 1 Hz (1s)
#define TMP112A_RATE_4HZ 0x0080 // 4 Hz (250ms)
#define TMP112A_RATE_8HZ 0x00C0 // 8 Hz (125ms)
/* Default Configuration */
/******************************************************************************/
#define TMP112A_CONFIG_DEFAULT (TMP112A_RESOLUTION_12BIT | TMP112A_RATE_8HZ)
/* Temperature Conversion Constants */
/******************************************************************************/
#define TMP112A_TEMP_RESOLUTION 0.0625f // 12-bit resolution (°C/LSB)
#define TMP112A_TEMP_MIN -55.0f // 最低温度 (°C)
#define TMP112A_TEMP_MAX 125.0f // 最高温度 (°C)
/* Status Definitions */
/******************************************************************************/
typedef enum {
TMP112A_STATUS_SUCCESS = 0,
TMP112A_STATUS_ERROR,
TMP112A_STATUS_TIMEOUT,
TMP112A_STATUS_INVALID_PARAM,
TMP112A_STATUS_OUT_OF_RANGE
} tmp112a_status_t;
typedef struct {
uint16_t raw_data;
float temperature_c;
float temperature_f;
bool alert_flag;
} tmp112a_result_t;
/******************************************************************************/
/* Function Declarations */
/*!
\brief 初始化TMP112A传感器
\param[in] none
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_init(void);
/*!
\brief 配置TMP112A传感器
\param[in] config: 配置值
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_config(uint16_t config);
/*!
\brief 读取温度
\param[in] none
\param[out] result: 结果结构体指针
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_read_temperature(tmp112a_result_t *result);
void tmp112a_get_raw_temperature_value(uint8_t *value);
/*!
\brief 设置温度阈值
\param[in] low_temp: 低温阈值 (°C)
\param[in] high_temp: 高温阈值 (°C)
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_set_thresholds(float low_temp, float high_temp);
/*!
\brief 进入关机模式
\param[in] none
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_shutdown(void);
/*!
\brief 退出关机模式
\param[in] none
\param[out] none
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_wakeup(void);
/*!
\brief 单次转换
\param[in] none
\param[out] result: 结果结构体指针
\retval tmp112a_status_t
*/
tmp112a_status_t tmp112a_one_shot(tmp112a_result_t *result);
/*!
\brief 获取状态字符串
\param[in] status: 状态码
\param[out] none
\retval const char* 状态字符串
*/
const char* tmp112a_get_status_string(tmp112a_status_t status);
#endif //TMP112_H
+8 -8
View File
@@ -1,8 +1,8 @@
#ifndef UART_H
#define UART_H
#include "gd32e23x.h"
void rs485_init(void);
#endif // UART_H
#ifndef UART_H
#define UART_H
#include "gd32e23x.h"
void rs485_init(void);
#endif // UART_H
+119 -119
View File
@@ -1,119 +1,119 @@
/**
* @file uart_ring_buffer.h
* @brief 简单高效的环形接收缓冲区(字节队列)接口声明。
* @details 提供字节写入/读取、可读长度查询、清空与丢弃统计等 API,
* 适用于中断接收(写)与主循环解析(读)的典型嵌入式串口场景。
*/
#ifndef UART_RING_BUFFER_H
#define UART_RING_BUFFER_H
#include <stdint.h>
#include <stdbool.h>
/**
* @def UART_RX_BUFFER_SIZE
* @brief 接收环形缓冲区容量(单位:字节)。
* @note 采用“预留一格”区分空/满策略,最大可用容量为 UART_RX_BUFFER_SIZE-1。
*/
#define UART_RX_BUFFER_SIZE 64
/**
* @defgroup RingBuffer 环形缓冲区
* @brief 字节环形缓冲区(接收端)
* @{
*/
/**
* @section RingBuffer_Usage 使用说明
* 典型用法:中断接收(写入环形缓冲)、主循环解析(读取环形缓冲)。
*
* 1) 初始化
* @code{.c}
* uart_ring_buffer_init();
* @endcode
*
* 2) 使能串口接收非空中断(RBNE)并开启中断(以 USART0 为例)
* @code{.c}
* usart_interrupt_enable(USART0, USART_INT_RBNE);
* nvic_irq_enable(USART0_IRQn, 2, 0); // 根据工程需要设置优先级
* @endcode
*
* 3) 在中断服务函数中写入环形缓冲(参考你当前工程的写法)
* @code{.c}
* void USART0_IRQHandler(void) {
* if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) {
* uint8_t data = usart_data_receive(USART0);
* (void)uart_ring_buffer_put(data); // 缓冲满时丢弃并计数
* }
* }
* @endcode
*
* 4) 在主循环中读取处理
* @code{.c}
* while (uart_ring_buffer_available() > 0) {
* int b = uart_ring_buffer_get();
* if (b >= 0) {
* // 处理字节 b
* }
* }
* @endcode
*
* @note 缓冲区满时新字节会被丢弃,可用 uart_ring_buffer_drop_count() 查看累计丢弃数。
* @note 采用“预留一格”区分空/满,最大可用容量为 UART_RX_BUFFER_SIZE-1。
*/
/**
* @brief 初始化环形缓冲区。
* @details 复位读/写索引与丢弃计数,准备接收数据。
* @note 若在中断环境使用,初始化前建议关闭相关接收中断以避免并发竞争。
* @ingroup RingBuffer
*/
void uart_ring_buffer_init(void);
/**
* @brief 获取当前可读的字节数。
* @details 返回范围为 [0, UART_RX_BUFFER_SIZE-1]。
* @return 可读字节数(uint8_t)。
* @note 预留一个空槽区分“空/满”,因此满时返回 UART_RX_BUFFER_SIZE-1。
* @ingroup RingBuffer
*/
uint8_t uart_ring_buffer_available(void);
/**
* @brief 从环形缓冲区读取一个字节。
* @details 若缓冲区非空,返回队头字节并推进读指针;若为空,返回 -1。
* @return 读取到的字节(0..255),或 -1 表示缓冲区为空。
* @retval -1 缓冲区为空,无数据可读。
* @ingroup RingBuffer
*/
int uart_ring_buffer_get(void);
/**
* @brief 向环形缓冲区写入一个字节。
* @param data 待写入的字节。
* @return 是否写入成功。
* @retval true 写入成功。
* @retval false 写入失败(缓冲区已满,数据被丢弃并计数)。
* @note 如需改为“覆盖写入”策略,可在满时先推进读指针再写入。
* @ingroup RingBuffer
*/
bool uart_ring_buffer_put(uint8_t data);
/**
* @brief 清空环形缓冲区。
* @details 复位读/写索引与丢弃计数,相当于逻辑上丢弃所有已接收数据,不擦除数据区内容。
* @ingroup RingBuffer
*/
void uart_ring_buffer_clear(void);
/**
* @brief 获取因缓冲区满而被丢弃的字节累计数量。
* @details 该计数在 init/clear 时清零。
* @return 丢弃的累计字节数。
* @ingroup RingBuffer
*/
uint32_t uart_ring_buffer_drop_count(void);
/** @} */
#endif // UART_RING_BUFFER_H
/**
* @file uart_ring_buffer.h
* @brief 简单高效的环形接收缓冲区(字节队列)接口声明。
* @details 提供字节写入/读取、可读长度查询、清空与丢弃统计等 API,
* 适用于中断接收(写)与主循环解析(读)的典型嵌入式串口场景。
*/
#ifndef UART_RING_BUFFER_H
#define UART_RING_BUFFER_H
#include <stdint.h>
#include <stdbool.h>
/**
* @def UART_RX_BUFFER_SIZE
* @brief 接收环形缓冲区容量(单位:字节)。
* @note 采用“预留一格”区分空/满策略,最大可用容量为 UART_RX_BUFFER_SIZE-1。
*/
#define UART_RX_BUFFER_SIZE 64
/**
* @defgroup RingBuffer 环形缓冲区
* @brief 字节环形缓冲区(接收端)
* @{
*/
/**
* @section RingBuffer_Usage 使用说明
* 典型用法:中断接收(写入环形缓冲)、主循环解析(读取环形缓冲)。
*
* 1) 初始化
* @code{.c}
* uart_ring_buffer_init();
* @endcode
*
* 2) 使能串口接收非空中断(RBNE)并开启中断(以 USART0 为例)
* @code{.c}
* usart_interrupt_enable(USART0, USART_INT_RBNE);
* nvic_irq_enable(USART0_IRQn, 2, 0); // 根据工程需要设置优先级
* @endcode
*
* 3) 在中断服务函数中写入环形缓冲(参考你当前工程的写法)
* @code{.c}
* void USART0_IRQHandler(void) {
* if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) {
* uint8_t data = usart_data_receive(USART0);
* (void)uart_ring_buffer_put(data); // 缓冲满时丢弃并计数
* }
* }
* @endcode
*
* 4) 在主循环中读取处理
* @code{.c}
* while (uart_ring_buffer_available() > 0) {
* int b = uart_ring_buffer_get();
* if (b >= 0) {
* // 处理字节 b
* }
* }
* @endcode
*
* @note 缓冲区满时新字节会被丢弃,可用 uart_ring_buffer_drop_count() 查看累计丢弃数。
* @note 采用“预留一格”区分空/满,最大可用容量为 UART_RX_BUFFER_SIZE-1。
*/
/**
* @brief 初始化环形缓冲区。
* @details 复位读/写索引与丢弃计数,准备接收数据。
* @note 若在中断环境使用,初始化前建议关闭相关接收中断以避免并发竞争。
* @ingroup RingBuffer
*/
void uart_ring_buffer_init(void);
/**
* @brief 获取当前可读的字节数。
* @details 返回范围为 [0, UART_RX_BUFFER_SIZE-1]。
* @return 可读字节数(uint8_t)。
* @note 预留一个空槽区分“空/满”,因此满时返回 UART_RX_BUFFER_SIZE-1。
* @ingroup RingBuffer
*/
uint8_t uart_ring_buffer_available(void);
/**
* @brief 从环形缓冲区读取一个字节。
* @details 若缓冲区非空,返回队头字节并推进读指针;若为空,返回 -1。
* @return 读取到的字节(0..255),或 -1 表示缓冲区为空。
* @retval -1 缓冲区为空,无数据可读。
* @ingroup RingBuffer
*/
int uart_ring_buffer_get(void);
/**
* @brief 向环形缓冲区写入一个字节。
* @param data 待写入的字节。
* @return 是否写入成功。
* @retval true 写入成功。
* @retval false 写入失败(缓冲区已满,数据被丢弃并计数)。
* @note 如需改为“覆盖写入”策略,可在满时先推进读指针再写入。
* @ingroup RingBuffer
*/
bool uart_ring_buffer_put(uint8_t data);
/**
* @brief 清空环形缓冲区。
* @details 复位读/写索引与丢弃计数,相当于逻辑上丢弃所有已接收数据,不擦除数据区内容。
* @ingroup RingBuffer
*/
void uart_ring_buffer_clear(void);
/**
* @brief 获取因缓冲区满而被丢弃的字节累计数量。
* @details 该计数在 init/clear 时清零。
* @return 丢弃的累计字节数。
* @ingroup RingBuffer
*/
uint32_t uart_ring_buffer_drop_count(void);
/** @} */
#endif // UART_RING_BUFFER_H