add mcu flash size detect and auto config usart

This commit is contained in:
2025-08-25 17:26:19 +08:00
parent 2d752eed5e
commit d651ff73c9
7 changed files with 136 additions and 19 deletions

View File

@@ -29,7 +29,7 @@ set(TARGET_SRC
Src/led.c Src/led.c
Src/uart_ring_buffer.c Src/uart_ring_buffer.c
Src/command.c Src/command.c
Src/i2c.c Src/board_config.c
Src/ultrasonic_analog.c Src/ultrasonic_analog.c
) )

View File

@@ -1,6 +1,10 @@
#ifndef BOARD_CONFIG_H #ifndef BOARD_CONFIG_H
#define BOARD_CONFIG_H #define BOARD_CONFIG_H
#define GD32E23XF4 0x10
#define GD32E23XF6 0x20
#define GD32E23XF8 0x40
/* >>>>>>>>>>>>>>>>>>>>[RS485 PHY DEFINE]<<<<<<<<<<<<<<<<<<<< */ /* >>>>>>>>>>>>>>>>>>>>[RS485 PHY DEFINE]<<<<<<<<<<<<<<<<<<<< */
// #define RS485_MAX13487 // RS485 PHY : MAX13487 (AutoDir) // #define RS485_MAX13487 // RS485 PHY : MAX13487 (AutoDir)
@@ -18,6 +22,23 @@
/******************************************************************************/ /******************************************************************************/
/* 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_GPIO_I2C RCU_GPIOF
#define RCU_I2C RCU_I2C0 #define RCU_I2C RCU_I2C0
#define I2C_SCL_PORT GPIOF #define I2C_SCL_PORT GPIOF
@@ -36,15 +57,15 @@
/******************************************************************************/ /******************************************************************************/
#define RS485_RCU RCU_USART0 #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_RCU RCU_GPIOA
#define RS485_GPIO_PORT GPIOA #define RS485_GPIO_PORT GPIOA
#define RS485_EN_PIN GPIO_PIN_1
#define RS485_TX_PIN GPIO_PIN_2 #define RS485_TX_PIN GPIO_PIN_2
#define RS485_RX_PIN GPIO_PIN_3 #define RS485_RX_PIN GPIO_PIN_3
#define RS485_PHY USART0
#define RS485_BAUDRATE 115200U #define RS485_BAUDRATE 115200U
#define RS485_EN_PIN GPIO_PIN_1
#define RS485_IRQ USART0_IRQn
/******************************************************************************/ /******************************************************************************/
@@ -58,11 +79,6 @@
/******************************************************************************/ /******************************************************************************/
#define US_TX_DELAY_RCU RCU_TIMER15
#define US_TX_DELAY_TIMER TIMER15
/******************************************************************************/
#define US_RX_GPIO_RCU RCU_GPIOB #define US_RX_GPIO_RCU RCU_GPIOB
#define US_RX_EXTI_RCU RCU_CFGCMP #define US_RX_EXTI_RCU RCU_CFGCMP
#define US_RX_GPIO_PORT GPIOA #define US_RX_GPIO_PORT GPIOA
@@ -73,7 +89,6 @@
/******************************************************************************/ /******************************************************************************/
// 修改为TIMER15相关定义
#define US_ECHO_RCU RCU_TIMER16 #define US_ECHO_RCU RCU_TIMER16
#define US_ECHO_TIMER TIMER16 #define US_ECHO_TIMER TIMER16
#define US_ECHO_CH TIMER_CH_0 #define US_ECHO_CH TIMER_CH_0
@@ -81,4 +96,7 @@
/******************************************************************************/ /******************************************************************************/
void mcu_detect_and_config(void);
uint8_t get_flash_size(void);
#endif //BOARD_CONFIG_H #endif //BOARD_CONFIG_H

52
Src/board_config.c Normal file
View File

@@ -0,0 +1,52 @@
#include "gd32e23x.h"
#include "board_config.h"
#include "systick.h"
/******************************************************************************/
#define FLASH_SIZE_ADDR (*(const uint8_t *)0x1FFFF7E0) // Flash base address
/******************************************************************************/
/* 前向声明中断处理函数 */
void usart0_irq_handler(void);
void usart1_irq_handler(void);
usart_config_t g_usart_config = {
.rcu_usart = RCU_USART1,
.usart_periph = USART1,
.irq_type = USART1_IRQn,
.irq_handler = usart1_irq_handler // 初始化函数指针
};
uint8_t g_mcu_flash_size = 0;
void mcu_detect_and_config(void) {
g_mcu_flash_size = FLASH_SIZE_ADDR;
switch (g_mcu_flash_size) {
case GD32E23XF4:
g_usart_config.rcu_usart = RCU_USART0;
g_usart_config.usart_periph = USART0;
g_usart_config.irq_type = USART0_IRQn;
g_usart_config.irq_handler = usart0_irq_handler; // 指向USART0处理函数
break;
case GD32E23XF6:
g_usart_config.rcu_usart = RCU_USART1;
g_usart_config.usart_periph = USART1;
g_usart_config.irq_type = USART1_IRQn;
g_usart_config.irq_handler = usart1_irq_handler; // 指向USART1处理函数
break;
default: // Default to GD32E23XF8
g_usart_config.rcu_usart = RCU_USART1;
g_usart_config.usart_periph = USART1;
g_usart_config.irq_type = USART1_IRQn;
g_usart_config.irq_handler = usart1_irq_handler; // 指向USART1处理函数
break;
}
}
uint8_t get_flash_size(void) {
return g_mcu_flash_size;
}

View File

@@ -38,6 +38,7 @@ OF SUCH DAMAGE.
#include "uart_ring_buffer.h" #include "uart_ring_buffer.h"
#include "led.h" #include "led.h"
#include "ultrasonic_analog.h" #include "ultrasonic_analog.h"
#include "board_config.h"
/*! /*!
\brief this function handles NMI exception \brief this function handles NMI exception
@@ -151,8 +152,15 @@ void TIMER13_IRQHandler(void)
} }
void USART0_IRQHandler(void) { void USART0_IRQHandler(void) {
if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { // 检查当前配置是否使用USART0并且函数指针不为空
uint8_t data = usart_data_receive(USART0); if(g_usart_config.usart_periph == USART0 && g_usart_config.irq_handler != 0) {
(void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计 g_usart_config.irq_handler(); // 通过函数指针调用对应的处理函数
}
}
void USART1_IRQHandler(void) {
// 检查当前配置是否使用USART1并且函数指针不为空
if(g_usart_config.usart_periph == USART1 && g_usart_config.irq_handler != 0) {
g_usart_config.irq_handler(); // 通过函数指针调用对应的处理函数
} }
} }

View File

@@ -51,16 +51,20 @@ OF SUCH DAMAGE.
*/ */
int main(void) int main(void)
{ {
led_init();
mcu_detect_and_config();
setbuf(stdout, NULL); setbuf(stdout, NULL);
systick_config(); systick_config();
rs485_init(); rs485_init();
led_init();
ultrasonic_config(); ultrasonic_config();
ultrasonic_pwm_out_cycles(); ultrasonic_pwm_out_cycles();
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

@@ -16,6 +16,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "gd32e23x_usart.h" #include "gd32e23x_usart.h"
#include "board_config.h"
#undef errno #undef errno
extern int errno; extern int errno;
@@ -164,7 +165,7 @@ int _execve(char *name, char **argv, char **env)
// USART0 printf重定向实现 // USART0 printf重定向实现
int __io_putchar(int ch) { int __io_putchar(int ch) {
// 等待发送缓冲区空 // 等待发送缓冲区空
while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET) {} while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {}
usart_data_transmit(USART0, (uint8_t)ch); usart_data_transmit(RS485_PHY, (uint8_t)ch);
return ch; return ch;
} }

View File

@@ -3,7 +3,7 @@
#include "gd32e23x_rcu.h" #include "gd32e23x_rcu.h"
#include "gd32e23x_gpio.h" #include "gd32e23x_gpio.h"
#include "board_config.h" #include "board_config.h"
#include "uart_ring_buffer.h"
void rs485_init(void) { void rs485_init(void) {
@@ -37,7 +37,7 @@ void rs485_init(void) {
usart_enable(RS485_PHY); 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_RBNE);
// usart_interrupt_enable(RS485_PHY, USART_INT_IDLE); // usart_interrupt_enable(RS485_PHY, USART_INT_IDLE);
@@ -70,3 +70,37 @@ void rs485_init(void) {
#endif // RS485_MAX13487 #endif // RS485_MAX13487
} }
/******************************************************************************/
/* 具体的中断处理函数实现 */
/******************************************************************************/
void usart0_irq_handler(void) {
// 处理USART0的接收中断
if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) {
uint8_t data = usart_data_receive(USART0);
// 使用原有的环形缓冲区处理逻辑
(void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计
}
// 处理USART0的空闲中断
if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) {
usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE);
// 在这里添加空闲中断处理逻辑
}
}
void usart1_irq_handler(void) {
// 处理USART1的接收中断
if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE)) {
uint8_t data = usart_data_receive(USART1);
// 使用原有的环形缓冲区处理逻辑
(void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计
}
// 处理USART1的空闲中断
if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_IDLE)) {
usart_interrupt_flag_clear(USART1, USART_INT_FLAG_IDLE);
// 在这里添加空闲中断处理逻辑
}
}