#include "../main/SystemInclude.h" /**------------------------------------------------------------------------ * @brief 配置 DMAMUX(DMA 多路复用器) * @param channel: DMA 通道号,如 DMA_CHANNEL_0 * @param source: 请求源,如 REQUEST_SOURCE_ADC0 * @note 该函数将指定 DMA 通道与硬件请求源连接,并使能 DMAMUX 通道。 * 周期性触发(Periodic_Trigger)默认禁用。 * @example DMA_DMAMUX_CFG(DMA_CHANNEL_0, REQUEST_SOURCE_ADC0); **/ void DMA_DMAMUX_CFG(DMA_CHANNEL_t channel,DMAMUX_REQ_SRC_t source) { DMAMUX_InitTypeDef DMAMUX_InitStructure; DMAMUX_InitStructure.DMA_Channel = channel; DMAMUX_InitStructure.Request_Source = source; DMAMUX_InitStructure.Periodic_Trigger = DISABLE; DMAMUX_InitStructure.Cmd = ENABLE; LHL_DMAMUX_Init(&DMAMUX_InitStructure); } /*-===================================================================================================== //DMA中断回调 -=====================================================================================================*/ static dma_callbacks_t dma_callbacks[4] = {NULL}; /**------------------------------------------------------------------------ * @brief 注册 DMA 通道的中断回调函数 * @param dmachannel: DMA 通道号,如 DMA_CHANNEL_0 * @param dma_half_irq_callback: 半传输完成回调函数指针(可为 NULL) * @param dma_major_irq_callback: 主传输完成回调函数指针(可为 NULL) * @note 根据通道号自动使能对应的 NVIC 中断: * - CH0 使能 DMA1_CH0_IRQn * - CH1 使能 DMA1_CH1_IRQn * - CH2/CH3 使能 DMA1_CH2_CH3_IRQn * @example DMA_register_irq_callback(DMA_CHANNEL_0, my_half_cb, my_major_cb); **/ void DMA_register_irq_callback(DMA_CHANNEL_t dmachannel, dma_half_irq_callback_t dma_half_irq_callback ,dma_major_irq_callback_t dma_major_irq_callback) { dma_callbacks[dmachannel].half_callback = dma_half_irq_callback; dma_callbacks[dmachannel].major_callback = dma_major_irq_callback; switch (dmachannel) { //获取 EXTI 线对应的 IRQ 号 case DMA_CHANNEL_0: NVIC_EnableIRQ(DMA1_CH0_IRQn); break; case DMA_CHANNEL_1: NVIC_EnableIRQ(DMA1_CH1_IRQn); break; case DMA_CHANNEL_2: case DMA_CHANNEL_3: NVIC_EnableIRQ(DMA1_CH2_CH3_IRQn); break; default: break; // 不支持的通道 } } /**------------------------------------------------------------------------ * @brief DMA1 通道 0 中断服务函数 * @note 判断中断类型(半传输/主传输完成),调用对应回调函数(若已注册)。 * 最后清除通道 0 的中断标志。 **/ void DMA1_CH0_IRQHandler(void) { if(LHL_DMA_GetPending(DMA_CHANNEL_0) == DMA_IT_HALF) { if(dma_callbacks[DMA_CHANNEL_0].half_callback != NULL) { dma_callbacks[DMA_CHANNEL_0].half_callback(); } } else if(LHL_DMA_GetPending(DMA_CHANNEL_0) == DMA_IT_MAJOR) { if(dma_callbacks[DMA_CHANNEL_0].major_callback != NULL) { dma_callbacks[DMA_CHANNEL_0].major_callback(); } } LHL_DMA_ClearPending(DMA_CHANNEL_0); } /**------------------------------------------------------------------------ * @brief DMA1 通道 1 中断服务函数 * @note 判断中断类型(半传输/主传输完成),调用对应回调函数(若已注册)。 * 最后清除通道 1 的中断标志。 **/ void DMA1_CH1_IRQHandler(void)// { if(LHL_DMA_GetPending(DMA_CHANNEL_1) == DMA_IT_HALF) { if(dma_callbacks[DMA_CHANNEL_1].half_callback != NULL) { dma_callbacks[DMA_CHANNEL_1].half_callback(); } } else if(LHL_DMA_GetPending(DMA_CHANNEL_1) == DMA_IT_MAJOR) { if(dma_callbacks[DMA_CHANNEL_1].major_callback != NULL) { dma_callbacks[DMA_CHANNEL_1].major_callback(); } } LHL_DMA_ClearPending(DMA_CHANNEL_1); } /**------------------------------------------------------------------------ * @brief DMA1 通道 2 和 3 共享中断服务函数 * @note 分别检查通道 2 和通道 3 的中断标志,判断中断类型, * 并调用对应通道已注册的回调函数。最后清除两个通道的中断标志。 **/ void DMA1_CH2_3_IRQHandler(void) { if(LHL_DMA_GetPending(DMA_CHANNEL_2) == DMA_IT_HALF) { if(dma_callbacks[DMA_CHANNEL_2].half_callback != NULL) { dma_callbacks[DMA_CHANNEL_2].half_callback(); } } else if(LHL_DMA_GetPending(DMA_CHANNEL_2) == DMA_IT_MAJOR) { if(dma_callbacks[DMA_CHANNEL_2].major_callback != NULL) { dma_callbacks[DMA_CHANNEL_2].major_callback(); } } if(LHL_DMA_GetPending(DMA_CHANNEL_3) == DMA_IT_HALF) { if(dma_callbacks[DMA_CHANNEL_3].half_callback != NULL) { dma_callbacks[DMA_CHANNEL_3].half_callback(); } } else if(LHL_DMA_GetPending(DMA_CHANNEL_3) == DMA_IT_MAJOR) { if(dma_callbacks[DMA_CHANNEL_3].major_callback != NULL) { dma_callbacks[DMA_CHANNEL_3].major_callback(); } } LHL_DMA_ClearPending(DMA_CHANNEL_2); LHL_DMA_ClearPending(DMA_CHANNEL_3); }