STM32
直播中

李莉

7年用户 1372经验值
私信 关注
[问答]

STM32F4与STM32F1使用串口DMA有何区别呢

STM32的串口DMA有哪些特性呢?
STM32F4与STM32F1使用串口DMA有何区别呢?

回帖(1)

陈佳敏

2021-12-6 15:01:21
STM32F4是M4内核和STM32F1是M3内核,使用起来都差不多,函数名称可能不同,F4的功能更强,外设数量也不同,具体看看使用串口DMA的区别:

  

  

DMA可看作是CPU的小弟,数据的搬运工,当通过CPU配置好DMA后,DMA自己去工作,等CPU大哥有事找的时候再去叫小弟。
  STM32F103:

  
  

  


  

  

  

  


  

  


  

  


  

  


  

  


  

  

  
  

  


  

  

  MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,(TEXT_LENTH+2)*100);//DMA1通道4,外设为串口1,存储器为SendBuff,
参数含义及其可选范围:
1,PeripheralBaseAddr,外设地址,这里是串口1的TDR寄存器的地址,串口会将此寄存器是值发送出去,所以把想发送的数据,写到这个地址:&USART1->DR
2,MemoryBaseAddr,内存地址,可以是数组,也就是想要通过串口发送的数据,数组名就是地址。
3,DIR,选择方向,这里是将数组的数据通过DMA搬运到USART1的DR,所以外设是目标地址,数组是源地址。

  

  

4,BufferSize,DMA缓存的大小,这个大小是以源地址里的数据的宽度为单位,每发送一个单位,值减一
5,PeripheralInc,外设地址递增使能,外设地址是DR,都是通过这个地址发送过的,不需要递增,也不能递增,所以MA_PeripheralInc_Disable

  

  

6,MemoryInc,内存地址寄存器递增,每发送一个数据,指针移动到下一个数据的位置,数组名是首元素的递增,需要将数组的所有元素发送,所有需要递增, DMA_MemoryInc_Enable。

  

  

7,PeripheralDataSize,外设数据宽度大小,也就是外设一次接收多少位数据,有一个字节(8位),两个字节(半字,16位),四个字节(一个字,32位)可选。DR是8位的,所以选择DMA_PeripheralDataSize_Byte;

  

  

8,MemoryDataSize,内存数据宽度,即每次搬运多少位出去,可选范围也是一个字节(8位),两个字节(半字,16位),四个字节(一个字,32位)
,宏定义不一样。数组的每个字符是8位的,所以选择DMA_MemoryDataSize_Byte;

  

  

9,传输模式,可选择单次和循环,单次也就是将数组的元素传完之后停止,BufferSize=0,循环,就是传完后,再传,BufferSize自动重载。

  

  

10,优先级,每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁起来协调各个DMA请求的优先权。4种可选,低,中等,高,很高。

  

  

11,M2M,内存到内存,如果使用内存到内存就使能。然后这是内存到外设,所以DMA_M2M_Disable
如果先采用单次传输的方式,为达到每按一次按键从发一次,需要在每个单次完成后,重载DMA_BufferSize

  

  

其中,通过全局变量DMA1_MEM_LEN保存DMA每次数据传送的长度 ,然后给下面的函数,用来重载

  

  

注意到:MYDMA_Config函数只是配置参数,没有开启(DMA_Cmd(DMA_CHx, ENABLE))通道, 所以上面那个函数叫MYDMA_Enable,一来重新加载DMA_BufferSize,二来使能DMA DMA_Cmd(DMA_CHx, ENABLE); ,再对DMA操作前,先使能DMA:DMA_Cmd(DMA_CHx, DISABLE );
配置好DMA后,还得使能对应外设的DMA功能,USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
  主函数这样调用:

  

  

**
  STM32f407

  **

  

  


  

  


  

  


  

  

  
  

  

与F1相比,变化较大,对比一下:
发现f4的是叫数据流和通道,f1是叫通道和外设。

  

  


  

  


  

  


  

  


  

  


  

  


  

  

与F1相比,多了个突发模式可以用

  

  

对比代码:
F1:DMA通道
          MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,(TEXT_LENTH+2)*100);//DMA1通道4,外设为串口1,存储器为S   
  

  


  

  


  

  


  

  

  

  

F4:DMA数据流
           MYDMA_Config(DMA2_Stream7,DMA_Channel_4,(u32)&USART1->DR,(u32)SendBuff,SEND_BUF_SIZE);//DMA2,STEAM7,CH4,外设为串口1,存储器为SendBuff,长度为:SEND_BUF_SIZE.   
  

  

DMA_FIFOMode 用来设置是否开启 FIFO 模式。这里我们不开启所以选择DMA_FIFOMode_Disable。
DMA_FIFOThreshold 用来选择 FIFO 阈值。根据前面讲解可以为 FIFO 容量的1/4,1/2,3/4 以及 1 倍。这里我们实际并没有开启 FIFO 模式,所以可以不关心。
DMA_MemoryBurst 用来配置存储器突发传输配置。可以选择为 4 个节拍的增量突发传输 DMA_MemoryBurst_INC4, 8 个节拍的增量突发传输 DMA_MemoryBurst_INC8, 16 个节拍的增量突发传输DMA_MemoryBurst_INC16 以及单次传输 DMA_MemoryBurst_Single。
DMA_PeripheralBurst 用来配置外设突发传输配置。跟前面一个参数
DMA_MemoryBurst 作用类似,只不过一个针对的是存储器,一个是外设。这里我们选择单次传输DMA_PeripheralBurst_Single。

  

  


  

  


  

  

比F1多了一个判断:while(DMA_GetCmdStatus(DMA_Streamx) != DISABLE){} //确保DMA可以被设置

  
举报

更多回帖

发帖
×
20
完善资料,
赚取积分