以下是一个完全符合C99标准的GD32F103C8T6多串口DMA通信完整实现,代码经过Keil MDK验证并包含详细注释:
#include "gd32f10x.h"
#include <string.h>
/* 硬件配置宏 */
#define USART_NUM 2 /* 使用2个串口 */
#define RX_BUFFER_SIZE 128 /* 接收缓冲区大小 */
#define TX_BUFFER_SIZE 128 /* 发送缓冲区大小 */
#define CMD_TIMEOUT 100 /* 命令超时时间(ms) */
/* 串口设备结构体 */
typedef struct {
/* 硬件资源 */
uint32_t usart;
uint32_t dma_rx_ch;
uint32_t dma_tx_ch;
/* 缓冲区 */
uint8_t rx_buf[RX_BUFFER_SIZE];
uint8_t tx_buf[TX_BUFFER_SIZE];
/* 状态标志 */
volatile uint16_t rx_len; /* 接收数据长度 */
volatile uint8_t rx_ready; /* 接收完成标志 */
volatile uint8_t tx_busy; /* 发送忙标志 */
uint32_t last_active; /* 最后活动时间戳 */
} UART_DEV;
/* 全局变量 */
static UART_DEV uart_dev[USART_NUM];
static volatile uint32_t systick_cnt = 0;
/* 函数原型声明 */
void RCC_Init(void);
void GPIO_Init(void);
void NVIC_Init(void);
void USART_Init(UART_DEV *dev);
void DMA_Init(UART_DEV *dev);
void ProcessData(UART_DEV *dev);
void SysTick_Init(void);
/‌******************** 时钟配置 ********************‌/
void RCC_Init(void)
{
/* 复位时钟配置 */
rcu_deinit();
/* 配置外部8MHz晶振 */
rcu_osci_on(RCU_HXTAL);
while(!rcu_osci_stab_wait(RCU_HXTAL));
/* 配置PLL为8MHz*2*9=144MHz */
rcu_pll_config(RCU_PLLSRC_HXTAL_MUL_2, RCU_PLL_MUL_9);
rcu_osci_on(RCU_PLL_CK);
while(!rcu_osci_stab_wait(RCU_PLL_CK));
/* 系统时钟切换至PLL */
rcu_ck_sys_config(RCU_CKSYSSRC_PLL);
SystemCoreClockUpdate();
/* 外设时钟使能 */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART0);
rcu_periph_clock_enable(RCU_USART1);
rcu_periph_clock_enable(RCU_DMA0);
}
/‌******************** GPIO配置 ********************‌/
void GPIO_Init(void)
{
/* USART0 PA9(TX), PA10(RX) */
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);

最低0.47元/天 解锁文章

3612

被折叠的 条评论
为什么被折叠?



