diff --git a/CMakeLists.txt b/CMakeLists.txt index 8afb984..8679d2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ set(TARGET_SRC Src/i2c.c Src/ldc1612.c Src/tmp112.c + Src/mcu_config.c ) # 设置输出目录 diff --git a/Inc/board_config.h b/Inc/board_config.h index 5b43610..b9a22f9 100644 --- a/Inc/board_config.h +++ b/Inc/board_config.h @@ -21,6 +21,29 @@ // #define EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Enable #undef EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Disable +#define GD32E23XF4 0x10 +#define GD32E23XF6 0x20 +#define GD32E23XF8 0x40 + +/* MCU Type Detection */ +extern uint8_t g_mcu_type; + +/* Dynamic USART Configuration Structure */ +typedef struct { + uint32_t rcu_usart; + uint32_t usart_periph; + uint8_t gpio_af; + IRQn_Type irq_type; +} usart_config_t; + +extern usart_config_t g_usart_config; + +/* Function to detect MCU type and configure USART */ +void mcu_detect_and_config(void); + +/* Function to get current MCU type */ +uint8_t get_mcu_type(void); + /******************************************************************************/ #define RCU_GPIO_I2C RCU_GPIOF @@ -31,7 +54,7 @@ #define I2C_SDA_PIN GPIO_PIN_0 #define I2C_GPIO_AF GPIO_AF_1 -#define I2C_DEBUG_UART USART0 +#define I2C_DEBUG_UART USART1 /******************************************************************************/ @@ -41,15 +64,19 @@ /******************************************************************************/ -#define RS485_RCU RCU_USART0 +/* Use dynamic configuration instead of static defines */ #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 USART0 #define RS485_BAUDRATE 115200U #define RS485_EN_PIN GPIO_PIN_1 -#define RS485_IRQ USART0_IRQn + +/* Dynamic configuration - will be set by mcu_detect_and_config() */ +#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_AF (g_usart_config.gpio_af) /******************************************************************************/ diff --git a/LD/gd32e23x_flash.ld b/LD/gd32e23x_flash.ld index 405de65..f48d452 100644 --- a/LD/gd32e23x_flash.ld +++ b/LD/gd32e23x_flash.ld @@ -12,8 +12,8 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K } /* Sections */ diff --git a/Src/gd32e23x_it.c b/Src/gd32e23x_it.c index aa19aa8..287dc43 100644 --- a/Src/gd32e23x_it.c +++ b/Src/gd32e23x_it.c @@ -37,6 +37,7 @@ OF SUCH DAMAGE. #include "uart.h" #include "uart_ring_buffer.h" #include "led.h" +#include "board_config.h" /*! \brief this function handles NMI exception @@ -102,8 +103,19 @@ void SysTick_Handler(void) { } 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); // 缓冲满时丢弃,返回值可用于统计 + if (get_mcu_type() == GD32E23XF4) { + if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { + uint8_t data = usart_data_receive(USART0); + (void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计 + } + } +} + +void USART1_IRQHandler(void) { + if (get_mcu_type() == GD32E23XF6 || get_mcu_type() == GD32E23XF8) { + if (RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE)) { + uint8_t data = usart_data_receive(USART1); + (void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计 + } } } \ No newline at end of file diff --git a/Src/main.c b/Src/main.c index 9047325..1f8e01a 100644 --- a/Src/main.c +++ b/Src/main.c @@ -43,6 +43,8 @@ OF SUCH DAMAGE. #include "ldc1612.h" #include "tmp112.h" +#define FLASH_SIZE_ADDR (*(const uint16_t *)0x1FFFF7E0) + /*! \brief main function \param[in] none @@ -51,13 +53,41 @@ OF SUCH DAMAGE. */ int main(void) { + systick_config(); + + /* Detect MCU type and configure USART accordingly */ + mcu_detect_and_config(); + + uint16_t flash_kb = FLASH_SIZE_ADDR; + + rs485_init(); + printf("MCU Type detected: "); + switch (get_mcu_type()) { + case GD32E23XF4: + printf("GD32E23XF4 (using USART0)\r\n"); + break; + case GD32E23XF6: + printf("GD32E23XF6 (using USART1)\r\n"); + break; + case GD32E23XF8: + printf("GD32E23XF8 (using USART1)\r\n"); + break; + default: + printf("Unknown (default to GD32E23XF8)\r\n"); + break; + } setbuf(stdout, NULL); - systick_config(); + rs485_init(); led_init(); + printf("Flash Size: %d KB\r\n", flash_kb); + printf("%x\r\n", flash_kb); + + printf("Flash Size Bytes: %02X\r\n", flash_kb & 0xFF); + #ifdef DEBUG_VERBOSE char hello_world[] = {"Hello World!\r\n"}; diff --git a/Src/mcu_config.c b/Src/mcu_config.c new file mode 100644 index 0000000..c0b1b92 --- /dev/null +++ b/Src/mcu_config.c @@ -0,0 +1,77 @@ +/*! + \file mcu_config.c + \brief MCU type detection and dynamic configuration + + \version 2025-08-20, V1.0.0, MCU detection for GD32E23x +*/ + +#include "gd32e23x.h" +#include "board_config.h" + +#define FLASH_SIZE_ADDR (*(const uint16_t *)0x1FFFF7E0) + +/* Global variables for dynamic configuration */ +uint8_t g_mcu_type = 0; +usart_config_t g_usart_config = {0}; + +/*! + \brief detect MCU type and configure USART accordingly + \param[in] none + \param[out] none + \retval none +*/ +void mcu_detect_and_config(void) +{ + uint16_t flash_kb = FLASH_SIZE_ADDR; + uint8_t size = (flash_kb >> 8) & 0xFF; + + /* Detect MCU type based on flash size */ + switch (size) { + case GD32E23XF4: + g_mcu_type = GD32E23XF4; + /* Configure for USART0 (GD32E23XF4) */ + g_usart_config.rcu_usart = RCU_USART0; + g_usart_config.usart_periph = USART0; + g_usart_config.gpio_af = GPIO_AF_1; + g_usart_config.irq_type = USART0_IRQn; + break; + + case GD32E23XF6: + g_mcu_type = GD32E23XF6; + /* Configure for USART1 (GD32E23XF6) */ + g_usart_config.rcu_usart = RCU_USART1; + g_usart_config.usart_periph = USART1; + g_usart_config.gpio_af = GPIO_AF_1; + g_usart_config.irq_type = USART1_IRQn; + break; + + case GD32E23XF8: + g_mcu_type = GD32E23XF8; + /* Configure for USART1 (GD32E23XF8) */ + g_usart_config.rcu_usart = RCU_USART1; + g_usart_config.usart_periph = USART1; + g_usart_config.gpio_af = GPIO_AF_1; + g_usart_config.irq_type = USART1_IRQn; + break; + + default: + /* Default to GD32E23XF8 configuration */ + g_mcu_type = GD32E23XF8; + g_usart_config.rcu_usart = RCU_USART1; + g_usart_config.usart_periph = USART1; + g_usart_config.gpio_af = GPIO_AF_1; + g_usart_config.irq_type = USART1_IRQn; + break; + } +} + +/*! + \brief get current MCU type + \param[in] none + \param[out] none + \retval MCU type (GD32E23XF4, GD32E23XF6, or GD32E23XF8) +*/ +uint8_t get_mcu_type(void) +{ + return g_mcu_type; +} diff --git a/Src/syscalls.c b/Src/syscalls.c index 46beccf..c1a1d8c 100644 --- a/Src/syscalls.c +++ b/Src/syscalls.c @@ -16,6 +16,7 @@ #include #include #include "gd32e23x_usart.h" +#include "board_config.h" #undef errno extern int errno; @@ -164,7 +165,7 @@ int _execve(char *name, char **argv, char **env) // USART0 printf重定向实现 int __io_putchar(int ch) { // 等待发送缓冲区空 - while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET) {} - usart_data_transmit(USART0, (uint8_t)ch); + while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} + usart_data_transmit(RS485_PHY, (uint8_t)ch); return ch; } diff --git a/Src/uart.c b/Src/uart.c index 6d699c9..98cfdb8 100644 --- a/Src/uart.c +++ b/Src/uart.c @@ -8,12 +8,12 @@ void rs485_init(void) { #ifndef RS485_MAX13487 - /* 使能 GPIOA 和 USART0 时钟 */ + /* 使能 GPIOA 和 USART 时钟 */ rcu_periph_clock_enable(RS485_GPIO_RCU); rcu_periph_clock_enable(RS485_RCU); - /* 配置 PA2 为 USART0_TX,PA3 为 USART0_RX */ - gpio_af_set(RS485_GPIO_PORT, GPIO_AF_1, RS485_TX_PIN | RS485_RX_PIN | RS485_EN_PIN); + /* 配置 PA2 为 USART_TX,PA3 为 USART_RX */ + gpio_af_set(RS485_GPIO_PORT, RS485_GPIO_AF, RS485_TX_PIN | RS485_RX_PIN | RS485_EN_PIN); gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, RS485_TX_PIN | RS485_RX_PIN); gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_TX_PIN | RS485_RX_PIN); @@ -37,7 +37,7 @@ void rs485_init(void) { usart_enable(RS485_PHY); - nvic_irq_enable(USART0_IRQn, 0); + nvic_irq_enable(RS485_IRQ, 0); usart_interrupt_enable(RS485_PHY, USART_INT_RBNE); // usart_interrupt_enable(RS485_PHY, USART_INT_IDLE);