本文主要是介绍c语言中0x1u是多少,HAL库源文件stm32h7xx_hal_dma_ex.c学习笔记(2018-08-10 V1.1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
自己写了个BDMA双缓冲配置的函数,验证了一下,BDMA双缓冲还是可以用的。手册还是比较靠谱的
。
不想改动官方库,这样以后升级库也方便,以下代码放在单独的文件里。
#define BDMA_CCR_DBM_Pos (15U)
#define BDMA_CCR_DBM_Msk (0x1U << BDMA_CCR_DBM_Pos) /*!< 0x00008000 */
#define BDMA_CCR_DBM BDMA_CCR_DBM_Msk /*!< DBM bits(Double-Buffer Mode)*/
#define BDMA_CCR_CT_Pos (16U)
#define BDMA_CCR_CT_Msk (0x1U << BDMA_CCR_CT_Pos) /*!< 0x00010000 */
#define BDMA_CCR_CT BDMA_CCR_CT_Msk /*!< CT bits(Current Target Memory)*/
HAL_StatusTypeDef HAL_BDMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
{
HAL_StatusTypeDef status = HAL_OK;
__IO uint32_t *ifcRegister_Base = NULL; /* DMA Stream Interrupt Clear register */
/* Check the parameters */
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
/* Memory-to-memory transfer not supported in double buffering mode */
if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
{
hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
return HAL_ERROR;
}
/* Process locked */
__HAL_LOCK(hdma);
if(HAL_DMA_STATE_READY == hdma->State)
{
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_BUSY;
/* Initialize the error code */
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
/* Enable the Double buffer mode */
((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= (uint32_t)BDMA_CCR_DBM;
/* Configure DMA Stream destination address */
*((uint32_t*)(&((BDMA_Channel_TypeDef *)hdma->Instance)->CMAR)+1) = SecondMemAddress;
/* Configure the source, destination address and the data length */
/* Configure DMA Stream data length */
((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength;
/* Peripheral to Memory */
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
{
/* Configure DMA Stream destination address */
((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress;
/* Configure DMA Stream source address */
((BDMA_Channel_TypeDef *)hdma->Instance)->CMAR = SrcAddress;
}
/* Clear all flags */
BDMA->IFCR |= (BDMA_ISR_GIF0 << hdma->StreamIndex);
/* Clear the DMAMUX synchro overrun flag */
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
if(hdma->DMAmuxRequestGen != 0U)
{
/* Clear the DMAMUX request generator overrun flag */
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
}
/* Enable Common interrupts*/
MODIFY_REG(((BDMA_Channel_TypeDef *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE));
if(hdma->XferHalfCpltCallback != NULL)
{
/*Enable Half Transfer IT if corresponding Callback is set*/
((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= BDMA_CCR_HTIE;
}
/* Check if DMAMUX Synchronization is enabled*/
if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0)
{
/* Enable DMAMUX sync overrun IT*/
hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
}
if(hdma->DMAmuxRequestGen != 0U)
{
/* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
/* enable the request gen overrun IT*/
hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
}
/* Enable the peripheral */
__HAL_DMA_ENABLE(hdma);
}
else
{
/* Set the error code to busy */
hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
/* Return error status */
status = HAL_ERROR;
}
return status;
}
另外需要注意的是,官方库的DMA中断处理中,没有针对BDMA双缓冲的处理,但是可以自己在DMA传输完成中断回调中判断当前使用的缓冲区自行处理。
static void HAL_TransferCplt(DMA_HandleTypeDef *hdma)
{
if((((BDMA_Channel_TypeDef *)hdma->Instance)->CCR & BDMA_CCR_CT_Msk) != RESET) {
//...
} else {
//...
}
}
希望可以帮到需要用这个功能的人。
这篇关于c语言中0x1u是多少,HAL库源文件stm32h7xx_hal_dma_ex.c学习笔记(2018-08-10 V1.1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!