野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13950|回复: 7

关于DMA配置的问题

[复制链接]
发表于 2015-8-29 17:26:51 | 显示全部楼层 |阅读模式
本帖最后由 jiajie 于 2015-8-29 17:32 编辑

刚刚接手 stm32用dma的方式实现串口的发送操作,想着通过dma方式实现串口接收。出了些问题:
实验现象是
··················发送以后一直接收空的内容,停不下来!
请大家 给点帮助谢了!

1、

但是在配置DMA时候有点疑惑
  1. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  2.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
复制代码
也就是这俩该怎么选择 。
我自己的理解是这样的   外设是串口 串口的数据寄存器(USART_DR)是32位但是 前24位保留   也就是只有8位
我定义了一个8位的变量(uint8_t) 那么现在上面就该被配置成     DMA_MemoryDataSize_Byte    和   DMA_PeripheralDataSize_Byte
不知道我的理解对不对。
2、USART 数据寄存器标志位 RXNE 是怎样被清零的 数据手册里这样解释的:
  1. RXNE:读数据寄存器非空
  2. 当RDR移位寄存器中的数据被转移到USART_DR寄存器中,该位被硬件置位。如果
  3. USART_CR1寄存器中的RXNEIE为1,则产生中断<font color="#ff8c00">。对USART_DR的读操作可以将该位清
  4. 零。</font> RXNE位也可以通过写入0来清除,只有在多缓存通讯中才推荐这种清除程序。
  5. 0:数据没有收到;
  6. 1:收到数据,可以读出。
复制代码
里边提到的"对USART_DR的读操作可以将该位清" 这是说   对USART_DR寄存器进行读操作以后硬件自动把RXNE标志位清零,还是在进行读操作的函数里边软件清零。
为了搞清楚这个问题我 找到USART_ReceiveDate()函数
  1. uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
  2. {
  3.   /* Check the parameters */
  4.   assert_param(IS_USART_ALL_PERIPH(USARTx));
  5.   
  6.   /* Receive Data */
  7.   return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
  8. }
复制代码
并没有发现软件清零。也就是说对USART_DR寄存器进行读操作以后硬件自动把RXNE标志位清零 (不知道到底对不对)
下边是DMA方式实现串口接收的主要的配置代码
  1. int main(void)
  2. {
  3.         SysTick_Init();
  4.         LED_GPIO_Config();
  5.         USART1_DMA_Config();
  6.         USART1_Config();
  7.         printf("\nDMA′&#174;&#191;ú&#189;óê&#213;êμ&#209;é£o\n");
  8.         while(1)
  9.         {
  10.                 if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==!RESET)
  11.       printf("%c",ReceiveBuff);
  12.                         Delay_ms(100);
  13.         }        
  14. }
复制代码
  1. void USART1_DMA_Config(void)
  2. {
  3.     DMA_InitTypeDef DMA_InitStructure;
  4.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  5.     DMA_InitStructure.DMA_BufferSize = 1;
  6.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  7.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  8.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
  9.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  10.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  11.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  12.     DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
  13.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  14.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  15.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  16.     DMA_Init(DMA1_Channel5,&DMA_InitStructure);
  17.     DMA_Cmd(DMA1_Channel5,ENABLE);        
  18.         }
复制代码

在USART1_Config();里边使能了串口的DMA方式




回复

使用道具 举报

发表于 2015-8-29 17:48:47 | 显示全部楼层
串口的DMA方式已经有例程和解析材料,在《零角度玩转STM32-V2.pdf》的11.3 DMA 实例之串口通信
,楼主可以先看看pdf,应该理解更多
USART_DR寄存器进行读操作以后硬件自动把RXNE标志位清零(确实是这样的)
回复 支持 反对

使用道具 举报

发表于 2015-8-29 17:50:32 | 显示全部楼层
在做串口DMA实验时候要把串口调试助手的自动清空选上,不然很容易造成串口调试助手界面卡死情况
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-8-29 17:59:51 | 显示全部楼层
亽亼 发表于 2015-8-29 17:50
在做串口DMA实验时候要把串口调试助手的自动清空选上,不然很容易造成串口调试助手界面卡死情况

恩 谢了  但是没看见哪有自动清空
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-8-29 18:06:33 | 显示全部楼层
亽亼 发表于 2015-8-29 17:48
串口的DMA方式已经有例程和解析材料,在《零角度玩转STM32-V2.pdf》的11.3 DMA 实例之串口通信
,楼主可以 ...

恩恩    文档上的实验室用dma方式发送的实验   
回复 支持 反对

使用道具 举报

发表于 2015-8-29 18:22:20 | 显示全部楼层
QQ截图20150829173935.png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-8-29 18:23:52 | 显示全部楼层

哦哦  你用的是这款啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-8-30 12:16:52 | 显示全部楼层

嘿嘿 好了    主要是我DMA配置的问题。谢了啊!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-9-23 15:19 , Processed in 0.048936 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表