打印
[STM8]

【转】STM8L 在USART中使用DMA来发送与接收数据

[复制链接]
890|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
联通移不动|  楼主 | 2016-11-13 17:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以USART为例子来使用DMA分两部分,第一为,DMA这个外设自身的配置;第二为,USART的DMA部分配置,
DMA与USART的DMA配置
[cpp] view plain copy


  • void SYS_DMA_Init(void)  
  • {         
  •     CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);</span>    //打开时钟,很重要  
  •     /* Deinitialize DMA channels */  
  •     DMA_GlobalDeInit();  
  •    
  •     DMA_DeInit(DMA1_Channel1);  
  •     DMA_DeInit(DMA1_Channel2);  
  •       
  •     /* DMA channel Rx of USART Configuration */  
  •     //该函数主要要配置好接受的数组,以及USART的数据寄存器地址,数组大小,以及DMA模式  
  •     DMA_Init(DMA1_Channel2, (uint16_t)RxBuffer, (uint16_t)0x5231, \  
  •              10, DMA_DIR_PeripheralToMemory, DMA_Mode_Normal, \  
  •              DMA_MemoryIncMode_Inc, DMA_Priority_Low, DMA_MemoryDataSize_Byte);  
  •    
  •     /* DMA channel Tx of USART Configuration */  
  •     //该函数主要配置发送数组,以及USART的数据寄存器地址,数组大小,以及DMA模式  
  •     DMA_Init(DMA1_Channel1, (uint16_t)TxBuffer, (uint16_t)0x5231, \  
  •              60, DMA_DIR_MemoryToPeripheral, DMA_Mode_Normal, \  
  •              DMA_MemoryIncMode_Inc, DMA_Priority_High, DMA_MemoryDataSize_Byte);  
  •       
  •     /* Enable the USART Tx/Rx DMA requests */  
  •     USART_DMACmd(USART1, USART_DMAReq_TX, ENABLE);  
  •     USART_DMACmd(USART1, USART_DMAReq_RX, ENABLE);  
  •    
  •     /* Global DMA Enable */  
  •     DMA_GlobalCmd(ENABLE);  
  •    
  •     /* Enable the USART Tx DMA channel */  
  •     DMA_Cmd(DMA1_Channel1, ENABLE);  
  •     /* Enable the USART Rx DMA channel */  
  •     DMA_Cmd(DMA1_Channel2, ENABLE);           
  • }  




下面主要对void DMA_Init(DMA_Channel_TypeDef* DMA_Channelx,
              uint32_t DMA_Memory0BaseAddr,
              uint16_t DMA_PeripheralMemory1BaseAddr,
              uint8_t DMA_BufferSize,
              DMA_DIR_TypeDef DMA_DIR,
              DMA_Mode_TypeDef DMA_Mode,
              DMA_MemoryIncMode_TypeDef DMA_MemoryIncMode,
              DMA_Priority_TypeDef DMA_Priority,
              DMA_MemoryDataSize_TypeDef DMA_MemoryDataSize )


沙发
联通移不动|  楼主 | 2016-11-13 17:12 | 只看该作者
函数的主要参数做一下说明,DMA_Channelx:针对不同的外设,这个有可能是通道0123,主要根据下表来进行选择:
file:///C:/Users/Fangzebin/Documents/My%20Knowledge/temp/04f9f09b-69e1-4c7a-98eb-ea4aceb1304d_files/be854c33-7555-4e67-9abd-19b8444716ff.png




本例子中,USART_TX 对应的是通道1,USART_RX对应的是通道2。
DMA_Memory0BaseAddr:该参数为存储器地址,在本例中为接收数组RXBuffer或发送数组TxBuffer的指针地址。

DMA_PeripheralMemory1BaseAddr:该参数为外设的数据地址,在本例中为USART的数据寄存器的地址

DMA_BufferSize:该参数为接收数组或发送数组的缓存区大小。

DMA_DIR_TypeDef DMA_DIR:该参数为DMA数据传输的方向,在USART_TX中为存储器到外设,在USART_RX 中就为外设到存储器。

DMA_Mode_TypeDef DMA_Mode:该参数为DMA的模式,分正常模式和循环模式两种。正常模式下响应了DMA请求后不再响应请求。
下面再讲讲如何在DMA正常模式下,响应了一次DMA请求后,再次启动DMA请求,分别以USART_TX、USART_RX为例子讲解
USART_TX:在上面例子中,TxBuffer[]存放着待发送的数组,当调用DMA_Cmd(DMA1_Channel1, ENABLE);
启动DMA通道后,DMA响应了该次请求,如需再次响应请求则需先关闭DMA通道DMA_Cmd(DMA1_Channel1, DISABLE); 并调用DMA_SetCurrDataCounter(DMA1_Channel1, 60)函数重新设置待发送的数据大小,之后再使能DMA通道DMA_Cmd(DMA1_Channel1, ENABLE); 即可重新发送数据。
USART_RX:USART DMA接收中,与上面USART_TX的流程相同,当调用了DMA_Cmd(DMA1_Channel1, ENABLE)之后,DMA可响应首次接收请求,如需再次响应请求则需要关闭DMA通道DMA_Cmd(DMA1_Channel1, DISABLE); 并调用DMA_SetCurrDataCounter(DMA1_Channel2, 10)函数重新设置待接收的数据大小,之后再使能DMA通道DMA_Cmd(DMA1_Channel1, ENABLE); 即可再次响应USART接收DMA请求。



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

127

帖子

0

粉丝