|
@@ -0,0 +1,173 @@
|
|
|
+/* 包含头文件-----------------------------------------------------------------*/
|
|
|
+#include "pwm_dma.h"
|
|
|
+
|
|
|
+/* 私有宏定义-----------------------------------------------------------------*/
|
|
|
+/* 定时器2的PWM DMA使能 1:通道1-PA0 2:通道2-PA1 3:通道3-PA2 4:通道4-PA3 */
|
|
|
+#define TIM2_PWM_DMA_EN (1)
|
|
|
+
|
|
|
+#if (1 == TIM2_PWM_DMA_EN)
|
|
|
+#define TIM_DMA_CH (DMA1_Channel5)
|
|
|
+#define TIM_CCR_ADDR (TIM2->CCR1)
|
|
|
+#define DMA_IRQ_FUN (DMA1_Channel5_IRQHandler)
|
|
|
+#define DMA_IRQ_FLAG (DMA1_IT_TC5)
|
|
|
+#elif (2 == TIM2_PWM_DMA_EN)
|
|
|
+#define TIM_DMA_CH (DMA1_Channel7)
|
|
|
+#define TIM_CCR_ADDR (TIM2->CCR2)
|
|
|
+#define DMA_IRQ_FUN (DMA1_Channel7_IRQHandler)
|
|
|
+#define DMA_IRQ_FLAG (DMA1_IT_TC7)
|
|
|
+#elif (3 == TIM2_PWM_DMA_EN)
|
|
|
+#define TIM_DMA_CH (DMA1_Channel1)
|
|
|
+#define TIM_CCR_ADDR (TIM2->CCR3)
|
|
|
+#define DMA_IRQ_FUN (DMA1_Channel1_IRQHandler)
|
|
|
+#define DMA_IRQ_FLAG (DMA1_IT_TC1)
|
|
|
+#elif (4 == TIM2_PWM_DMA_EN)
|
|
|
+#define TIM_DMA_CH (DMA1_Channel7)
|
|
|
+#define TIM_CCR_ADDR (TIM2->CCR4)
|
|
|
+#define DMA_IRQ_FUN (DMA1_Channel7_IRQHandler)
|
|
|
+#define DMA_IRQ_FLAG (DMA1_IT_TC7)
|
|
|
+#endif
|
|
|
+
|
|
|
+/* 私有类型定义---------------------------------------------------------------*/
|
|
|
+
|
|
|
+/* 私有变量-------------------------------------------------------------------*/
|
|
|
+
|
|
|
+/* 全局变量-------------------------------------------------------------------*/
|
|
|
+
|
|
|
+/* 私有函数原型---------------------------------------------------------------*/
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief pwm初始化
|
|
|
+ * @param arr : 重装值
|
|
|
+ * @param psc : 预分频数
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+static void pwm_config(uint16_t arr, uint16_t psc)
|
|
|
+{
|
|
|
+ GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
|
|
+ TIM_OCInitTypeDef TIM_OCInitStructure;
|
|
|
+
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); /* 使能GPIO外设时钟使能 */
|
|
|
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* 开启定时器时钟 */
|
|
|
+
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+#if (1 == TIM2_PWM_DMA_EN)
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
|
|
+#elif (2 == TIM2_PWM_DMA_EN)
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
|
|
|
+#elif (3 == TIM2_PWM_DMA_EN)
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
|
|
+#elif (4 == TIM2_PWM_DMA_EN)
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
|
|
|
+#endif
|
|
|
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
|
+
|
|
|
+ TIM_DeInit(TIM2);
|
|
|
+
|
|
|
+ TIM_TimeBaseStructure.TIM_Period = arr - 1; /* 自动重装载值 */
|
|
|
+ TIM_TimeBaseStructure.TIM_Prescaler = psc - 1; /* 时钟预分频数 */
|
|
|
+ TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; /* 时钟分频系数 1分频 */
|
|
|
+ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /* 计数模式 向上计数 */
|
|
|
+ TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* 初始化定时器 */
|
|
|
+
|
|
|
+ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; /* PWM模式1 */
|
|
|
+ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; /* 输出使能 */
|
|
|
+ TIM_OCInitStructure.TIM_Pulse = 0; /* 比较值 */
|
|
|
+ TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; /* 输出极性高 */
|
|
|
+ TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; /* 空闲状态为低 */
|
|
|
+ TIM_OC1Init(TIM2, &TIM_OCInitStructure); /* 初始化比较输出 */
|
|
|
+ TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); /* OC预装载使能 */
|
|
|
+
|
|
|
+ TIM_Cmd(TIM2, DISABLE); /* 开启定时器 */
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief DMA初始化
|
|
|
+ * @param memory : 内存基地址
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+static void dma_config(void *memory)
|
|
|
+{
|
|
|
+ DMA_InitTypeDef DMA_InitStructure;
|
|
|
+
|
|
|
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* 打开DMA时钟 */
|
|
|
+
|
|
|
+ DMA_DeInit(TIM_DMA_CH);
|
|
|
+ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM_CCR_ADDR; /* 外设基地址 */
|
|
|
+ DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)memory; /* 内存基地址 */
|
|
|
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; /* 数据方向 外设作为目标源 */
|
|
|
+ DMA_InitStructure.DMA_BufferSize = 0; /* 数据数量 */
|
|
|
+ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设基地址不递增 */
|
|
|
+ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存基地址递增 */
|
|
|
+ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; /* 外设数据大小为字节 2byte */
|
|
|
+ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; /* 内存数据大小为字节 2byte */
|
|
|
+ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 传输模式 单次传输 */
|
|
|
+ DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* DMA优先级 高 */
|
|
|
+ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; /* 内存到内存禁用 */
|
|
|
+ DMA_Init(TIM_DMA_CH, &DMA_InitStructure); /* 初始化DMA */
|
|
|
+
|
|
|
+ DMA_ITConfig(TIM_DMA_CH, DMA_IT_TC, ENABLE); /* 开启传输完成中断 */
|
|
|
+ DMA_Cmd(TIM_DMA_CH, DISABLE); /* 开启DMA */
|
|
|
+
|
|
|
+#if (1 == TIM2_PWM_DMA_EN)
|
|
|
+ TIM_DMACmd(TIM2, TIM_DMA_CC1, ENABLE); /* 开启对应通道DMA */
|
|
|
+#elif (2 == TIM2_PWM_DMA_EN)
|
|
|
+ TIM_DMACmd(TIM2, TIM_DMA_CC2, ENABLE); /* 开启对应通道DMA */
|
|
|
+#elif (3 == TIM2_PWM_DMA_EN)
|
|
|
+ TIM_DMACmd(TIM2, TIM_DMA_CC3, ENABLE); /* 开启对应通道DMA */
|
|
|
+#elif (4 == TIM2_PWM_DMA_EN)
|
|
|
+ TIM_DMACmd(TIM2, TIM_DMA_CC4, ENABLE); /* 开启对应通道DMA */
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief DMA中断函数
|
|
|
+ * @param None
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+void DMA_IRQ_FUN(void)
|
|
|
+{
|
|
|
+ if(DMA_GetITStatus(DMA_IRQ_FLAG) != RESET)
|
|
|
+ {
|
|
|
+ pwm_dma_stop();
|
|
|
+
|
|
|
+ DMA_ClearITPendingBit(DMA_IRQ_FLAG);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief PWM DMA初始化
|
|
|
+ * @param arr : 定时器重装值
|
|
|
+ * @param psc : 定时器预分频数
|
|
|
+ * @param memory : DMA内存基地址
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+void pwm_dma_config(uint16_t arr, uint16_t psc, void *memory)
|
|
|
+{
|
|
|
+ pwm_config(arr, psc);
|
|
|
+ dma_config(memory);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief PWM DMA传输启动
|
|
|
+ * @param size : 传输数量
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+void pwm_dma_start(uint16_t size)
|
|
|
+{
|
|
|
+ DMA_SetCurrDataCounter(TIM_DMA_CH, size);
|
|
|
+ DMA_Cmd(TIM_DMA_CH, ENABLE);
|
|
|
+ TIM_Cmd(TIM2, ENABLE);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief PWM DMA传输停止
|
|
|
+ * @param None
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+void pwm_dma_stop(void)
|
|
|
+{
|
|
|
+ DMA_Cmd(TIM_DMA_CH, DISABLE);
|
|
|
+ TIM_Cmd(TIM2, DISABLE);
|
|
|
+}
|