感谢 Tesla DeLorean 提供的有用信息。我意识到我应该提出一些信号表来解释我所追求的。
总结我的问题和解决方案:
- 我一直在努力理解循环(循环模式)是如何通过 HAL API 处理的。我错过的最重要的部分是 HAL_DMA_Start_IT(Channel, Output, Input, **DATALENGTH**); 说的是输出位置的大小,直接塞到DMA的NDTR寄存器中。
- EXTI 中断触发的循环模式意味着每次中断将读取“PeriphDataAlignment”“dmamux_ReqGenParams.RequestNumber”次。我在这里错过的再次与第 1 点有关,数据长度(又名 NDTR)控制 DMA 输出点周围的扭曲。我最初认为它是由“dmamux_ReqGenParams.RequestNumber”控制的。
修复:
- 将数据长度更改为 2,因为我只希望在读取 2 个值时完成中断。我不需要中途中断。
- 将 request to back 设置为 1。因为每个边沿只需要触发 1 次读取。
- 回到单个缓冲区,因为我有足够的时间使用 sram 中的值。
这是当前工作的 init 和一张解释为 portA 收集的数据的图片
- int InitializeDmaChannels(void)
- {
- HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams = {0};
-
- /*##-2- Configure the DMA ##################################################*/
- /* Enable BDMA clock */
- __HAL_RCC_BDMA_CLK_ENABLE();
-
- { // Channel 0 init.
- /* Configure the DMA handler for Transmission process */
- /* DMA mode is set to circular for an infinite DMA transfer */
- DMA_Handle_Channel0.Instance = BDMA_Channel0;
- DMA_Handle_Channel0.Init.Request = BDMA_REQUEST_GENERATOR0;
- DMA_Handle_Channel0.Init.Direction = DMA_PERIPH_TO_MEMORY;
- DMA_Handle_Channel0.Init.PeriphInc = DMA_PINC_DISABLE;
- DMA_Handle_Channel0.Init.MemInc = DMA_MINC_ENABLE;
- DMA_Handle_Channel0.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
- DMA_Handle_Channel0.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;
- DMA_Handle_Channel0.Init.Mode = DMA_CIRCULAR;
- DMA_Handle_Channel0.Init.Priority = DMA_PRIORITY_VERY_HIGH;
- DMA_Handle_Channel0.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
- DMA_Handle_Channel0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
- DMA_Handle_Channel0.Init.MemBurst = DMA_MBURST_SINGLE;
- DMA_Handle_Channel0.Init.PeriphBurst = DMA_PBURST_SINGLE;
-
- /* Initialize the DMA with for Transmission process */
- HAL_StatusTypeDef dmares = HAL_OK;
- dmares = HAL_DMA_Init(&DMA_Handle_Channel0);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- /* Select Callbacks functions called after Transfer complete and Transfer error */
- dmares = HAL_DMA_RegisterCallback(&DMA_Handle_Channel0, HAL_DMA_XFER_CPLT_CB_ID, NULL);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- dmares = HAL_DMA_RegisterCallback(&DMA_Handle_Channel0, HAL_DMA_XFER_ERROR_CB_ID, HAL_TransferError);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- /* NVIC configuration for DMA transfer complete interrupt*/
- HAL_NVIC_SetPriority(BDMA_Channel0_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(BDMA_Channel0_IRQn);
-
- /*##-3- Configure and enable the DMAMUX Request generator ####################*/
- dmamux_ReqGenParams.SignalID = HAL_DMAMUX2_REQ_GEN_EXTI0;
- dmamux_ReqGenParams.Polarity = HAL_DMAMUX_REQ_GEN_RISING_FALLING;
- dmamux_ReqGenParams.RequestNumber = 1; /* 1 requests on each edge of the external request signal */
-
- dmares = HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle_Channel0, &dmamux_ReqGenParams);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- /* NVIC configuration for DMAMUX request generator overrun errors*/
- HAL_NVIC_SetPriority(DMAMUX2_OVR_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(DMAMUX2_OVR_IRQn);
-
- dmares = HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handle_Channel0);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- dmares = HAL_DMA_Start_IT(&DMA_Handle_Channel0, (uint32_t)&(GPIOB->IDR), (uint32_t)(PortBBuffer), 2);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
- }
-
- { // Channel 1 init.
- /* Configure the DMA handler for Transmission process */
- /* DMA mode is set to circular for an infinite DMA transfer */
- DMA_Handle_Channel1.Instance = BDMA_Channel1;
- DMA_Handle_Channel1.Init.Request = BDMA_REQUEST_GENERATOR0;
- DMA_Handle_Channel1.Init.Direction = DMA_PERIPH_TO_MEMORY;
- DMA_Handle_Channel1.Init.PeriphInc = DMA_PINC_DISABLE;
- DMA_Handle_Channel1.Init.MemInc = DMA_MINC_ENABLE;
- DMA_Handle_Channel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
- DMA_Handle_Channel1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
- DMA_Handle_Channel1.Init.Mode = DMA_CIRCULAR;
- DMA_Handle_Channel1.Init.Priority = DMA_PRIORITY_VERY_HIGH;
- DMA_Handle_Channel1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
- DMA_Handle_Channel1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
- DMA_Handle_Channel1.Init.MemBurst = DMA_MBURST_SINGLE;
- DMA_Handle_Channel1.Init.PeriphBurst = DMA_PBURST_SINGLE;
-
- /* Initialize the DMA with for Transmission process */
- HAL_StatusTypeDef dmares = HAL_OK;
- dmares = HAL_DMA_Init(&DMA_Handle_Channel1);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- /* Select Callbacks functions called after Transfer complete and Transfer error */
- dmares = HAL_DMA_RegisterCallback(&DMA_Handle_Channel1, HAL_DMA_XFER_CPLT_CB_ID, NULL);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
- dmares = HAL_DMA_RegisterCallback(&DMA_Handle_Channel1, HAL_DMA_XFER_ERROR_CB_ID, HAL_TransferError);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- /* NVIC configuration for DMA transfer complete interrupt*/
- HAL_NVIC_SetPriority(BDMA_Channel1_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(BDMA_Channel1_IRQn);
-
- /*##-3- Configure and enable the DMAMUX Request generator ####################*/
- dmamux_ReqGenParams.SignalID = HAL_DMAMUX2_REQ_GEN_EXTI0;
- dmamux_ReqGenParams.Polarity = HAL_DMAMUX_REQ_GEN_RISING_FALLING;
- dmamux_ReqGenParams.RequestNumber = 1;
-
- dmares = HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle_Channel1, &dmamux_ReqGenParams);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- /* NVIC configuration for DMAMUX request generator overrun errors*/
- HAL_NVIC_SetPriority(DMAMUX2_OVR_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(DMAMUX2_OVR_IRQn);
-
- dmares = HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handle_Channel1);
- if (dmares != HAL_OK) {
- Error_Handler();
- }
-
- volatile uint32_t dmares1 = HAL_DMA_Start_IT(&DMA_Handle_Channel1, (uint32_t)&(GPIOA->IDR), (uint32_t)(PortABuffer), 2);
- if (dmares1 != HAL_OK) {
- Error_Handler();
- }
- }
-
- return 0;
- }
|
|
2022-12-6 11:30:05
评论
举报
|
|
|