GD32F450的串口DMA收发+接受完成中断

GD32的库比较糟糕当时完全是参考STM32的驱动来的,当然我也知道直接用ST的库可以,但是原因比较特殊就不多说了。

代码就不贴了,以后用GD的机会我想不会太多。

先初始化串口,使能串口,使能接受完成中断。

再初始化DMA通道。贴一段

1 int fputc(int ch, FILE *f)
2 {
3     usart_data_transmit(USART0, (uint8_t)ch);
4     while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
5     return ch;
6 }
 1 void uart0_dma_config(void)
 2 {
 3         dma_single_data_parameter_struct dma_init_struct;
 4     /* enable DMA1 */
 5     rcu_periph_clock_enable(RCU_DMA1);
 6     /* deinitialize DMA channel7(USART0 tx) */
 7     dma_deinit(DMA1, DMA_CH7);
 8     dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
 9     dma_init_struct.memory0_addr = (uint32_t)tx_buffer0;
10     dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
11     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
12     dma_init_struct.number = TXBUFF_SIZE;
13     dma_init_struct.periph_addr = USART0_DATA_ADDRESS;
14     dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
15     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
16     dma_single_data_mode_init(DMA1, DMA_CH7, dma_init_struct);
17     /* configure DMA mode */
18     dma_circulation_disable(DMA1, DMA_CH7);
19     dma_channel_subperipheral_select(DMA1, DMA_CH7, DMA_SUBPERI4);
20
21     dma_deinit(DMA1, DMA_CH2);
22     dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
23     dma_init_struct.memory0_addr = (uint32_t)rx_buffer0;
24         dma_init_struct.number = RXBUFF_SIZE;
25     dma_single_data_mode_init(DMA1, DMA_CH2, dma_init_struct);
26     /* configure DMA mode */
27     dma_circulation_disable(DMA1, DMA_CH2);
28     dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI4);
29
30         dma_channel_enable(DMA1, DMA_CH2);//UART0 RX
31
32         usart_dma_receive_config(USART0, USART_DENR_ENABLE);
33
34 //        nvic_irq_enable(DMA1_Channel2_IRQn, 3, 0);
35 //        dma_interrupt_enable(DMA1,DMA_CH2,DMA_CHXCTL_FTFIE);
36 }    

#define USART0_DATA_ADDRESS    ((uint32_t)0x40011004)

其实里面的USART0_DATA_ADDRESS,就是串口0 的数据寄存器地址。

先看接收。

 1 void USART1_IRQHandler(void)
 2 {
 3     uint32_t buff_length = 0;
 4     if((RESET != usart_interrupt_flag_get(USART1, USART_INT_IDLEIE)) &&
 5        (RESET != usart_flag_get(USART1, USART_FLAG_IDLEF)))
 6     {
 7                 usart_data_receive(USART1);
 8                 buff_length =  RXBUFF_SIZE - DMA_CHCNT(DMA0,DMA_CH5);
 9 //                 UART_TRANSMIT(USART1,rx_buffer1,buff_length);
10 //                 UART_DMA_TRANSMIT(USART1,rx_buffer1,buff_length);
11 //            while(1)
12 //            if(dma_flag_get(DMA0,DMA_CH6,DMA_INTF_FTFIF)!=RESET)//µÈ´ýDMA2_Steam7´«ÊäÍê³É
13 //                {
14 //                    dma_flag_clear(DMA0,DMA_CH6,DMA_INTF_FTFIF);//Çå³ýDMA2_Steam7´«ÊäÍê³É±êÖ¾
15 //
16 //                    break;
17 //            }
18             UART_DMA_TRANSMIT(UART3,rx_buffer1,buff_length);
19              while(1)
20             if(dma_flag_get(DMA0,DMA_CH4,DMA_INTF_FTFIF)!=RESET)//µÈ´ýDMA2_Steam7´«ÊäÍê³É
21                 {
22                     dma_flag_clear(DMA0,DMA_CH4,DMA_INTF_FTFIF);//Çå³ýDMA2_Steam7´«ÊäÍê³É±êÖ¾
23
24                     break;
25             }
26             dma_channel_disable(DMA0, DMA_CH5);
27             dma_flag_clear(DMA0,DMA_CH5,DMA_INTF_FTFIF);//Çå³ýDMA2_Steam7´«ÊäÍê³É±êÖ¾
28             dma_channel_enable(DMA0, DMA_CH5);
29             }
30             else{
31                         uint32_t isrflags   = USART_STAT0(USART1);
32                         if((usart_interrupt_flag_get(USART1,USART_FLAG_PERR))!=RESET)
33                         {
34                                         USART_DATA(USART1);
35                                         usart_flag_clear(USART1, USART_FLAG_PERR);
36                         }
37                         if((usart_interrupt_flag_get(USART1, USART_FLAG_FERR))!=RESET)
38                         {
39                                         USART_DATA(USART1);
40                                         usart_flag_clear(USART1, USART_FLAG_FERR);
41                         }
42
43                         if((usart_interrupt_flag_get(USART1, USART_FLAG_NERR))!=RESET)
44                         {
45                                         USART_DATA(USART1);
46                                         usart_flag_clear(USART1, USART_FLAG_NERR);
47                         }
48
49                         if((usart_interrupt_flag_get(USART1, USART_FLAG_ORERR))!=RESET)
50                         {
51                                         USART_DATA(USART1);//ORE???,????CR
52                                         usart_flag_clear(USART1, USART_FLAG_ORERR);
53                         }
54     }
55 }

数据当然是在DMA通道FIFO里,本次接收长度=总的FIFO长度-剩余接收长度。

然后发送这么长的数据。

清发送标志,关闭接受通道,清接收标志,再打开接收通道。

 1 void UART_DMA_TRANSMIT(uint32_t usart_periph,uint8_t *DATA,uint32_t NUM)
 2 {
 3     if(usart_periph == USART0)
 4         {
 5             memcpy(tx_buffer0,DATA,NUM);
 6             DMA_CHCNT(DMA1, DMA_CH7) = NUM;
 7             dma_channel_enable(DMA1, DMA_CH7);
 8         }
 9         else if(usart_periph == USART1)
10         {
11             memcpy(tx_buffer1,DATA,NUM);
12             DMA_CHCNT(DMA0, DMA_CH6) = NUM;
13             dma_channel_enable(DMA0, DMA_CH6);
14         }
15         else if(usart_periph == USART2)
16         {
17             memcpy(tx_buffer2,DATA,NUM);
18             DMA_CHCNT(DMA0, DMA_CH3) = NUM;
19             dma_channel_enable(DMA0, DMA_CH3);
20         }
21         else if(usart_periph == UART3)
22         {
23             memcpy(tx_buffer3,DATA,NUM);
24             DMA_CHCNT(DMA0, DMA_CH4) = NUM;
25             dma_channel_enable(DMA0, DMA_CH4);
26         }
27
28         usart_dma_transmit_config(usart_periph, USART_DENT_ENABLE);
29
30 }

发送函数:把数放入通道FIFO,告诉通道数据长度,使能通道,调用一次发送。OK

原文地址:https://www.cnblogs.com/schoolmate-li/p/10876835.html

时间: 2024-10-23 20:15:51

GD32F450的串口DMA收发+接受完成中断的相关文章

STM32的串口DMA收发以及双缓冲区的实现

在使用STM32的UART的DMA功能总结如下: 首先上代码,这里采用STM32 的USART1作为Demo,RX的DMA为DMA1_Channel5,TX的DMA为DMA1_Channel4.初始化如下,红色的标记需要注意: RX-DMA初始化 1 // DMA Rx 2 USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); 3 DMA_Cmd(DMA1_Channel5,DISABLE); 4 DMA_InitStruct.DMA_PeripheralBa

STM32F407的串口采用DMA收发数据

?? STM32F407的串口采用DMA收发数据 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN8 开发环境:MDK5.13 mcu: stm32f407VGT6 说明: 之前用STM32F103实现DMA收发串口数据,现在项目中采用STM32F407,所以将此机制移植到F4上. STM32F103上用DMA收发串口数据文章: STM32的串口采用DMA方式发送数据测试 STM32的串口采用DMA方式接收数据测试 源代码: 串

STM32CubeMX HAL库串口+DMA数据发送不定长度数据接收

参考资料:1.ST HAL库官网资料 2.https://blog.csdn.net/u014470361/article/details/79206352#comments 一.STM32CubeMX配置外部时钟 注意在进行外部时钟配置时,即"High Speed Clock"和"Low Speed Clock"需配置成"Crytal/Ceramic Resonator(低温/陶瓷谐振器)"不能配置为"BYASS Clock Sour

ecos stm32 步步深入8 - 手工打造串口usart2驱动实验ecos中断

最近忙别的事情,很长时间没碰ecos了,这两天有点空,抽空写个串口驱动玩玩,也验证一下ecos的中断调用.LZ花了两天时间写好这个驱动,中间遇到了几个比较恶心的问题,后来发现是前面的基础没打好,所幸都解决了. 尽管ECOS已经写好了串口的驱动程序,只需要在配置工具中使能即可.不过别人写的毕竟不是自己的,还是自己写的用的方便,这次试验的主要目的是为了调试ecos的中断服务,让串口中断能收发数据. 首先遇到的最大的问题,事实上跟什么串口都没关系,就是debug时一执行task delay,调试程序就

android4.2串口jni收发数据(基于自定义协议)

代码已经验证过,没问题 ! 代码层次结构: |-----serial_communication_class--- |                     |-------src--------- |                                  |------com------ |                                             |----object----- |                                

STM32Cube 串口DMA发送问题

STM32Cube 串口DMA发送问题:只能运行一次,第二次返回状态为HAL_BUSY 解决办法: 这样就可以实现每次调用HAL_UART_Trasmit_DMA发送指定长度的数组.

STM32串口DMA超时接收方法,可大大节约CPU时间

//超时时间定义#define        UART1_TimeoutComp 2  //20ms#define        UART2_TimeoutComp 10  //100ms#define        UART3_TimeoutComp 10  //100ms u8 UART1_Timeout,UART2_Timeout,UART3_Timeout;u16 UART1_FlagTemp,UART2_FlagTemp,UART3_FlagTemp;u8 uart1_data_tem

串口通信常用波特率,中断函数

1.12M晶振产生2400 4800波特率 /**************************************************************** 函数名:UART串口初始化函数 调  用:UART_init(); 参  数:无 返回值:无 结  果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用) 备  注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ] /********************************

串口实现FIFO接受数据

基本原理:静态队列 /* * 串口的FIFO简单读取实现 * 功能,实现串口的FIFO实现 * 使用方法: * 版本:v1.0.0 * */ #include "sys.h" #include "usartbuf.h" USARType Usart_fifo_Read( Usart_RecerivePoint Rusart,uint8_t * buf,uint8_t length) { if (Rusart->Count - length < 0)//缓