⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stm32f10x_svpwm_1shunt.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name          : STM32x_svpwm_1shunt.c
* Author             : IMS Systems Lab
* Date First Issued  : Mar/08
* Description        : 1 shunt resistor current reading module
********************************************************************************
* History:
* 29/05/08 v2.0
* 02/07/08 v2.0.1
* 03/07/08 v2.0.2
* 11/07/08 v2.0.3
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* THIS SOURCE CODE IS PROTECTED BY A LICENSE.
* FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
* IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*******************************************************************************/

#include "STM32F10x_MCconf.h"

#ifdef SINGLE_SHUNT

/* Includes-------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_svpwm_1shunt.h"
#include "MC_Globals.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

#define NB_CONVERSIONS 16

#define SQRT_3		1.732051
#define T		(PWM_PERIOD * 4)
#define T_SQRT3         (u16)(T * SQRT_3)

#define SECTOR_1	(u32)1
#define SECTOR_2	(u32)2
#define SECTOR_3	(u32)3
#define SECTOR_4	(u32)4
#define SECTOR_5	(u32)5
#define SECTOR_6	(u32)6

#define REGULAR         ((u8)0)
#define BOUNDARY_1      ((u8)1)  // Two small, one big
#define BOUNDARY_2      ((u8)2)  // Two big, one small
#define BOUNDARY_3      ((u8)3)  // Three equal

#define PHASE_B_ADC_CHANNEL     ADC_Channel_15	  //B 相电流检测使用AD15通道,PC5脚。

#define ADC_PRE_EMPTION_PRIORITY 1
#define ADC_SUB_PRIORITY 0

#define BRK_PRE_EMPTION_PRIORITY 0
#define BRK_SUB_PRIORITY 0

#define TIM1_UP_PRE_EMPTION_PRIORITY 0
#define TIM1_UP_SUB_PRIORITY 0

#ifdef IR_2101S
#define LOW_SIDE_POLARITY  TIM_OCNIdleState_Reset	   //停车不锁转子,转子可以自由转动
//#define LOW_SIDE_POLARITY  TIM_OCNIdleState_Set	 //停车锁定转子,绕组刹车
#endif
#ifdef IR_2103S
#define LOW_SIDE_POLARITY  TIM_OCNIdleState_Set		   //停车不锁转子,转子可以自由转动
//#define LOW_SIDE_POLARITY  TIM_OCNIdleState_Reset	 //停车锁定转子,绕组刹车
#endif

// Direct address of the registers used by DMA
#define TIM1_CCR1_Address   0x40012C34
#define TIM1_CCR2_Address   0x40012C38
#define TIM1_CCR3_Address   0x40012C3C
#define TIM1_CCR4_Address   0x40012C40
#define TIM1_DMAR_Address   0x40012C4C

#define CCMR1_OC1PE_BB    0x4225830C	   // TIMR1_CCMR1_OC1PE 的BITBAND位地址。
#define CCMR1_OC2PE_BB    0x4225832C	   // TIMR1_CCMR1_OC2PE 的BITBAND位地址。
#define CCMR2_OC3PE_BB    0x4225838C	   // TIMR1_CCMR1_OC3PE 的BITBAND位地址。

#define CH1NORMAL 0x0060
#define CH2NORMAL 0x6000
#define CH3NORMAL 0x0060
#define CH4NORMAL 0x7000
#define CH1TOGGLE 0x0030
#define CH2TOGGLE 0x3000
#define CH3TOGGLE 0x0030
#define CH4TOGGLE 0x3000

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8  bSector;  
u16 hPhaseOffset=0;

u8 bInverted_pwm=INVERT_NONE,bInverted_pwm_new=INVERT_NONE;
u8  bStatorFluxPos, bStatorFluxPosOld;
DUTYVALUESTYPE dvDutyValues;
CURRENTSAMPLEDTYPE csCurrentSampled;
u8 bError=0;

s16 hCurrAOld,hCurrBOld,hCurrCOld;
s16 hDeltaA,hDeltaB,hDeltaC;
u8 bReadDelta;

u16 hPreloadCCMR1Disable;
u16 hPreloadCCMR1Set;
u16 hPreloadCCMR2Disable;
u16 hPreloadCCMR2Set;
   
u16 hCCDmaBuffCh1[4];
u16 hCCDmaBuffCh2[4];
u16 hCCDmaBuffCh3[4];
u16 hCCDmaBuffCh4[4];

u16 hCCRBuff[4];

u8 bStBd3 = 0;
u8 bDistEnab = 0;

/* Private function prototypes -----------------------------------------------*/

void SVPWM_InjectedConvConfig(void);

/*******************************************************************************
* Function Name  : SVPWM_1ShuntInit
* Description    : It initializes PWM and ADC peripherals
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SVPWM_1ShuntInit(void)
{ 
  ADC_InitTypeDef ADC_InitStructure;
  TIM_TimeBaseInitTypeDef TIM1_TimeBaseStructure;
  TIM_OCInitTypeDef TIM1_OCInitStructure;
  TIM_BDTRInitTypeDef TIM1_BDTRInitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;

  /* ADC1, ADC2, DMA, GPIO, TIM1 clocks enabling -----------------------------*/
  
  /* ADCCLK = PCLK2/6 */
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);	 // ADCCLK = 12MHZ

  /* Enable DMA clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  
  /* Enable GPIOA, GPIOC, GPIOE, AFIO clocks */
  // 这里忘了设置PB口的时钟使能,造成不用JLINK时程序不正常。原来使用了PE口。
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOE, ENABLE);
  /* Enable ADC1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  /* Enable ADC2 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); 
   
  /* Enable TIM1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
     
  /* ADC1, ADC2, PWM pins configurations -------------------------------------*/
  GPIO_StructInit(&GPIO_InitStructure);
  /****** Configure PC.00,01,2,3,4,5 (ADC Channels [10..15]) as analog input ****/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
     
  GPIO_StructInit(&GPIO_InitStructure);
  /****** Configure PA.06,07(ADC Channels [6..7]) as analog input ****/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

   GPIO_StructInit(&GPIO_InitStructure);
  /****** Configure PB.00,01(ADC Channels [8..9]) as analog input ****/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  
  // After reset value of DMA buffers
  hCCDmaBuffCh1[0] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh1[1] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh1[2] = PWM_PERIOD >> 1;
  hCCDmaBuffCh1[3] = PWM_PERIOD >> 1;
  ;
  hCCDmaBuffCh2[0] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh2[1] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh2[2] = PWM_PERIOD >> 1;
  hCCDmaBuffCh2[3] = PWM_PERIOD >> 1;
  
  hCCDmaBuffCh3[0] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh3[1] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh3[2] = PWM_PERIOD >> 1;
  hCCDmaBuffCh3[3] = PWM_PERIOD >> 1;
  
  // Default Update DMA buffer Ch 1,2,3,4 after reset
  hCCRBuff[0] = PWM_PERIOD >> 1;
  hCCRBuff[1] = PWM_PERIOD >> 1;
  hCCRBuff[2] = PWM_PERIOD >> 1;
  hCCRBuff[3] = (PWM_PERIOD >> 1) - TBEFORE;
  
  // After reset value of dvDutyValues
  dvDutyValues.hTimePhA = PWM_PERIOD >> 1;
  dvDutyValues.hTimePhB = PWM_PERIOD >> 1;
  dvDutyValues.hTimePhC = PWM_PERIOD >> 1;
  
  /* TIM1 Channel 1 toggle mode */
  /* DMA Channel2 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel2);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_CCR1_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(hCCDmaBuffCh1);
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  // 外设作为数据传输的目的地 
  DMA_InitStructure.DMA_BufferSize = 4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址寄存器递增
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址寄存器递增
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 数据宽度为 16 位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 工作在循环缓存模式 
  DMA_InitStructure.DMA_Priority = DMA_Priority_High; // DMA通道 x拥有高优先级
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // DMA通道 x没有设置为内存到内存传输
  DMA_Init(DMA1_Channel2, &DMA_InitStructure);
  /* Enable DMA Channel2 */
  //DMA_Cmd(DMA_Channel2, ENABLE);
  DMA_Cmd(DMA1_Channel2, DISABLE);
  
  /* TIM1 Channel 2 toggle mode */
  /* DMA Channel3 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel3);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_CCR2_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(hCCDmaBuffCh2);
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel3, &DMA_InitStructure);
  /* Enable DMA Channel3 */
  //DMA_Cmd(DMA_Channel3, ENABLE);
  DMA_Cmd(DMA1_Channel3, DISABLE);

  /* TIM1 Channel 3 toggle mode */
  /* DMA Channel6 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel6);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_CCR3_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(hCCDmaBuffCh3);
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel6, &DMA_InitStructure);
  /* Enable DMA Channel6 */
  DMA_Cmd(DMA1_Channel6, DISABLE);
  
  /* TIM1 Channel 4 PWM2 or toggle mode */
  /* DMA channel4 configuration */
  DMA_DeInit(DMA1_Channel4);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_CCR4_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(hCCDmaBuffCh4);
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 2;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel4, &DMA_InitStructure);
  
  DMA_Cmd(DMA1_Channel4, ENABLE);
  
  /* DMA TIM1 update configuration */
  DMA_DeInit(DMA1_Channel5);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_DMAR_Address; 
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(hCCRBuff);
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  
  DMA_Cmd(DMA1_Channel5, ENABLE);
   
  /* TIM1 Peripheral Configuration -------------------------------------------*/
  /* TIM1 Registers reset */
  TIM_DeInit(TIM1);
  TIM_TimeBaseStructInit(&TIM1_TimeBaseStructure);
  /* Time Base configuration */
  TIM1_TimeBaseStructure.TIM_Prescaler = 0x0;	  //TIM1_Prescaler设置了用来作为 TIM1时钟频率除数的预分频值。
  												  //它的取值必须在 0x0000 和0xFFFF 之间
  TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned3;	//TIM1 中央对齐模式 3 在计数器向上和向下计数都触发中断 
  TIM1_TimeBaseStructure.TIM_Period = PWM_PERIOD;							//参考TIM1_CR1控制寄存器的5-6位
  TIM1_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;	//为了设置死区时间和数字滤波
  
  // Initial condition is REP=0 to set the UPDATE only on the underflow
  TIM1_TimeBaseStructure.TIM_RepetitionCounter = REP_RATE;
  TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure);

//==============================================================================  
// 设置TIM1_CH1\CH2\CH3的工作状态,使用IR2103或者IR2101应该设定不同的
// 有效边沿。   
  TIM_OCStructInit(&TIM1_OCInitStructure);
  /* Channel 1, 2,3 in PWM mode */
  TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  // TIM1 脉冲宽度调制模式 1 
		   											  // 和PWM模式2正好相反,具体参考TIM1_CCMR1
													  // 寄存器的4-6位。	
													  
  TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能输出比较状态 
  TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;  //使能输出比较 N状态                 
  TIM1_OCInitStructure.TIM_Pulse = PWM_PERIOD >> 1; // 50%占空比
  TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  // TIM1 输出比较极性高 

//设置使用IR2101S或者IR2103S
#ifdef IR_2101S
  TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;   //IR2101S      
#endif
#ifdef IR_2103S
  TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;      //IR2103S

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -