微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 关于 DMA 方式实现串口接收的的问题

关于 DMA 方式实现串口接收的的问题

时间:10-02 整理:3721RD 点击:
刚刚接手 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′??ú?óê?êμ?é£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方式

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top