- 新增完整的CMSIS解决方案配置,包含AC6/GCC/IAR/CLANG编译器支持 - 添加项目配置文件,定义了设备层、系统层、应用层的模块结构 - 配置ARM::CMSIS和GigaDevice::GD32E50x_DFP软件包依赖 - 创建多层代码架构:应用入口(main)、系统层(sys)、设备层(device) - 实现任务管理系统,包含任务调度器和任务执行器分离设计 - 集成ADC、CANFD、定时器、串口、温度采样等核心功能模块 - 添加详细的README文档说明项目结构和代码组织方式 - 配置AC6链接脚本和运行时环境文件 - 设置Git忽略规则以排除编译产物和临时文件
109 lines
2.9 KiB
Plaintext
109 lines
2.9 KiB
Plaintext
/**
|
|
* @file usart0.cpp
|
|
* @brief USART0 串口配置与 printf 重定向实现。
|
|
* @note 使用 TX 中断 + 环形缓冲替代逐字节忙等 TBE,降低 CPU 占用。
|
|
*/
|
|
|
|
#include "main.h"
|
|
#include "device/usart0.h"
|
|
#include "sys/config.h"
|
|
|
|
#define USARTx USART0
|
|
#define USART_TX_BUF_SIZE 256U
|
|
|
|
namespace {
|
|
uint8_t g_tx_buf[USART_TX_BUF_SIZE];
|
|
volatile uint16_t g_tx_head = 0U;
|
|
volatile uint16_t g_tx_tail = 0U;
|
|
|
|
inline uint16_t tx_buf_next(uint16_t idx)
|
|
{
|
|
return (idx + 1U) % USART_TX_BUF_SIZE;
|
|
}
|
|
|
|
inline bool tx_buf_full(void)
|
|
{
|
|
return tx_buf_next(g_tx_head) == g_tx_tail;
|
|
}
|
|
|
|
inline bool tx_buf_empty(void)
|
|
{
|
|
return g_tx_head == g_tx_tail;
|
|
}
|
|
} // namespace
|
|
|
|
/**
|
|
* @brief 重定向标准输出字符到 USART0。
|
|
* @param[in] ch 待输出的字符。
|
|
* @param[in] f 标准流指针;当前实现中未实际使用。
|
|
* @retval 返回已发送的字符值。
|
|
* @note 将字符写入环形发送缓冲,由 USART0 TXE 中断负责实际发送。
|
|
*/
|
|
extern "C" int fputc(int ch, FILE *f)
|
|
{
|
|
(void)f;
|
|
uint16_t next = tx_buf_next(g_tx_head);
|
|
|
|
while(next == g_tx_tail) {
|
|
/* 缓冲满,忙等一小段时间后重试;
|
|
* 在 115200 波特率下通常不会发生 */
|
|
}
|
|
g_tx_buf[g_tx_head] = static_cast<uint8_t>(ch);
|
|
g_tx_head = next;
|
|
|
|
/* 启动 TXE 中断以触发实际硬件发送 */
|
|
usart_interrupt_enable(USARTx, USART_INT_TBE);
|
|
|
|
return ch;
|
|
}
|
|
|
|
/**
|
|
* @brief USART0 中断服务例程。
|
|
* @note 处理 TXE 发送缓冲区空中断,从环形缓冲取下一字节发送。
|
|
*/
|
|
extern "C" void USART0_IRQHandler(void)
|
|
{
|
|
if(usart_interrupt_flag_get(USARTx, USART_INT_FLAG_TBE) != RESET) {
|
|
if(!tx_buf_empty()) {
|
|
usart_data_transmit(USARTx, g_tx_buf[g_tx_tail]);
|
|
g_tx_tail = tx_buf_next(g_tx_tail);
|
|
}
|
|
/* 缓冲已空,关 TXE 中断,等下次 fputc 再开 */
|
|
if(tx_buf_empty()) {
|
|
usart_interrupt_disable(USARTx, USART_INT_TBE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief 配置 USART0 相关 GPIO 引脚。
|
|
*/
|
|
void usart0_gpio_config(void)
|
|
{
|
|
rcu_periph_clock_enable(RCU_GPIOA);
|
|
|
|
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
|
|
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
|
|
}
|
|
|
|
/**
|
|
* @brief 配置并使能 USART0 外设。
|
|
* @note 当前使用 8N1 格式,115200 波特率,收发同时使能。
|
|
* 同步配置 NVIC 以便 TXE 中断驱动发送。
|
|
*/
|
|
void usart0_config(void)
|
|
{
|
|
rcu_periph_clock_enable(RCU_USART0);
|
|
|
|
usart_deinit(USARTx);
|
|
usart_baudrate_set(USARTx, CONFIG_USART0_BAUDRATE);
|
|
usart_word_length_set(USARTx, USART_WL_8BIT);
|
|
usart_stop_bit_set(USARTx, USART_STB_1BIT);
|
|
usart_parity_config(USARTx, USART_PM_NONE);
|
|
usart_receive_config(USARTx, USART_RECEIVE_ENABLE);
|
|
usart_transmit_config(USARTx, USART_TRANSMIT_ENABLE);
|
|
usart_enable(USARTx);
|
|
|
|
/* 使能 USART0 NVIC,用于 TXE 中断驱动发送 */
|
|
nvic_irq_enable(USART0_IRQn, 2U, 0U);
|
|
} |