本帖最后由 slotg 于 2019-12-24 08:06 编辑
学习笔记+适用于STM32F0系列的STM32Cube固件例程
DMA_FLASHToRAM
在固件库 Projects\STM32F030R8-Nucleo\Examples\DMA\DMA_FLASHToRAM 里面的这一个例程:
这个例程是将内部 FLASH 的数据使用 DMA 的方式传输到 RAM 内,我直接编译后下载到 STM32F030R8-Nucleo 开发板后运行就看到板载的 LD2 亮起!嗯,发生了什么事?看看 main 回圈:
- int main(void)
- {
- /* STM32F0xx HAL library initialization:
- - Configure the Flash prefetch
- - 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.
- - Low Level Initialization
- */
- HAL_Init();
- /* Configure the system clock to 48 MHz */
- SystemClock_Config();
- /* Initialize LED */
- BSP_LED_Init(LED2);
- /* Set to 1 if an transfer error is detected */
- transferErrorDetected = 0;
- /* Configure and enable the DMA channel for Memory to Memory transfer */
- DMA_Config();
- /* Infinite loop */
- while (1)
- {
- if (transferErrorDetected == 1)
- {
- /* Toggle LED2 with a period of 200 ms */
- BSP_LED_Toggle(LED2);
- HAL_Delay(200);
- }
- }
- }
流程中将 transferErrorDetected 变数设定为 0,在 while (1) 回圈中当 transferErrorDetected 变数为 1 时 LD2 会以 200ms 的周期闪烁。然而在 DMA_Config() 函数里做了那些事情呢?
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] Configure the DMA controller according to the parameters
- * defined in main.h file
- * [url=home.php?mod=space&uid=536309]@NOTE[/url] This function is used to :
- * -1- Enable DMA1 clock
- * -2- Select the DMA functional Parameters
- * -3- Select the DMA instance to be used for the transfer
- * -4- Initialize the DMA channel
- * -5- Select Callbacks functions called after Transfer complete and
- * Transfer error interrupt detection
- * -6- Configure NVIC for DMA transfer complete/error interrupts
- * -7- Start the DMA transfer using the interrupt mode
- * @param None
- * @retval None
- */
- static void DMA_Config(void)
- {
- /*## -1- Enable DMA1 clock #################################################*/
- __HAL_RCC_DMA1_CLK_ENABLE();
- /*##-2- Select the DMA functional Parameters ###############################*/
- DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY; /* M2M transfer mode */
- DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE; /* Peripheral increment mode Enable */
- DmaHandle.Init.MemInc = DMA_MINC_ENABLE; /* Memory increment mode Enable */
- DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; /* Peripheral data alignment : Word */
- DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; /* memory data alignment : Word */
- DmaHandle.Init.Mode = DMA_NORMAL; /* Normal DMA mode */
- DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; /* priority level : high */
- /*##-3- Select the DMA instance to be used for the transfer : DMA1_Channel1 #*/
- DmaHandle.Instance = DMA_INSTANCE;
- /*##-4- Initialize the DMA channel ##########################################*/
- if (HAL_DMA_Init(&DmaHandle) != HAL_OK)
- {
- /* Initialization Error */
- Error_Handler();
- }
-
- /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
- HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, TransferComplete);
- HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_ERROR_CB_ID, TransferError);
- /*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/
- /* Set Interrupt Group Priority */
- HAL_NVIC_SetPriority(DMA_INSTANCE_IRQ, 0, 0);
- /* Enable the DMA global Interrupt */
- HAL_NVIC_EnableIRQ(DMA_INSTANCE_IRQ);
- /*##-7- Start the DMA transfer using the interrupt mode ####################*/
- /* Configure the source, destination and buffer size DMA fields and Start DMA transfer */
- /* Enable All the DMA interrupts */
- if (HAL_DMA_Start_IT(&DmaHandle, (uint32_t)&aSRC_Const_Buffer, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
- {
- /* Transfer Error */
- Error_Handler();
- }
- }
这里以 7 个步骤清楚的说明了 DMA 的设定流程,程式在做好 DMA 的相关设定后将 FLASH 内的数组 aSRC_Const_Buffer[] 传输到 RAM 内的数组 aDST_Buffer[]。程序设定了 2 个回调函数,当传输成功 (HAL_DMA_XFER_CPLT_CB_ID) 时调用 TransferComplete() 函数,传输失败 (HAL_DMA_XFER_ERROR_CB_ID) 时调用 TransferError() 函数。
回调函数 TransferComplete() 内点亮 LD2。
- static void TransferComplete(DMA_HandleTypeDef *DmaHandle)
- {
- /* Turn LED2 on: Transfer correct */
- BSP_LED_On(LED2);
- }
回调函数 TransferError() 内设定 transferErrorDetected 变数为 1,该变数在 main() 主回圈里让 LD2 闪烁。
- static void TransferError(DMA_HandleTypeDef *DmaHandle)
- {
- transferErrorDetected = 1;
- }
所以当程序下载运行后 LD2 也就点亮了起来。
|