124 lines
4.7 KiB
C
124 lines
4.7 KiB
C
#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);
|
||
}
|
||
|
||
|