这里使用ADC1联动DMA1, 开启半传输中断、传输中断。debug时,dma也一直在工作,所以半传输中断、传输中断会同时生效。
1. adc1使用了DMA1_Stream0,Instance表示如下
一个DMA数据流中断标志占6个bit(在DMA_LISR)。Stream0 :hdma->StreamIndex=0,Stream1:hdma->StreamIndex=6
DMA_Base_Registers *regs_dma = (DMA_Base_Registers *)hdma->StreamBaseAddress;
tmpisr_dma = regs_dma->ISR;
tmpisr_dma表示
(hdma->StreamIndex & 0x1FU) 保证在0~31之间。
DMA_FLAG_TEIF0_4 ((uint32_t)0x00000008U)
2. 代码
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
uint32_t tmpisr_dma, tmpisr_bdma;
uint32_t ccr_reg;
__IO uint32_t count = 0U;
uint32_t timeout = SystemCoreClock / 9600U;
DMA_Base_Registers *regs_dma = (DMA_Base_Registers *)hdma->StreamBaseAddress;
BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
tmpisr_dma = regs_dma->ISR;
tmpisr_bdma = regs_bdma->ISR;
if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)
{
if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != 0U)
{
((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_TE);
regs_dma->IFCR = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
hdma->ErrorCode |= HAL_DMA_ERROR_TE;
}
}
if ((tmpisr_dma & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != 0U)
{
regs_dma->IFCR = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
hdma->ErrorCode |= HAL_DMA_ERROR_FE;
}
}
if ((tmpisr_dma & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != 0U)
{
regs_dma->IFCR = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
hdma->ErrorCode |= HAL_DMA_ERROR_DME;
}
}
if ((tmpisr_dma & (DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
{
regs_dma->IFCR = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
{
if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
{
if(hdma->XferHalfCpltCallback != NULL)
{
hdma->XferHalfCpltCallback(hdma);
}
}
else
{
if(hdma->XferM1HalfCpltCallback != NULL)
{
hdma->XferM1HalfCpltCallback(hdma);
}
}
}
else
{
if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
{
((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_HT);
}
if(hdma->XferHalfCpltCallback != NULL)
{
hdma->XferHalfCpltCallback(hdma);
}
}
}
}
if ((tmpisr_dma & (DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
{
regs_dma->IFCR = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
if(HAL_DMA_STATE_ABORT == hdma->State)
{
((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
((DMA_Stream_TypeDef *)hdma->Instance)->FCR &= ~(DMA_IT_FE);
if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
{
((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_HT);
}
regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
__HAL_UNLOCK(hdma);
hdma->State = HAL_DMA_STATE_READY;
if(hdma->XferAbortCallback != NULL)
{
hdma->XferAbortCallback(hdma);
}
return;
}
if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
{
if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
{
if(hdma->XferM1CpltCallback != NULL)
{
hdma->XferM1CpltCallback(hdma);
}
}
else
{
if(hdma->XferCpltCallback != NULL)
{
hdma->XferCpltCallback(hdma);
}
}
}
else
{
if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
{
((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_TC);
__HAL_UNLOCK(hdma);
hdma->State = HAL_DMA_STATE_READY;
}
if(hdma->XferCpltCallback != NULL)
{
hdma->XferCpltCallback(hdma);
}
}
}
}
if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
{
if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != 0U)
{
hdma->State = HAL_DMA_STATE_ABORT;
__HAL_DMA_DISABLE(hdma);
do
{
if (++count > timeout)
{
break;
}
}
while((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U);
__HAL_UNLOCK(hdma);
if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
{
hdma->State = HAL_DMA_STATE_ERROR;
}
else
{
hdma->State = HAL_DMA_STATE_READY;
}
}
if(hdma->XferErrorCallback != NULL)
{
hdma->XferErrorCallback(hdma);
}
}
}
else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U)
{
ccr_reg = (((BDMA_Channel_TypeDef *)hdma->Instance)->CCR);
if (((tmpisr_bdma & (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_HTIE) != 0U))
{
regs_bdma->IFCR = (BDMA_ISR_HTIF0 << (hdma->StreamIndex & 0x1FU));
if((ccr_reg & BDMA_CCR_DBM) != 0U)
{
if((ccr_reg & BDMA_CCR_CT) == 0U)
{
if(hdma->XferM1HalfCpltCallback != NULL)
{
hdma->XferM1HalfCpltCallback(hdma);
}
}
else
{
if(hdma->XferHalfCpltCallback != NULL)
{
hdma->XferHalfCpltCallback(hdma);
}
}
}
else
{
if((ccr_reg & BDMA_CCR_CIRC) == 0U)
{
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
}
if(hdma->XferHalfCpltCallback != NULL)
{
hdma->XferHalfCpltCallback(hdma);
}
}
}
else if (((tmpisr_bdma & (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TCIE) != 0U))
{
regs_bdma->IFCR = (BDMA_ISR_TCIF0) << (hdma->StreamIndex & 0x1FU);
if((ccr_reg & BDMA_CCR_DBM) != 0U)
{
if((ccr_reg & BDMA_CCR_CT) == 0U)
{
if(hdma->XferM1CpltCallback != NULL)
{
hdma->XferM1CpltCallback(hdma);
}
}
else
{
if(hdma->XferCpltCallback != NULL)
{
hdma->XferCpltCallback(hdma);
}
}
}
else
{
if((ccr_reg & BDMA_CCR_CIRC) == 0U)
{
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
__HAL_UNLOCK(hdma);
hdma->State = HAL_DMA_STATE_READY;
}
if(hdma->XferCpltCallback != NULL)
{
hdma->XferCpltCallback(hdma);
}
}
}
else if (((tmpisr_bdma & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TEIE) != 0U))
{
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
hdma->ErrorCode = HAL_DMA_ERROR_TE;
__HAL_UNLOCK(hdma);
hdma->State = HAL_DMA_STATE_READY;
if (hdma->XferErrorCallback != NULL)
{
hdma->XferErrorCallback(hdma);
}
}
else
{
}
}
else
{
}
}
void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
{
ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
if ((hadc->State & (HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) == 0UL)
{
SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
if ((hadc->Instance->ISR & ADC_FLAG_EOS) != 0UL)
{
if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
{
if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_CONT) == 0UL)
{
CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
{
SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
}
}
else
{
if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMNGT) == 0UL)
{
CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
{
SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
}
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->ConvCpltCallback(hadc);
#else
HAL_ADC_ConvCpltCallback(hadc);
#endif
}
else
{
if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) != 0UL)
{
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->ErrorCallback(hadc);
#else
HAL_ADC_ErrorCallback(hadc);
#endif
}
else
{
hadc->DMA_Handle->XferErrorCallback(hdma);
}
}
static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
{
if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)
{
uint32_t stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U};
hdma->StreamIndex = flagBitshiftOffset[stream_number & 0x7U];
if (stream_number > 3U)
{
hdma->StreamBaseAddress = (((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU)) + 4U);
}
else
{
hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU));
}
}
else
{
hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0xFFU));
}
return hdma->StreamBaseAddress;
}
}
3. HAL_ADC_Start_DMA 中 DMA模式下ADC溢出中断强制使能
/* With DMA, overrun event is always considered as an error even if
hadc->Init.Overrun is set to ADC_OVR_DATA_OVERWRITTEN. Therefore,
ADC_IT_OVR is enabled. */
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); //原来是0,现在打开,DMA模式下ADC溢出中断强制使能
LL_ADC_REG_SetDataTransferMode(hadc->Instance, (uint32_t)hadc->Init.ConversionDataManagement);
4. 代码
void ADC_DMAError(DMA_HandleTypeDef *hdma)
{
ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA);
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->ErrorCallback(hadc);
#else
HAL_ADC_ErrorCallback(hadc);
#endif
}
void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
{
ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
if ((hadc->State & (HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) == 0UL)
{
SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
if ((hadc->Instance->ISR & ADC_FLAG_EOS) != 0UL)
{
if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
{
if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_CONT) == 0UL)
{
CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
{
SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
}
}
else
{
if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMNGT) == 0UL)
{
CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
{
SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
}
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->ConvCpltCallback(hadc);
#else
HAL_ADC_ConvCpltCallback(hadc);
#endif
}
else
{
if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) != 0UL)
{
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->ErrorCallback(hadc);
#else
HAL_ADC_ErrorCallback(hadc);
#endif
}
else
{
hadc->DMA_Handle->XferErrorCallback(hdma);
}
}
}
}
void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
{
ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->ConvHalfCpltCallback(hadc);
#else
HAL_ADC_ConvHalfCpltCallback(hadc);
#endif
}
__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
{
UNUSED(hadc);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)