流程
选择端口,了解端口配置特性
DMA请求映射表
GPIO初始化和USARTx初始化
DMA初始化
DMA接收
DAM发送
中断服务函数
GD32F307串口端口定义
DMA请求映射表
Peripheral | Ch0 | Ch1 | Ch2 | Ch3 | Ch4 | Ch5 | Ch6 |
---|---|---|---|---|---|---|---|
USART | / | USART2_TX | USART2_RX | USART0_TX | USART0_RX | USART1_RX | USART1_TX |
串口初始化
TX - 配置为复用推挽输出
RX - 配置为浮空输入
void UART1_Init(void)
{
//使能中断,配置中断优先级
nvic_irq_enable(USART1_IRQn, 0, 2);//中断源 抢占优先级, 响应优先级
//配置GPIO
rcu_periph_clock_enable(RCU_GPIOA);
//使能UARTx时钟
rcu_periph_clock_enable(RCU_USART1);
//UART1 TX(PA2) Init
gpio_init(UART1_TX_PORT,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,UART1_TX_PIN);
//UART1 RX(PA3) Init
gpio_init(UART1_RX_PORT,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,UART1_RX_PIN);
//Reset UARTx
usart_deinit(USART1);
usart_baudrate_set(USART1,115200);//配置波特率
usart_parity_config(USART1,USART_PM_NONE);//配置校验
usart_word_length_set(USART1,USART_WL_8BIT);//配置数据长度
usart_stop_bit_set(USART1,USART_STB_1BIT);//配置停止位
usart_hardware_flow_rts_config(USART1,USART_RTS_DISABLE);//RTS Disable
usart_hardware_flow_cts_config(USART1,USART_CTS_DISABLE);//CTS Disable
usart_receive_config(USART1,USART_RECEIVE_ENABLE);//使能串口接收功能
usart_transmit_config(USART1,USART_TRANSMIT_ENABLE);//使能串口发送功能
usart_enable(USART1);//使能串口
usart_interrupt_enable(USART1, USART_INT_IDLE);//使能RX空闲中断
}
DMA初始化
DMA接收
void UART1_RevDMAConfig(void)
{
dma_parameter_struct dma_struct;
rcu_periph_clock_enable(RCU_DMA0);//使能时钟
dma_deinit(DMA0,DMA_CH5);
dma_struct_para_init(&dma_struct);
dma_struct.direction = DMA_PERIPHERAL_TO_MEMORY;//传输方向 外设到内存
dma_struct.memory_addr = (uint32_t)(uart1data_t.uc_dmarevbuf);//源地址
dma_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_struct.number = DMA_BUFMAXSIZE;
dma_struct.periph_addr = (uint32_t)USART1+4;//USART1+4
dma_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_struct.priority = DMA_PRIORITY_HIGH;
dma_init(DMA0,DMA_CH5,&dma_struct);
dma_circulation_disable(DMA0, DMA_CH5);
dma_memory_to_memory_disable(DMA0, DMA_CH5);
dma_circulation_enable(DMA0, DMA_CH5);//启用循环接收数据
//使能传输
usart_dma_receive_config(USART1,USART_DENR_ENABLE);
dma_channel_enable(DMA0, DMA_CH5);
}
DMA发送
void UART1_SendDMAConfig(unsigned char *buf,unsigned short int len)
{
dma_parameter_struct dma_struct;
rcu_periph_clock_enable(RCU_DMA0);//使能时钟
dma_deinit(DMA0,DMA_CH6);
dma_struct_para_init(&dma_struct);
dma_struct.direction = DMA_MEMORY_TO_PERIPHERAL;//传输方向 内存到外设
dma_struct.memory_addr = (uint32_t)(buf);//源地址
dma_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_struct.number = len;
dma_struct.periph_addr = (uint32_t)USART1+4;//USART1+4
dma_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_struct.priority = DMA_PRIORITY_HIGH;
dma_init(DMA0,DMA_CH6,&dma_struct);
dma_circulation_disable(DMA0, DMA_CH6);
dma_memory_to_memory_disable(DMA0, DMA_CH6);
dma_circulation_disable(DMA0, DMA_CH6);//禁用循环接收数据
//使能传输
usart_dma_transmit_config(USART1,USART_DENT_ENABLE);
dma_channel_enable(DMA0, DMA_CH6);
}
中断服务函数
void USART1_IRQHandler(void)
{
if(RESET != usart_interrupt_flag_get(USART1,USART_INT_FLAG_IDLE))
{
usart_data_receive(USART1);
DMA_DATA_Trea(&uart1data_t);
}
//检测过载错误
if(RESET!=usart_interrupt_flag_get(USART1,USART_INT_FLAG_ERR_ORERR))
{
usart_data_receive(USART1);
}
}
获取本次通讯的数据并回传到串口助手
uartdata->ui_Point_Hend = uartdata->ui_Poing_End;//获取本次接收数据头指针
uartdata->ui_Poing_End = DMA_BUFMAXSIZE -
dma_transfer_number_get(DMA0,DMA_CH5);//获取本次数据尾指针
//将接收到的数据发送到串口助手
if(uartdata->ui_Poing_End>uartdata->ui_Point_Hend)
{
uartdata->ui_dmarevlen = uartdata->ui_Poing_End
- uartdata->ui_Point_Hend;
for(i=0;i<uartdata->ui_dmarevlen;i++)
{
uartdata->uc_dmasendbuf[i] =
uartdata->uc_dmarevbuf[uartdata->ui_Point_Hend+i];
}
}
else
{
for(i=0;i<DMA_BUFMAXSIZE-uartdata->ui_Point_Hend;i++)
{
uartdata->uc_dmasendbuf[i] =
uartdata->uc_dmarevbuf[uartdata->ui_Point_Hend+i];
}
for(i=0;i<uartdata->ui_Poing_End;i++)
{
uartdata->uc_dmasendbuf[DMA_BUFMAXSIZE-uartdata->ui_Point_Hend+i]
= uartdata->uc_dmarevbuf[i];
}
uartdata->ui_dmarevlen =
DMA_BUFMAXSIZE-uartdata->ui_Point_Hend+uartdata->ui_Poing_End;
}
UART1_SendDMAConfig(uartdata->uc_dmasendbuf,uartdata->ui_dmarevlen);
串口通讯助手测试结果