例子: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;
} |