Browse Source

新增pwm_dma模板

阿衰0110 11 months ago
parent
commit
475cf0e208
2 changed files with 200 additions and 0 deletions
  1. 173 0
      system_driver_new/pwm_dma.c
  2. 27 0
      system_driver_new/pwm_dma.h

+ 173 - 0
system_driver_new/pwm_dma.c

@@ -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);
+}

+ 27 - 0
system_driver_new/pwm_dma.h

@@ -0,0 +1,27 @@
+#ifndef __PWM_DMA_AS_H
+#define __PWM_DMA_AS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 包含头文件-----------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/* 宏定义---------------------------------------------------------------------*/
+
+/* 类型定义-------------------------------------------------------------------*/
+
+/* 全局变量-------------------------------------------------------------------*/
+
+/* 函数原型-------------------------------------------------------------------*/
+void pwm_dma_config(uint16_t arr, uint16_t psc, void *memory);
+
+void pwm_dma_start(uint16_t size);
+void pwm_dma_stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pwm_dma.h */