stm32-9DMA为CPU减负

来源:互联网 发布:苹果关闭数据流量 编辑:程序博客网 时间:2024/06/07 16:16

stm32-9DMA为CPU减负


      • stm32-9DMA为CPU减负
        • 一DMA相关
          • 用DMA传输数据到USART1过程
          • 注意
        • 二分析程序
          • 主函数
          • 跟踪USART1_DMA_Config配置函数它定义于bsp_usart1c文件中
          • 内存装入数据的代码块
          • USART1向DMA发出TX请求


一、DMA相关

直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间高速数据传输。无须CPU任何干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
两个DMA控制器有12个通道(DMA1有7个通道, DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权

1. 用DMA传输数据到USART1过程
  1. 当发生TXE事件(TDR为空)产生DMA请求到DMA控制器 -> DMA应答,访问外设 -> 外设受到应答信号,释放请求->DMA撤销应答
  2. DMA将数据加载到外设TDR
  3. 计数器DMA_CNDTRx递减
2. 注意
  1. 编号低的通道优先级高
  2. 每次传输后相关寄存器自减

二、分析程序

1. 主函数

主要功能:用DMA移动数据由内存SendBuff到外设USART1,CPU处理其他事情
1. USART1_Config();用于配置串口通信
2. USART1_DMA_Config();用于配制DMA:由内存到外设
3. LED_GPIO_Config();用于配制LED,供CPU控制

#include "stm32f10x.h"#include "bsp_usart1.h"#include "bsp_led.h"extern uint8_t SendBuff[SENDBUFF_SIZE];//static void Delay(__IO u32 nCount); /**  * @brief    * @param    * @retval   */int main(void){        /* USART1 config 115200 8-N-1 */        USART1_Config();        /* DMA配置 */        USART1_DMA_Config();        /* LED配置 */        LED_GPIO_Config();        /* 打印“usart1 DMA TX 测试” */        printf("\r\n usart1 DMA TX 测试 \r\n");        /* 将数据装入内存 */        {            uint16_t i;            /*填充将要发送的数据*/            for(i=0;i<SENDBUFF_SIZE;i++)            {                SendBuff[i]  = 'A';            }        }        /* USART1 向 DMA发出TX请求 */        USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);        /* 此时CPU是空闲的,可以干其他事情 */        //例如:同时控制LED        for(;;)        {            LED1(ON);            Delay(0xFFFFF);            LED1(OFF);            Delay(0xFFFFF);        }}static void Delay(__IO uint32_t nCount)  //简单的延时函数{    for(; nCount != 0; nCount--);}

2.跟踪USART1_DMA_Config配置函数,它定义于bsp_usart1.c文件中

DMA_InitTypeDef 定义于文件“stm32f10x_dma.h”:
通过DMA初始化结构体初始化DMA寄存器
使能DMA

typedef struct{    u32 DMA_PeripheralBaseAddr;    u32 DMA_MemoryBaseAddr;    u32 DMA_DIR;    u32 DMA_BufferSize;    u32 DMA_PeripheralInc;    u32 DMA_MemoryInc;    u32 DMA_PeripheralDataSize;    u32 DMA_MemoryDataSize;    u32 DMA_Mode;    u32 DMA_Priority;    u32 DMA_M2M;} DMA_InitTypeDef;
/**  * @brief  USART1 TX DMA 配置,由内存到外设(USART1->DR)  * @param    * @retval   */void USART1_DMA_Config(void){    /*定义初始化DMA的结构体*/    DMA_InitTypeDef DMA_InitStructure;    /*开启DMA时钟*/    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    /*设置DMA外设基地址:串口数据寄存器地址*/    DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;         /*设置内存基地址(要传输变量的指针)*/    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;    /*外设作为传输的目的DST或来源SRC:目的*/           DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;      /*指定DMA通道的DMA缓存的大小,单位为数据单位,大小DMA_BufferSize=SENDBUFF_SIZE*/     DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;    /*外设地址是否自增:不自增*/            DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;     /*内存地址是否自增:自增*/    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;     /*外设数据单位*/      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    /*内存数据宽度8、16、32:8位*/    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;      /*DMA模式:循环*/    //当指定 DMA 通道数据传输配置为内存到内存时,不能使用循环缓存模式。    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;      /*优先级(非常高、高、中、低):中*/        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;      /*禁止内存到内存的传输*/    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;    /*根据 DMA_InitStruct 中指定的参数初始化 DMA1 的通道 4 寄存器*/             DMA_Init(DMA1_Channel4, &DMA_InitStructure);           /*使能DMA*/    DMA_Cmd (DMA1_Channel4,ENABLE);    /*使能DMA完成后产生中断*/                    //DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);  }

3. 内存装入数据的代码块
{    uint16_t i;    /* 填充将要发送的数据到内存 */    for(i=0;i<SENDBUFF_SIZE;i++)    {        SendBuff[i]  = 'A';    }}

4. USART1向DMA发出TX请求

USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);//在文件stm32f10x_usart.c中
功能描述:使能或者失能指定 USART 的 DMA 请求
输入参数 1 USARTx: x 可以是 1, 2 或者 3,来选择 USART 外设
输入参数 2 USART_DMAreq:指定 DMA 请求
输入参数 3 NewState: USARTx DMA 请求源的新状态,这个参数可以取: ENABLE 或者 DISABLE

/**  * @brief  Enables or disables the USART’s DMA interface.  * @param  USARTx: Select the USART or the UART peripheral.   *   This parameter can be one of the following values:  *   USART1, USART2, USART3, UART4 or UART5.  * @param  USART_DMAReq: specifies the DMA request.  *   This parameter can be any combination of the following values:  *     @arg USART_DMAReq_Tx: USART DMA transmit request  *     @arg USART_DMAReq_Rx: USART DMA receive request  * @param  NewState: new state of the DMA Request sources.  *   This parameter can be: ENABLE or DISABLE.  * @note The DMA mode is not available for UART5 except in the STM32  *       High density value line devices(STM32F10X_HD_VL).    * @retval None  */void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState){  /* Check the parameters */  assert_param(IS_USART_ALL_PERIPH(USARTx));  assert_param(IS_USART_DMAREQ(USART_DMAReq));    assert_param(IS_FUNCTIONAL_STATE(NewState));   if (NewState != DISABLE)  {    /* Enable the DMA transfer for selected requests by setting the DMAT and/or       DMAR bits in the USART CR3 register */    USARTx->CR3 |= USART_DMAReq;  }  else  {    /* Disable the DMA transfer for selected requests by clearing the DMAT and/or       DMAR bits in the USART CR3 register */    USARTx->CR3 &= (uint16_t)~USART_DMAReq;  }}
0 0