AT32F407 DMA串口通信收发
本帖最后由 Jekele 于 2021-3-19 11:34 编辑笔者407板子的USRAT1发没问题,收貌似有问题(废了老大的劲,最终断定USART1有问题),换了USART2立马就好了。
一、USRAT2串口配置
1、配置USART2时钟,GPIO(复用),USRAT2串口模式...
2、开启USART2发送完成中断,总线空闲检测中断,使能DMA串口发送请求,使能DMA串口接收请求,最后使能USART2串口。
二、DMA配置
1、参数配置中寄存器地址为使用串口的数据寄存器地址,内存地址为自定义的内存地址;
2、使能DMA发送通道,使能DMA接收通道,使能DMA发送端传输完成中断;
三、中断配置
1、中断分组配置,使能USART2中断,使能DMA发送通道中断。
四、DMA串口发送
1、笔者采用的单次发送模式,如果不进行其他操作,上电后只发送一次就会停止。
2、想要后续继续使用DMA发送,在第一次发送完成后,先清中断标志、关闭DMA发送通道,再次设置发送的字节数(一定要在关闭发送通道的情况下设置),最后在打开DMA发送通道完成下一次的发送。
五、DMA串口接收
1、接收完成一包数据后进入总线空闲检测中断,先清中断标志、关闭DMA接收通道(防止再次接收到数据造成干扰),再获取接收的数据长度、处理接收到的数据等操作。
2、为保证后续继续通过DMA接收数据,要再次设置接收的字节数,并重新打开DMA接收通道。最后循环操作即可。
USRAT1发没问题,收貌似有问题(废了老大的劲,最终断定USART1有问题),换了USART2立马就好了
这个具体点的问题现象是什么?
一点小建议:用DMA收发的话,一般就不要软件去判定以及清除RDNE标志了。还有就前面描述来看TRAC的中断函数及相关操作是多余的 usart1 pa9 pa10的硬件电路连在了at link ez上的,请看一下电路 本帖最后由 Jekele 于 2021-3-22 11:05 编辑
muyichuan2012 发表于 2021-3-19 23:32
usart1 pa9 pa10的硬件电路连在了at link ez上的,请看一下电路
首先谢谢版主回复,电路我也看了,板子at link CN2这里没有焊接,是断开的,按理说不影响吧。如果还有其他情况请版主告知一二,谢谢! hoop 发表于 2021-3-19 19:27
USRAT1发没问题,收貌似有问题(废了老大的劲,最终断定USART1有问题),换了USART2立马就好了
这个具体点 ...
你好,这个不光是DMA模式接收不了数据,普通模式也是接收不了。本人对硬件了解不是很好,就没再往下查。 Jekele 发表于 2021-3-22 11:04
你好,这个不光是DMA模式接收不了数据,普通模式也是接收不了。本人对硬件了解不是很好,就没再往下查。 ...
好的
如果有需要的话,可以@我一起调试分析。
可以肯定的是USART1的收发在设计阶段是有经过严格测试的,不会存在前述问题才对。 本帖最后由 admvip 于 2021-3-28 22:03 编辑
USART1 DMA空闲中断收发没有问题,已经写代码通过测试了。分别使用固定DMA通道和弹性DMA通道,都没有问题,正常收发。
串口1初始化函数
串口1空闲中断接收函数
中断回调函数
admvip 发表于 2021-3-28 21:51
USART1 DMA空闲中断收发没有问题,已经写代码通过测试了。分别使用固定DMA通道和弹性DMA通道,都没有问题, ...
你好,可以把第一张图再发一下吗,看不清楚,我这里也遇到问题了,想借鉴一下啊,谢谢 小叶三千 发表于 2021-3-30 13:43
你好,可以把第一张图再发一下吗,看不清楚,我这里也遇到问题了,想借鉴一下啊,谢谢 ...
void USART1_Init(void)
{
/* 定义串口初始化所需参数配置结构体 */
GPIO_InitType GPIO_InitStructure;
USART_InitType USART_InitStructure;
NVIC_InitType NVIC_InitStructure;
DMA_InitType DMA_InitStructure;
/* 开启串口相关外设时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA | RCC_APB2PERIPH_USART1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA1, ENABLE);
/* 串口1引脚设置 */
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_9; //TX 引脚
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure the UART1 RX pin */
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_10; //RX 引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_PD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART1 中断设置 */
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the DMA1通道3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the DMA1通道4 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* USART1 参数设置 */
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_INTConfig(USART1, USART_INT_IDLEF, ENABLE); //USART1串口空闲中断使能
USART_Cmd(USART1, ENABLE); //USART1 使能
/* DMA参数配置 */
/* USART1_Tx_DMA_Channel (triggered by USART1 Tx event) Config */
DMA_Reset(DMA1_Channel3); //复位DMA通道
DMA_Reset(DMA1_Channel4);
DMA_Flexible_Config(DMA1, Flex_Channel3, DMA_FLEXIBLE_UART1_TX); //启用DMA弹性通道
DMA_Flexible_Config(DMA1, Flex_Channel4, DMA_FLEXIBLE_UART1_RX);
DMA_DefaultInitParaConfig(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_BASE+0x04; //USART1串口数据寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Txbuffer; //存储器数据源地址(指针)
DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALDST; //外设为数据目的地
DMA_InitStructure.DMA_BufferSize = TX_Buffer_Size; //设置DMA传输的数据数量
DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; //DMA外设地址增长禁止
DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; //DMA存储器地址增长使能
DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_BYTE; //DMA传输外设数据类型--字节型
DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE; //DMA传输存储器数据类型--字节型
DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; //DMA运行模式--单次
DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH; //DMA优先级--非常高
DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; //DMA存储器到存储器模式禁止
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
/* USART1_rx_DMA_Channel (triggered by USART1 Rx event) Config */
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_BASE+0x04; //USART1串口数据寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Rxbuffer; //存储器数据源地址(指针)
DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC; //外设为数据源
DMA_InitStructure.DMA_BufferSize = RX_Buffer_Size; //设置DMA传输的数据数量
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
DMA_ChannelEnable(DMA1_Channel3, ENABLE); //DMA1通道3使能
DMA_ChannelEnable(DMA1_Channel4, ENABLE); //DMA1通道4使能
DMA_INTConfig(DMA1_Channel3, DMA_INT_TC, ENABLE); //DMA1通道3 传输完成中断使能
DMA_INTConfig(DMA1_Channel4, DMA_INT_TC, ENABLE); //DMA1通道4 传输完成中断使能
/* 开启USART1串口DMA传输请求 DMA传输正式启动*/
USART_DMACmd(USART1, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE);
} admvip 发表于 2021-3-30 17:05
void USART1_Init(void)
{
/* 定义串口初始化所需参数配置结构体 */
多谢多谢 感谢楼主和7楼的详细说明。 请问楼主有没有打包的工程,想参考一下
页:
[1]