Files
CHJ/user/MCU/lhl_dma.c
2026-03-20 21:19:53 +08:00

124 lines
4.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "../main/SystemInclude.h"
/**------------------------------------------------------------------------
* @brief 配置 DMAMUXDMA 多路复用器)
* @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);
}