打印

DMAMUX的Request Generator功能适合操作总线接口的外设,特别是ADC,是否适合高速AD,待测试

[复制链接]
382|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
菊江先生|  楼主 | 2018-8-10 16:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
例子:DMAMUX_RequestGen



DMXMUX的Request Generator触发源可以选择外部中断,也可以选择定时器或者其他触发源,这样用户就可以通过定时器触发控制DMA的传输速度。将FMC总线外挂的高速ADC传输数据到内部SRAM做缓冲

例子DMAMUX_RequestGen的配置参考:
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO   uint32_t DMA_TransferErrorFlag = 0;

#if defined ( __ICCARM__ )
#pragma location = 0x38000000
uint32_t SRC_Buffer_LED1_Toggle[2]  =
                                      {  0,          /*Value for LED 1 ON  */
                                         LED1_PIN    /*Value for LED 1 OFF */  
                                      };
#elif defined ( __CC_ARM )
__attribute__((section (".RAM_D3"))) uint32_t SRC_Buffer_LED1_Toggle[2] =
                                      {  0,          /*Value for LED 1 ON  */
                                         LED1_PIN    /*Value for LED 1 OFF */  
                                      };
#elif defined ( __GNUC__ )
uint32_t __attribute__((section (".RAM_D3"))) SRC_Buffer_LED1_Toggle[2]  =
                                      {  0,          /*Value for LED 1 ON  */
                                         LED1_PIN    /*Value for LED 1 OFF */  
                                      };
#endif


DMA_HandleTypeDef DMA_Handle;
LPTIM_HandleTypeDef  LptimHandle;

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void CPU_CACHE_Enable(void);
void LPTIM_Config(void);
static void HAL_TransferError(DMA_HandleTypeDef *hdma);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  
  HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams;
  
  /* Enable the CPU Cache */
  CPU_CACHE_Enable();
  
  /* STM32H7xx HAL library initialization:
     - Systick timer is configured by default as source of time base, but user
       can eventually implement his proper time base source (a general purpose
       timer for example or other time source), keeping in mind that Time base
       duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
       handled in milliseconds basis.
     - Set NVIC Group Priority to 4
     - Low Level Initialization
  */
  HAL_Init();
  
  /* Configure the system clock to 400 MHz */
  SystemClock_Config();
  
  /* -1- Initialize LEDs mounted on STM32H743ZI-NUCLEO board */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED3);
  

  /*##-2- Configure the DMA ##################################################*/
  
  /* Enable BDMA clock */
  __HAL_RCC_BDMA_CLK_ENABLE();
  
  /* Configure the DMA handler for Transmission process     */
  /* DMA mode is set to circual for an infinit DMA transfer */  
  DMA_Handle.Instance                 = BDMA_Channel0;
  
  DMA_Handle.Init.Request             = BDMA_REQUEST_GENERATOR0;  
  DMA_Handle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
  DMA_Handle.Init.PeriphInc           = DMA_PINC_DISABLE;
  DMA_Handle.Init.MemInc              = DMA_MINC_ENABLE;
  DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  DMA_Handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  DMA_Handle.Init.Mode                = DMA_CIRCULAR;
  DMA_Handle.Init.Priority            = DMA_PRIORITY_LOW;
  DMA_Handle.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  DMA_Handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  DMA_Handle.Init.MemBurst            = DMA_MBURST_SINGLE;
  DMA_Handle.Init.PeriphBurst         = DMA_PBURST_SINGLE;
  
  DMA_Handle.XferCpltCallback         = NULL;
  DMA_Handle.XferErrorCallback        = HAL_TransferError;
  
  /* Initialize the DMA with for Transmission process */
  HAL_DMA_Init(&DMA_Handle);
  
  /* NVIC configuration for DMA transfer complete interrupt*/
  HAL_NVIC_SetPriority(BDMA_Channel0_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(BDMA_Channel0_IRQn);
  
  /*##-3- Configure and enable the DMAMUX Request generator  ####################*/
  dmamux_ReqGenParams.SignalID  = HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT; /* External request signal is LPTIM2 signal */
  dmamux_ReqGenParams.Polarity  = HAL_DMAMUX_REQ_GEN_RISING;      /* External request signal edge is Rising  */
  dmamux_ReqGenParams.RequestNumber = 1;                          /* 1 requests on each edge of the external request signal  */
  
  HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle, &dmamux_ReqGenParams);
  
  /* NVIC configuration for DMAMUX request generator overrun errors*/
  HAL_NVIC_SetPriority(DMAMUX2_OVR_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(DMAMUX2_OVR_IRQn);
  
  HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handle);
  
  /*##-4- Configure and enable the LPTIM2 used as DMA external request generator signal #####*/
  LPTIM_Config();
  
  /*##-5- Start the DMA transfer ################################################*/
  /* DMA source buffer is  SRC_BUFFER_LED1_TOGGLE containing values to be written
  to GPIOB ODR register in order to turn LED1 On/Off each time comes a request from the DMAMUX request generator */  
  HAL_DMA_Start(&DMA_Handle, (uint32_t)SRC_Buffer_LED1_Toggle, (uint32_t)&GPIOB->ODR, 2);
  
  /* Infinite loop */
  while (1)
  {
    if(DMA_TransferErrorFlag != 0)
    {
      Error_Handler();      
    }
  }
}

/**
  * @brief  Configure and start the LPTIM2 with 2sec period and 50% duty cycle.
  * @param  None
  * @retval None
  */
void LPTIM_Config(void)
{

  uint32_t periodValue;
  uint32_t pulseValue ;
  
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
  
  /* Enable the LSE clock source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
  
  /* LPTIM2 clock source set to LSE*/
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM2;
  PeriphClkInitStruct.Lptim2ClockSelection = RCC_LPTIM2CLKSOURCE_LSE;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);  

  periodValue = (2 * LSE_VALUE)/40;    /* Calculate the Timer  Autoreload value for 2sec period */
  pulseValue  = periodValue/2;        /* Set the Timer  pulse value for 50% duty cycle         */
  
  /* TIM1 Peripheral clock enable */
  __HAL_RCC_LPTIM2_CLK_ENABLE();
  
  LptimHandle.Instance                           = LPTIM2;

  LptimHandle.Init.CounterSource                 = LPTIM_COUNTERSOURCE_INTERNAL;
  LptimHandle.Init.UpdateMode                    = LPTIM_UPDATE_ENDOFPERIOD;
  LptimHandle.Init.OutputPolarity                = LPTIM_OUTPUTPOLARITY_LOW;
  LptimHandle.Init.Clock.Source                  = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  LptimHandle.Init.Clock.Prescaler               = LPTIM_PRESCALER_DIV4;
  LptimHandle.Init.UltraLowPowerClock.Polarity   = LPTIM_CLOCKPOLARITY_RISING;
  LptimHandle.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
  LptimHandle.Init.Trigger.Source                = LPTIM_TRIGSOURCE_SOFTWARE;
  LptimHandle.Init.Trigger.ActiveEdge            = LPTIM_ACTIVEEDGE_RISING;
  LptimHandle.Init.Trigger.SampleTime            = LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION;

  if(HAL_LPTIM_Init(&LptimHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
  
  /* Start the timer */
  if (HAL_LPTIM_PWM_Start(&LptimHandle, periodValue, pulseValue) != HAL_OK)
  {
    Error_Handler();
  }  
  
}

static void HAL_TransferError(DMA_HandleTypeDef *hdma)
{
  DMA_TransferErrorFlag = 1;
}

使用特权

评论回复

相关帖子

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

本版积分规则

446

主题

447

帖子

0

粉丝