void Timer1_Config(void)//ROLL Timer configuration { //Timer1 Config //PWM pin config GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //PWM pin config GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); //Time Base configuration TIM_TimeBaseInitStructure.TIM_Prescaler = 5; // Period*Prescaler=24'000'000Hz //2400 1s TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 1000; //20000(presc=24)=50hz(servo signal) TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure); //Configuration in PWM mode TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1 ; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC3Init(TIM1, &TIM_OCInitStructure); //Automatic Output enable, Break, dead time and lock configuration TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 200; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); //TIM1 counter enable TIM_Cmd(TIM1, ENABLE); //Main Output Enable TIM_CtrlPWMOutputs(TIM1, ENABLE); }
/* * TIMxCLK/CK_PSC --> TIMxCNT --> TIMx_ARR --> TIMxCNT 重新计数 * TIMx_CCR(电平发生变化) * 信号周期=(TIMx_ARR +1 ) * 时钟周期 * 占空比=TIMx_CCR/(TIMx_ARR +1) */ static void TIM1_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; /* PWM信号电平跳变值 */ u16 CCR1_Val = 0; /* ----------------------------------------------------------------------- TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR+1)* 100% = 50% TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR+1)* 100% = 37.5% TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR+1)* 100% = 25% TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR+1)* 100% = 12.5% ----------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 999; //当定时器从0计数到999,即为1000次,为一个定时周期 TIM_TimeBaseStructure.TIM_Prescaler = 0; //设置预分频:不预分频,即为72MHz TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //设置时钟分频系数:不分频(这里用不到) TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //设置跳变值,当计数器计数到这个值时,电平发生跳变 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //当定时器计数值小于CCR1_Val时为高电平 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1,&TIM_OCInitStructure); //使能通道1 TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_ARRPreloadConfig(TIM1, ENABLE); // 使能TIM3重载寄存器ARR /* TIM1 enable counter */ TIM_Cmd(TIM1, ENABLE); //使能定时器1 TIM_CtrlPWMOutputs(TIM1, ENABLE); }
void complementaryPWM(uint8_t timer, int freqHz, uint16_t deadtime) { #if defined(SERIES_STM32F30x) // init timebase timerInit(timer, freqHz); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; TIM_OC1Init(TIMER_MAP[timer].TIMx, &TIM_OCInitStructure); TIM_OC2Init(TIMER_MAP[timer].TIMx, &TIM_OCInitStructure); TIM_OC3Init(TIMER_MAP[timer].TIMx, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = deadtime; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIMER_MAP[timer].TIMx, &TIM_BDTRInitStructure); /* counter enable */ TIM_Cmd(TIMER_MAP[timer].TIMx, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIMER_MAP[timer].TIMx, ENABLE); #endif }
static void timerPWMadvancedConfig(TIM_TypeDef *tim) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //Time Base configuration TIM_TimeBaseInitStructure.TIM_Prescaler = 1; // 36 MHz TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; TIM_TimeBaseInitStructure.TIM_Period = PWM_PERIOD - 1; // 36 MHz / (2 * 1000) = 18 kHz TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV2; TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(tim, &TIM_TimeBaseInitStructure); //Configuration in PWM mode TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; timerChannelConfig(tim, &TIM_OCInitStructure); //Automatic Output enable, Break, dead time and lock configuration TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = deadTimeRegister; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(tim, &TIM_BDTRInitStructure); }
void brake_init (void) { /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = 0; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable Break interrupt */ TIM_ITConfig (TIM1, TIM_IT_Break, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM1 Configuration */ TIM_Config(); /* --------------------------------------------------------------------------- TIM1 Configuration to: 1/ Generate 3 complementary PWM signals with 3 different duty cycles: TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock TIM1CLK is fixed to SystemCoreClock, the TIM1 Prescaler is equal to 0 so the TIM1 counter clock used is SystemCoreClock (168MHz). The objective is to generate PWM signal at 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 The Three Duty cycles are computed as the following description: The channel 1 duty cycle is set to 50% so channel 1N is set to 50%. The channel 2 duty cycle is set to 25% so channel 2N is set to 75%. The channel 3 duty cycle is set to 12.5% so channel 3N is set to 87.5%. The Timer pulse is calculated as follows: - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 2/ Insert a dead time equal to (11/SystemCoreClock) ns 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parameters level1. Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /* Compute the value to be set in ARR register to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570) - 1; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) { } }
/****************************************************************************** * タイトル : PWM初期設定 * 関数名 : Init_PWM * 戻り値 : int型 0:設定できた 1:設定できない * 引数1 : TIM_TypeDef *型 TIMx TIMx TIMのポインタ * 引数2 : GPIO_TypeDef型 *GPIOx GPIOx GPIOのポインタ * 引数3 : uint16_t型 pin GPIO_Pin_x PINの設定 * 引数4 : int型 frequency PWM周波数[Hz](整数) * 作成者 : 永谷 智貴 * 作成日 : 2014/11/10 ******************************************************************************/ int Init_PWM(TIM_TypeDef * TIMx,GPIO_TypeDef *GPIOx,uint16_t pin,int frequency)//エラーがあれば1、なければ0をreturnする { long TIM_clock=0; int prescaler=0; int period=0; int calc_retry_flag=1; //float error_ratio=0; unsigned short i = 0; Pin_t pin_state;// //システムクロックをRCC_Clocksで取得 SystemCoreClockUpdate(); RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(&RCC_Clocks); //TIMのクロックの取得 if((TIM2<=TIMx&&TIMx<=TIM7)||(TIM12<=TIMx&&TIMx<=TIM14)){ TIM_clock=RCC_Clocks.PCLK1_Frequency*((RCC_TIMPRE+1)*2); //PCLK1のTIMプリスケーラ倍したらTIM2-7,12-14のクロックが出てくる }else{ TIM_clock=RCC_Clocks.PCLK2_Frequency*((RCC_TIMPRE+1)*2); //PCLK2のTIMプリスケーラ倍したら上のやつ以外のクロックが出てくる } #ifdef PRINTF_AVAILABLE printf("Init_PWM() start.\nTIM_clock:%d,\n",TIM_clock); #endif //上下の設定可能な周波数の中に納まっているか確認 if(frequency<FREQUENCY_UNDER_LIMIT || frequency>TIM_clock/PRESCALER_UNDER_LIMIT/PERIOD_UNDER_LIMIT) { #ifdef PRINTF_AVAILABLE printf("Error. Frequency value out of range. '%d' - '%d' Requested frequency '%d'\n",FREQUENCY_UNDER_LIMIT,TIM_clock/PRESCALER_UNDER_LIMIT/PERIOD_UNDER_LIMIT,frequency); #endif return 1; //おかしければエラー返して終了 } //prescaler,periodを計算 while(calc_retry_flag) //periodが制限内の最大になるまでprescalerを上げているだけ。計算でも出せるけど、見た目だけはこっちのほうがきれい。 { prescaler++; period=TIM_clock/prescaler/frequency; if(period<=PERIOD_LIMIT) calc_retry_flag=0; if(prescaler>=PRESCALER_LIMIT){ //prescalerが上の制限を超しちゃったらエラーを履くけどそうはならない。 #ifdef PRINTF_AVAILABLE printf("Error. Prescaler value out of range. '%d'-'%d' \n",PRESCALER_UNDER_LIMIT,PRESCALER_LIMIT); #endif return 1; //おかしければエラー返して終了 } } // error_ratio=fabs(((float)TIM_clock/prescaler/period-(float)frequency)/(float)frequency)*100;//周波数の誤差をパーセントで計算。1%以内には納まる。 frequency=TIM_clock/prescaler/period; //設定した数値から算出される周波数 大体同じ。 #ifdef PRINTF_AVAILABLE printf("Result: \n period:%d,\n prescaler:%d,\n frequency:%d,\n\n",period,prescaler,frequency); #endif //ここから普通のPWM設定 //設定に使用する構造体の宣言 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM設定用構造体宣言 TIM_OCInitTypeDef TIM_OCInitStructure; //OC設定用構造体宣言 TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //クロック供給 RCC_PeriphClock_TIM(TIMx);//TIMクロック供給 //クロック供給とGPIO設定 Init_port(GPIO_Mode_AF,GPIOx,pin,GPIO_PuPd_NOPULL,GPIO_OType_PP); //TIM設定 TIM_TimeBaseStructure.TIM_Period = period-1; //計算したperiod-1 TIM_TimeBaseStructure.TIM_Prescaler = prescaler-1; //計算したprescaler-1 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //なんかここ変えても周波数変わらなかったんだよね ナニコレ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //カウンターモードアップ設定 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //高機能タイマー用 基本0 TIM_TimeBaseInit(TIMx,&TIM_TimeBaseStructure); //設定書き込み TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWMモード1 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //アクティブレベル時の極性をHighレベルにセット TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //タイマ出力を有効化 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC1PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 TIM_OC2Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC2PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 TIM_OC3Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC3PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 TIM_OC4Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC4PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 //使用するピンをTIMの出力として設定 // GPIO_PinAFConfig(GPIOx,Pin_select_source(pin),Tim_select_af(TIMx));//AF設定 /*TIM1とTIM8はSTM32の中でも高機能タイマに分類され、 モータ制御用に使用されるBREAK入力機能がついている このBREAK機能の中でoutputの有効化という機能があり、デフォルトの設定で タイマー出力ごとにoutputが無効に設定されているためPWM信号が止まる。 そのため、 タイマの更新イベントごとにoutputが自動的に再有効になるように設定する。*/ if(TIMx == TIM1 || TIMx == TIM8){ TIM_BDTRStructInit(&TIM_BDTRInitStructure); TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIMx, &TIM_BDTRInitStructure); TIM_CtrlPWMOutputs(TIMx, ENABLE); } Analysis_GPIO_Pin(pin, &pin_state); for (i = 0; i < 16; i++){ if (pin_state.user_pin[i] == 1){ GPIO_PinAFConfig(GPIOx, Pin_select_source(pin_state.pin_address[i]), Tim_select_af(TIMx));//AF設定 } } //ミニMDではしない方が良さげ TIMx->CCR1=0;TIMx->CCR2=0;TIMx->CCR3=0;TIMx->CCR4=0; //一応duty全部0%にしておく TIM_ARRPreloadConfig(TIMx,ENABLE);//プリロード設定の適用 TIM_Cmd(TIMx,ENABLE);//タイマー有効化 return 0; }
/** * @brief Configure the TIM1 Pins. * @param None * @retval None */ static void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* GPIOA and GPIOB clocks enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* GPIOA Configuration: Channel 1, 2, 1N and 3 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* GPIOB Configuration: Channel 2N and 3N as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_12; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect TIM pins to AF2 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_2); /*---------------------------------------------------------------------------- The STM32F0xx TIM1 peripheral offers the possibility to program in advance the configuration for the next TIM1 outputs behaviour (step) and change the configuration of all the channels at the same time. This operation is possible when the COM (commutation) event is used. The COM event can be generated by software by setting the COM bit in the TIM1_EGR register or by hardware (on TRC rising edge). In this example, a software COM event is generated each 100 ms: using the SysTick interrupt. The TIM1 is configured in Timing Mode, each time a COM event occurs, a new TIM1 configuration will be set in advance. The following Table describes the TIM1 Channels states: ----------------------------------------------- | Step1 | Step2 | Step3 | Step4 | Step5 | Step6 | ---------------------------------------------------------- |Channel1 | 1 | 0 | 0 | 0 | 0 | 1 | ---------------------------------------------------------- |Channel1N | 0 | 0 | 1 | 1 | 0 | 0 | ---------------------------------------------------------- |Channel2 | 0 | 0 | 0 | 1 | 1 | 0 | ---------------------------------------------------------- |Channel2N | 1 | 1 | 0 | 0 | 0 | 0 | ---------------------------------------------------------- |Channel3 | 0 | 1 | 1 | 0 | 0 | 0 | ---------------------------------------------------------- |Channel3N | 0 | 0 | 0 | 0 | 1 | 1 | ---------------------------------------------------------- ----------------------------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 4095; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2,3 and 4 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 2047; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = 1023; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = 511; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = 1; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_CCPreloadControl(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Enable the TIM1 Trigger and commutation interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
/******************************************************************************* * Function Name : TIM1_PWM_Init * Description : It initializes PWM peripherals * Input : None * Output : None * Return : None *******************************************************************************/ void TIM1_PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM1_TimeBaseStructure; TIM_OCInitTypeDef TIM1_OCInitStructure; TIM_BDTRInitTypeDef TIM1_BDTRInitStructure; /* Enable TIM1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOE, ENABLE); /*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_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; 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_StructInit(&GPIO_InitStructure); /* GPIOE Configuration: BKIN pin */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOE, &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_TimeBaseStructure.TIM_Period = PWM_PERIOD; 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); 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; TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; 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); /* Channel 4 Configuration in OC */ TIM_OCStructInit(&TIM1_OCInitStructure); TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 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; TIM1_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;//0:刹车输入低电平有效;1:刹车输入高电平有效。由外部引脚电平从高到底,引起。 TIM1_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; //TIM_AutomaticOutput_Enable: 刹车后,刹车输入电平变为无效无效后,下一个脉冲周期,自动回复脉冲输出。 //TIM_AutomaticOutput_Disable: 刹车后,脉冲输出永久禁止,除非手动调用TIM_CtrlPWMOutputs(TIM1, ENABLE),否则不能启动pwm输出。 TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStructure); TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); TIM_ClearITPendingBit(TIM1, TIM_IT_Break); // TIM_ITConfig(TIM1, TIM_IT_Break,ENABLE); TIM_ITConfig(TIM1, TIM_IT_Break,DISABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); // Resynch to have the Update evend during Undeflow TIM_GenerateEvent(TIM1, TIM_EventSource_Update); //UG=1:重新初始化计数器,并产生一个更新事件加上REP=1,保证了在中心对齐模式下更新事件只发生向下溢出CNT=1处 // Clear Update Flag TIM_ClearFlag(TIM1, TIM_FLAG_Update); TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE);//不允许更新中断, TIM_ITConfig(TIM1, TIM_IT_CC4,DISABLE);//不允许CC4捕获中断 }
//arr:自动重装值 //psc:时钟预分频数 void PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//初始化TIMx的时间基数 TIM_OCInitTypeDef TIM_OCInitStructure;//初始化外设TIMx TIM_BDTRInitTypeDef TIM_BDTRInitStructure;//死区设置 /*************1、引脚io设置*************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);//使能GPIO外设时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//使能复用功能 //设置该引脚为复用输出功能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //端口频率可设为2,10,50 GPIO_Init(GPIOA, &GPIO_InitStructure);//启动A端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_13; GPIO_Init(GPIOB, &GPIO_InitStructure);//启动B端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8; GPIO_Init(GPIOC, &GPIO_InitStructure);//启动C端口 /*****************2、通道设置*****************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_TIM8, ENABLE);//使能外设时钟TIMx,TIM8 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值80K TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器 TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM脉冲宽度调制模式1:小于设定值则为高;2反之 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //选择互补输出比较状态 TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High; //TIM互补输出极性为高 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //选择空闲状态 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //重置互补输出的输出比较状态 TIM_OC1Init(TIM1, &TIM_OCInitStructure); //TIMx通道1设置 TIM_OC1Init(TIM8, &TIM_OCInitStructure); TIM_OC2Init(TIM8, &TIM_OCInitStructure); TIM_OC3Init(TIM8, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //预装载使能,为了让控制更精准,更改不是立马改变,在本次波形执行完之后 TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //不用也可以 TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); // TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); // //死区设置 TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;//设置在运行模式下非工作状态选项 TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;//设置空闲状态下的非工作状态 TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;//设置锁电平参数,不锁定任何位 TIM_BDTRInitStructure.TIM_DeadTime = 100;//死区时间,0-0xff,设置了输出打开和关闭之间的延时 TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;//刹车功能使能 TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//自动输出使能 TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure); // TIM_BDTRConfig(TIM8,&TIM_BDTRInitStructure); // TIM_Cmd(TIM1, ENABLE); //使能TIMx TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能 TIM_Cmd(TIM8, ENABLE); //使能TIM8 TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能 pwm_set_off(TIM8, TIM_Channel_1); pwm_set_off(TIM8, TIM_Channel_2); pwm_set_off(TIM8, TIM_Channel_3); pwm_set_off(TIM1, TIM_Channel_1); }
/** * @brief Configures TIM1: channels in PWM mode * @param None * @retval None */ void TIM_Config(void) { TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; /* GPIOA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* TIM1 channels pin configuration: TIM1_CH1 -> PA8 */ GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Enable Alternate function on PA8 to be controlled by TIM1 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 100; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 50; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRStructInit(&TIM_BDTRInitStructure); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); }
static void config_tim1( void ) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; uint16_t TimerPeriod = 0; uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0, Channel4Pulse = 0; /* Compute the value to be set in ARR register to generate signal frequency at 16 Khz */ //TimerPeriod = (SystemCoreClock / 16000) - 1; // In center aligned mode, counts up and down, so * 2. // TimerPeriod = (84000000 / ( 2 * 14000 )) - 1; TimerPeriod = 1000; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ //Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); Channel1Pulse = 500; /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ //Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); Channel2Pulse = 250; /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ //Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); Channel3Pulse = 125; // pulse sent to other timer to trigger ADC; // 97 steps from 999 -> 999-97 = 902 Channel4Pulse = 902; /* Time Base configuration */ TIM_TimeBaseStructInit( &TIM_TimeBaseStructure ); // 14 MHz / 1000 steps == 14 kHz TIM_TimeBaseStructure.TIM_Prescaler = PRESCALER; //TIM_TimeBaseStructure.TIM_Prescaler = 65535; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCStructInit( &TIM_OCInitStructure ); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OCStructInit( &TIM_OCInitStructure ); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_Pulse = Channel4Pulse; TIM_OC4Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRStructInit( &TIM_BDTRInitStructure ); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); /* Master Mode selection and TRGO update output */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC4Ref); TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); }
void gpdrive_init(volatile mc_configuration *configuration) { utils_sys_lock_cnt(); m_init_done = false; // Restore timers TIM_DeInit(TIM1); TIM1->CNT = 0; // Disable channel 2 pins palSetPadMode(GPIOA, 9, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(GPIOA, 9); palSetPadMode(GPIOB, 14, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(GPIOB, 14); m_conf = configuration; m_fsw_now = 40000; m_mod_now = 0.0; m_current_now = 0.0; m_current_now_filtered = 0.0; m_output_mode = GPD_OUTPUT_MODE_NONE; memset((void*)&m_sample_buffer, 0, sizeof(m_sample_buffer)); m_buffer_int_scale = 1.0 / 128.0; m_is_running = false; m_output_now = 0.0; m_curr0_sum = 0; m_curr1_sum = 0; m_curr_samples = 0; m_curr0_offset = 0; m_curr1_offset = 0; m_dccal_done = false; #ifdef HW_HAS_3_SHUNTS m_curr2_sum = 0; m_curr2_offset = 0; #endif m_last_adc_isr_duration = 0; memset((void*)&m_current_state, 0, sizeof(m_current_state)); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = SYSTEM_CORE_CLOCK / (int)m_fsw_now; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = TIM1->ARR / 2; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OC4Init(TIM1, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = conf_general_calculate_deadtime(HW_DEAD_TIME_NSEC, SYSTEM_CORE_CLOCK); TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_CCPreloadControl(TIM1, ENABLE); TIM_ARRPreloadConfig(TIM1, ENABLE); ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE); dmaStreamAllocate(STM32_DMA_STREAM(STM32_DMA_STREAM_ID(2, 4)), 3, (stm32_dmaisr_t)adc_int_handler, (void *)0); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_Value; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC->CDR; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = HW_ADC_CHANNELS; 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_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream4, &DMA_InitStructure); DMA_Cmd(DMA2_Stream4, ENABLE); DMA_ITConfig(DMA2_Stream4, DMA_IT_TC, ENABLE); // Note that the ADC is running at 42MHz, which is higher than the // specified 36MHz in the data sheet, but it works. ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Falling; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC2; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = HW_ADC_NBR_CONV; ADC_Init(ADC1, &ADC_InitStructure); ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = 0; ADC_Init(ADC2, &ADC_InitStructure); ADC_Init(ADC3, &ADC_InitStructure); ADC_TempSensorVrefintCmd(ENABLE); ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); hw_setup_adc_channels(); ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); ADC_Cmd(ADC3, ENABLE); TIM_Cmd(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); // Always sample ADC in the beginning of the PWM cycle TIM1->CCR2 = 200; utils_sys_unlock_cnt(); ENABLE_GATE(); DCCAL_OFF(); do_dc_cal(); // Start threads timer_thd_stop = false; chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL); stop_pwm_hw(); // Check if the system has resumed from IWDG reset if (timeout_had_IWDG_reset()) { mc_interface_fault_stop(FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET); } m_init_done = true; }
/** * Initialize the three phase (6outputs) PWM peripheral and internal state. */ void pwm_init(void) { NVIC_InitTypeDef nvic; GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef tim_base; TIM_OCInitTypeDef tim_oc; TIM_BDTRInitTypeDef tim_bdtr; (void)gpc_setup_reg(GPROT_PWM_OFFSET_REG_ADDR, &pwm_offset); /* Enable clock for TIM1 subsystem */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); /* Enable TIM1 interrupt */ nvic.NVIC_IRQChannel = TIM1_TRG_COM_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority = 1; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); /* Enable TIM1 interrupt */ nvic.NVIC_IRQChannel = TIM1_CC_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority = 1; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); /* GPIOA: TIM1 channel 1, 2 and 3 as alternate function push-pull */ gpio.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio); /* GPIOB: TIM1 channel 1N, 2N and 3N as alternate function * push-pull */ gpio.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOB, &gpio); /* Time base configuration */ tim_base.TIM_Period = PWM__BASE_CLOCK / PWM__FREQUENCY; tim_base.TIM_Prescaler = 0; tim_base.TIM_ClockDivision = 0; tim_base.TIM_CounterMode = TIM_CounterMode_Up; tim_base.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &tim_base); /* TIM1 channel 1, 2 and 3 settings */ tim_oc.TIM_OCMode = TIM_OCMode_Timing; tim_oc.TIM_OutputState = TIM_OutputState_Enable; tim_oc.TIM_OutputNState = TIM_OutputNState_Enable; tim_oc.TIM_Pulse = pwm_val; tim_oc.TIM_OCPolarity = TIM_OCPolarity_High; tim_oc.TIM_OCNPolarity = TIM_OCNPolarity_High; tim_oc.TIM_OCIdleState = TIM_OCIdleState_Set; tim_oc.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &tim_oc); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2Init(TIM1, &tim_oc); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3Init(TIM1, &tim_oc); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); /* TIM1 configure channel 4 as adc trigger source */ tim_oc.TIM_OCMode = TIM_OCMode_PWM2; tim_oc.TIM_Pulse = pwm_offset; TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC4Init(TIM1, &tim_oc); /* Automatic Output enable, break, dead time and lock configuration */ tim_bdtr.TIM_OSSRState = TIM_OSSRState_Enable; tim_bdtr.TIM_OSSIState = TIM_OSSIState_Enable; tim_bdtr.TIM_LOCKLevel = TIM_LOCKLevel_OFF; tim_bdtr.TIM_DeadTime = 10; tim_bdtr.TIM_Break = TIM_Break_Disable; tim_bdtr.TIM_BreakPolarity = TIM_BreakPolarity_High; tim_bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &tim_bdtr); TIM_CCPreloadControl(TIM1, ENABLE); /* Enable COM and CC interrupt */ TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE); //TIM_ITConfig(TIM1, TIM_IT_COM | TIM_IT_CC4, ENABLE); /* TIM1 enable counter */ TIM_Cmd(TIM1, ENABLE); /* Main output enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Setting default state of pwm to pwm_off */ pwm_off(); }
void TMER_Iinitialization(void) { //GPIO GPIO_InitTypeDef GPIO_InitStructure; //Interrupt NVIC_InitTypeDef NVIC_InitStructure; //Tmer TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //死区刹车结构体变量定义 TIM_OCInitTypeDef TIM_OCInitStructure; // TIM_ICInitTypeDef TIM_ICInitStructure; //定义结构体变量 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /************************************************************************** //---------------------------------TMER1 PWM------------------------------- ***************************************************************************/ PWM_Period=((SystemCoreClock / (2*PWM_FREQ) ) - 1); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE); /* TIM2 Configuration */ TIM_DeInit(TIM1); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_OCStructInit(&TIM_OCInitStructure); /* GPIOA Configuration: Channel 1, 2, 3, 4 and Channel 1N as alternate function push-pull */ GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); /* GPIOB Configuration: Channel 2N and 3N as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14| GPIO_Pin_15; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_2); //TRIP GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_2); /*----------------------------------------------------------------------- */ /* Compute the value to be set in ARR regiter to generate signal frequency at 12 Khz */ TIM_TimeBaseStructure.TIM_Prescaler = 0; //TIM基本初始化 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;//中央对齐计数模式 TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 1; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //TIM输出通道初始化 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse =200; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(TIM1,&TIM_OCInitStructure); TIM_OC2Init(TIM1,&TIM_OCInitStructure); TIM_OC3Init(TIM1,&TIM_OCInitStructure); TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //TIM输出通道4初始化,用来触发AD采样 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 24; //100; // TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC4Init(TIM1,&TIM_OCInitStructure); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; //死区刹车初始化 TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = DEADTIME; //96-2us TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; // TIM_Break_Disable;// TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure); TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); //使能捕获比较寄存器预装载(通道1) TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable); //使能捕获比较寄存器预装载(通道2) TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable); //使能捕获比较寄存器预装载(通道3) /* Enable the TIM1 Trigger and commutation interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ClearITPendingBit(TIM1, TIM_IT_Break); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM1, TIM_IT_Break, ENABLE); TIM_ClearFlag(TIM1, TIM_FLAG_Update); // 清除TIM2的更新标志位 ; TIM_ClearFlag(TIM1, TIM_FLAG_Break); TIM_ClearFlag(TIM1, TIM_FLAG_COM); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); }
void PWM1_Config(int period) { /* ----------------------------------------------------------------------- 1/ Generate 3 complementary PWM signals with 3 different duty cycles: In this example TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1 (APB2 Prescaler = 2, see system_stm32f4xx.c file). TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = 2*(HCLK / 2) = HCLK = SystemCoreClock To get TIM1 counter clock at 168 MHz, the prescaler is computed as follows: Prescaler = (TIM1CLK / TIM1 counter clock) - 1 Prescaler = (SystemCoreClock / 168 MHz) - 1 = 0 The objective is to generate PWM signal at 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 To get TIM1 output clock at 17.57 KHz, the period (ARR) is computed as follows: ARR = (TIM1 counter clock / TIM1 output clock) - 1 = 9561 The Three Duty cycles are computed as the following description: TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100 = 50% TIM1 Channel2 duty cycle = (TIM1_CCR2/ TIM1_ARR)* 100 = 25% TIM1 Channel3 duty cycle = (TIM1_CCR3/ TIM1_ARR)* 100 = 12.5% The Timer pulse is calculated as follows: - TIM1_CCRx = (DutyCycle * TIM1_ARR)/ 100 2/ Insert a dead time equal to (11/SystemCoreClock) ns 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parameters level1. Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Time Base configuration */ uint16_t PrescalerValue = 0; /* Compute the prescaler value */ PrescalerValue = (uint16_t)((SystemCoreClock / 2) / 1600000) - 1; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = period; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1to 4 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel4Pulse; TIM_OC4Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* ----------------------------------------------------------------------- TIM1 Configuration to: 1/ Generate 3 complementary PWM signals with 3 different duty cycles: TIM1CLK is fixed to SystemCoreClock, the TIM1 Prescaler is equal to 0 so the TIM1 counter clock used is SystemCoreClock. * SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density and Connectivity line devices. For Low-Density Value line and Medium-Density Value line devices, SystemCoreClock is set to 24 MHz. The objective is to generate PWM signal at 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 The Three Duty cycles are computed as the following description: The channel 1 duty cycle is set to 50% so channel 1N is set to 50%. The channel 2 duty cycle is set to 25% so channel 2N is set to 75%. The channel 3 duty cycle is set to 12.5% so channel 3N is set to 87.5%. The Timer pulse is calculated as follows: - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 2/ Insert a dead time equal to 11/SystemCoreClock ns 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parameters level1. ----------------------------------------------------------------------- */ /* Compute the value to be set in ARR register to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570) - 1; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) { } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* TIM1 and Timers(TIM3 and TIM4) synchronisation in parallel mode ----------- 1/TIM1 is configured as Master Timer: - PWM Mode is used - The TIM1 Update event is used as Trigger Output 2/TIM3 and TIM4 are slaves for TIM1, - PWM Mode is used - The ITR0(TIM1) is used as input trigger for both slaves - Gated mode is used, so starts and stops of slaves counters are controlled by the Master trigger output signal(update event). o For Low-density, Medium-density, High-density and Connectivity line devices: The TIMxCLK is fixed to 72 MHz, Prescaler = 0 so the TIM1 counter clock is 72 MHz. The Master Timer TIM1 is running at: TIM1 frequency = TIM1 counter clock / (TIM1_Period + 1) = 281.250 KHz and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50% The TIM3 is running at: (TIM1 frequency)/ ((TIM3 period +1)* (Repetion_Counter+1)) = 18.750 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 33.3% The TIM4 is running at: (TIM1 frequency)/ ((TIM4 period +1)* (Repetion_Counter+1)) = 28.125 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 50% o For Low-Density Value line and Medium-Density Value line devices: The TIMxCLK is fixed to 24 MHz, Prescaler = 0 so the TIM1 counter clock is 24 MHz. TIM1 frequency = 93.75 KHz TIM3 frequency = 6.25 KHz TIM4 frequency = 9.375 KHz --------------------------------------------------------------------------- */ /* TIM3 Peripheral Configuration ----------------------------------------*/ /* TIM3 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 2; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); /* TIM4 Peripheral Configuration ----------------------------------------*/ /* TIM4 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0); /* TIM1 Peripheral Configuration ----------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 4; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 127; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 5; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* TIM1 and Timers(TIM3 and TIM4) synchronisation in parallel mode ----------- 1/TIM1 is configured as Master Timer: - PWM Mode is used - The TIM1 Update event is used as Trigger Output 2/TIM3 and TIM4 are slaves for TIM1, - PWM Mode is used - The ITR0(TIM1) is used as input trigger for both slaves - Gated mode is used, so starts and stops of slaves counters are controlled by the Master trigger output signal(update event). TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz The Master Timer TIM1 is running at: TIM1 frequency = TIM1 counter clock / (TIM1_Period + 1) = 281.250 KHz and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50% The TIM3 is running: - At (TIM1 frequency)/((TIM3 period + 1)* (Repetion_Counter+1)) = 18.750 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 33.3% The TIM4 is running: - At (TIM1 frequency)/((TIM4 period + 1)* (Repetion_Counter+1)) = 28.125 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 50% --------------------------------------------------------------------------- */ /* TIM3 Peripheral Configuration ----------------------------------------*/ /* TIM3 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 2; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); /* TIM4 Peripheral Configuration ----------------------------------------*/ /* TIM4 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0); /* TIM1 Peripheral Configuration ----------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 4; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 127; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 5; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* ----------------------------------------------------------------------- TIM1 Configuration to: 1/ Generate 3 complementary PWM signals with 3 different duty cycles: TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz TIM1 frequency = TIM1CLK/(TIM1_Period + 1) = 1.098 KHz TIM1 Channel1 duty cycle = TIM1->CCR1 / TIM1_Period = 50% TIM1 Channel1N duty cycle = (TIM1_Period - TIM1_CCR1) / (TIM1_Period + 1) = 50% TIM1 Channel2 duty cycle = TIM1_CCR2 / TIM1_Period = 25% TIM1 Channel2N duty cycle = (TIM1_Period - TIM1_CCR1) / (TIM1_Period + 1) = 75% TIM1 Channel3 duty cycle = TIM1_CCR3 / TIM1_Period = 12.5% TIM1 Channel3N duty cycle = (TIM1_Period - TIM1_CCR3) / (TIM1_Period + 1) = 87.5% 2/ Insert a dead time equal to 1.62 us 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parametres level1. ----------------------------------------------------------------------- */ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2,3 and 4 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 117; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) { } }
void initPWM() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); //initialize Tim1 PWM outputs GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // Time Base configuration TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = BLDC_CHOPPER_PERIOD; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // Channel 1, 2, 3 – set to PWM mode - all 6 outputs TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; // initialize to zero output TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OC4Init(TIM1, &TIM_OCInitStructure); //for ADC TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; // DeadTime[ns] = value * (1/SystemCoreFreq) (on 72MHz: 7 is 98ns) TIM_BDTRInitStructure.TIM_DeadTime = BLDC_NOL; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //no break functionality TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); //Commutation event mapped to TIM4 - We are not using commute event, but interrupt from Hall timer directly to commute. //Not optimal solution? //TIM_SelectInputTrigger(TIM1, TIM_TS_ITR3); TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE); //adc sampling interrupt NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM1, ENABLE); // enable motor timer main output (the bridge signals) TIM_CtrlPWMOutputs(TIM1, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* NVIC Configuration */ NVIC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* SysTick Configuration */ SysTick_Configuration(); /*----------------------------------------------------------------------------- The STM32F10x TIM1 peripheral offers the possibility to program in advance the configuration for the next TIM1 outputs behaviour (step) and change the configuration of all the channels at the same time. This operation is possible when the COM (commutation) event is used. The COM event can be generated by software by setting the COM bit in the TIM1_EGR register or by hardware (on TRC rising edge). In this example, a software COM event is generated each 100 ms: using the Systick interrupt. The TIM1 is configured in Timing Mode, each time a COM event occurs, a new TIM1 configuration will be set in advance. The following Table describes the TIM1 Channels states: ----------------------------------------------- | Step1 | Step2 | Step3 | Step4 | Step5 | Step6 | ---------------------------------------------------------- |Channel1 | 1 | 0 | 0 | 0 | 0 | 1 | ---------------------------------------------------------- |Channel1N | 0 | 0 | 1 | 1 | 0 | 0 | ---------------------------------------------------------- |Channel2 | 0 | 0 | 0 | 1 | 1 | 0 | ---------------------------------------------------------- |Channel2N | 1 | 1 | 0 | 0 | 0 | 0 | ---------------------------------------------------------- |Channel3 | 0 | 1 | 1 | 0 | 0 | 0 | ---------------------------------------------------------- |Channel3N | 0 | 0 | 0 | 0 | 1 | 1 | ---------------------------------------------------------- -----------------------------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 4095; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2,3 and 4 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 2047; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = 1023; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = 511; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = 1; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_CCPreloadControl(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* ----------------------------------------------------------------------- TIM15 Configuration to: 1/ Generate a complementary PWM signals with 50% duty cycles: TIM15CLK = 24 MHz, Prescaler = 0, TIM15 counter clock = 24 MHz TIM15 frequency = TIM15CLK/(TIM15_Period + 1) = 366 Hz TIM15 Channel1 duty cycle = TIM15->CCR1 / TIM15_Period = 50% TIM15 Channel1N duty cycle = (TIM15_Period - TIM15_CCR1) / (TIM15_Period + 1) = 50% 2/ Insert a dead time equal to 1.62 us 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parametres level1. ----------------------------------------------------------------------- */ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM15, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 39; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM15, &TIM_BDTRInitStructure); /* TIM15 counter enable */ TIM_Cmd(TIM15, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM15, ENABLE); while (1) { } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM1 Configuration */ TIM_Config(); /* --------------------------------------------------------------------------- TIM1 and Timers(TIM3 and TIM4) synchronisation in parallel mode. 1/TIM1 is configured as Master Timer: - PWM Mode is used - The TIM1 Update event is used as Trigger Output 2/TIM3 and TIM4 are slaves for TIM1, - PWM Mode is used - The ITR0(TIM1) is used as input trigger for both slaves - Gated mode is used, so starts and stops of slaves counters are controlled by the Master trigger output signal(update event). In this example TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = HCLK = SystemCoreClock The TIM1 counter clock is equal to SystemCoreClock = 168 Mhz. The Master Timer TIM1 is running at: TIM1 frequency = TIM1 counter clock / (TIM1_Period + 1) = 656 KHz TIM1_Period = (TIM1 counter clock / TIM1 frequency) - 1 = 255 and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50% The TIM3 is running at: (TIM1 frequency)/ ((TIM3 period +1)* (Repetition_Counter+1)) = 43.730 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 33.3% The TIM4 is running at: (TIM1 frequency)/ ((TIM4 period +1)* (Repetition_Counter+1)) = 65.600 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 50% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /* TIM3 Peripheral Configuration ----------------------------------------*/ /* TIM3 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 2; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); /* TIM4 Peripheral Configuration ----------------------------------------*/ /* TIM4 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0); /* TIM1 Peripheral Configuration ----------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 4; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 127; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 5; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f30x.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f30x.c file */ /* GPIOA and GPIOB clocks enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* GPIOA Configuration: Channel 1, 2 and 3 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* GPIOA Configuration: BKIN and channel 1N as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure); /* GPIOB Configuration: 2N and 3N as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect TIM pins to AF6 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_6); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_6); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_6); /* --------------------------------------------------------------------------- TIM1 Configuration to: 1/ Generate 3 complementary PWM signals with 3 different duty cycles: TIM1 input clock (TIM1CLK) is set to APB2 clock (PCLK2). TIM1CLK = PCLK2 PCLK2 = HCLK => TIM1CLK = HCLK = SystemCoreClock TIM1CLK is fixed to SystemCoreClock, the TIM1 Prescaler is equal to 0 so the TIM1 counter clock used is SystemCoreClock (48MHz). The objective is to generate PWM signal at 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 The Three Duty cycles are computed as the following description: The channel 1 duty cycle is set to 50% so channel 1N is set to 50%. The channel 2 duty cycle is set to 25% so channel 2N is set to 75%. The channel 3 duty cycle is set to 12.5% so channel 3N is set to 87.5%. The Timer pulse is calculated as follows: - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 2/ Insert a dead time equal to (11/SystemCoreClock) ns 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parameters level1. Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f30x.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /* Compute the value to be set in ARR register to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570) - 1; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Infinite loop */ while (1) { } }