?? stm32f10x_svpwm_3shunt.c
字號:
/*****************************************************************************
* 文件名 : STM32x_svpwm_3shunt.c
* 功能描述 : 3分流電阻電流取樣模式
*******************************************************************************/
#include "STM32F10x_MCconf.h"
#ifdef THREE_SHUNT
/* Includes-------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_svpwm_3shunt.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
/*三相ABC,ADC轉換通道*/
#define PHASE_A_ADC_CHANNEL ADC_Channel_11
#define PHASE_B_ADC_CHANNEL ADC_Channel_10
#define PHASE_C_ADC_CHANNEL ADC_Channel_6
/* 電流取樣后設置母線電壓及溫度取樣*/
#define PHASE_A_MSK (u32)((u32)(PHASE_A_ADC_CHANNEL) << 10)
#define PHASE_B_MSK (u32)((u32)(PHASE_B_ADC_CHANNEL) << 10)
#define PHASE_C_MSK (u32)((u32)(PHASE_C_ADC_CHANNEL) << 10)
// Settings for current sampling only
/*#define PHASE_A_MSK (u32)((u32)(PHASE_A_ADC_CHANNEL) << 15)
#define PHASE_B_MSK (u32)((u32)(PHASE_B_ADC_CHANNEL) << 15)
#define PHASE_C_MSK (u32)((u32)(PHASE_C_ADC_CHANNEL) << 15)*/
// Setting for sampling of VBUS and Temp after currents sampling
#define TEMP_FDBK_MSK (u32)((u32)(TEMP_FDBK_CHANNEL) <<15)
#define BUS_VOLT_FDBK_MSK (u32)((u32)(BUS_VOLT_FDBK_CHANNEL) <<15)
// Settings for current sampling only
//#define TEMP_FDBK_MSK (u32)(0)
//#define BUS_VOLT_FDBK_MSK (u32)(0)
// Setting for sampling of VBUS and Temp after currents sampling
#define SEQUENCE_LENGHT 0x00100000
// Settings for current sampling only
//#define SEQUENCE_LENGHT 0x00000000
#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 1
#define TIM1_UP_SUB_PRIORITY 0
#define DMA_CH1_PRE_EMPTION_PRIORITY 1
#define DMA_CH1_SUB_PRIORITY 1
#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
#define PWM2_MODE 0
#define PWM1_MODE 1
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 bSector;
u16 hPhaseAOffset;
u16 hPhaseBOffset;
u16 hPhaseCOffset;
u8 PWM4Direction=PWM2_MODE;
/* Private function prototypes -----------------------------------------------*/
void SVPWM_InjectedConvConfig(void);
/*******************************************************************************
* Function Name : SVPWM_3ShuntInit
* Description : It initializes PWM and ADC peripherals
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SVPWM_3ShuntInit(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);
/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable GPIOA, GPIOC, GPIOE, AFIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE |
RCC_APB2Periph_GPIOC , 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 AIN0 、AIN1 ****/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* TIM1 Peripheral Configuration -------------------------------------------*/
/* TIM1 Registers reset */
TIM_DeInit(TIM1);
TIM_TimeBaseStructInit(&TIM1_TimeBaseStructure);
/* Time Base configuration */
TIM1_TimeBaseStructure.TIM_Prescaler = 0x0;
TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;//TIM1 中央對齊模式 1 只在計數器向下計數時觸發中斷
TIM1_TimeBaseStructure.TIM_Period = PWM_PERIOD;
TIM1_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;//設置死區時間和數字濾波器時間。DTS
// Initial condition is REP=0 to set the UPDATE only on the underflow
TIM1_TimeBaseStructure.TIM_RepetitionCounter = REP_RATE;
TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure);
TIM_OCStructInit(&TIM1_OCInitStructure);
/* Channel 1, 2,3 in PWM mode */
TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM1_OCInitStructure.TIM_Pulse = 0x505; //dummy value
TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
//設置使用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
#endif
TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM1_OCInitStructure.TIM_OCNIdleState = LOW_SIDE_POLARITY;
TIM_OC1Init(TIM1, &TIM1_OCInitStructure);
TIM_OC2Init(TIM1, &TIM1_OCInitStructure);
TIM_OC3Init(TIM1, &TIM1_OCInitStructure);
/*Timer1 alternate function full remapping*/
GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
/* GPIOE Configuration: Channel 1, 1N, 2, 2N, 3, 3N and 4 Output */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_StructInit(&GPIO_InitStructure);
/* GPIOE Configuration: Channel 1N, 2N, 3N */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Lock GPIOE Pin9 and Pin11 Pin 13 (High sides) */
GPIO_PinLockConfig(GPIOE, GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_13 );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
TIM_OCStructInit(&TIM1_OCInitStructure);
/* Channel 4 Configuration in OC */
TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //和1.2.3通道的PWM1模式正好相反,參考
// TIM1_CCMR1寄存器的4-6位。
TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM1_OCInitStructure.TIM_Pulse = PWM_PERIOD - 1;
TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM1_OCInitStructure.TIM_OCNIdleState = LOW_SIDE_POLARITY;
TIM_OC4Init(TIM1, &TIM1_OCInitStructure);
/* Enables the TIM1 Preload on CC1 Register */
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* Enables the TIM1 Preload on CC2 Register */
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* Enables the TIM1 Preload on CC3 Register */
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* Enables the TIM1 Preload on CC4 Register */
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* Automatic Output enable, Break, dead time and lock configuration*/
TIM1_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM1_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM1_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM1_BDTRInitStructure.TIM_DeadTime = DEADTIME;
TIM1_BDTRInitStructure.TIM_Break = TIM_Break_Enable; //沒有打開緊急停車功能
//NVIC中斷向量也要關閉
TIM1_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM1_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStructure);
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
TIM_ClearITPendingBit(TIM1, TIM_IT_Break);
TIM_ITConfig(TIM1, TIM_IT_Break,ENABLE);
/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
// Resynch to have the Update evend during Undeflow
TIM_GenerateEvent(TIM1, TIM_EventSource_Update);
// Clear Update Flag
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE);
TIM_ITConfig(TIM1, TIM_IT_CC4,DISABLE);
//設置DMA,用于存儲ADC1和ADC2的規則組轉換值。
//=================================================================================
/* DMA1 Channel1 Config */
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BufferLenght;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ClearITPendingBit(DMA1_IT_TC1);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
/* DMA1 Channel1 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);
//=====================================================================================
/* ADC1 registers reset ----------------------------------------------------*/
ADC_DeInit(ADC1);
/* ADC2 registers reset ----------------------------------------------------*/
ADC_DeInit(ADC2);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC2 */
ADC_Cmd(ADC2, ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult; //ADC1和ADC2工作在混合同步規則及注入模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; //非外部觸發,先用軟件觸發
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;
ADC_InitStructure.ADC_NbrOfChannel = 3; //BUS_SHUNT+BREAK_SHUNT+Chip Temp
ADC_Init(ADC1, &ADC_InitStructure);
ADC_DMACmd(ADC1, ENABLE); //如何把數據正確取出來???,使用DMA中斷吧。
/* ADC2 Configuration ------------------------------------------------------*/
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult; //ADC1和ADC2工作在混合同步規則及注入模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; //非外部觸發,先用軟件觸發
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;
ADC_InitStructure.ADC_NbrOfChannel = 3; //BUS_SHUNT+BREAK_SHUNT+Chip Temp
ADC_Init(ADC2, &ADC_InitStructure);
// ADC_ExternalTrigConvCmd(ADC2, ENABLE);
// ADC_SoftwareStartConvCmd(ADC1, DISABLE); //先關閉軟件觸發規則組,連續掃描
//下面分別設置規則通道組和注入通道組
/* Temp On CPU */
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);
/* ADC1 Regular Channel BREAK_SHUNT */
ADC_RegularChannelConfig(ADC1, BRK_SHUNT_CURR_CHANNEL, 2, ADC_SampleTime_239Cycles5);
/* ADC1 Regular Channel BUS_SHUNT */
ADC_RegularChannelConfig(ADC1, BUS_SHUNT_CURR_CHANNEL, 3, ADC_SampleTime_239Cycles5);
/* ADC2 Regular Channel POT1 */
ADC_RegularChannelConfig(ADC2, POT1_VOLT_FDBK_CHANNEL, 1, ADC_SampleTime_239Cycles5);
/* ADC2 Regular Channel AIN0 */
ADC_RegularChannelConfig(ADC2, AIN0_VOLT_FDBK_CHANNEL, 2, ADC_SampleTime_239Cycles5);
/* ADC1 Regular Channel AIN1 */
ADC_RegularChannelConfig(ADC2, AIN1_VOLT_FDBK_CHANNEL, 3, ADC_SampleTime_239Cycles5);
//=============================================================================
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE); //喚醒ADC1
ADC_TempSensorVrefintCmd(ENABLE); // Chanel 16 = Temp On Chip
//下面是校正ADC1和ADC2
//==============================================================================
/* Enable ADC1 reset calibaration register */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -