示例#1
0
文件: pwm.c 项目: sedulity11/pdb
// set the output enable - this is only required for TIM1 | TIM8
void pwmBDTRInit(const TIM_TypeDef *tim) {
    TIM_BDTRInitTypeDef TIM_BDTRInitStruct;

    TIM_BDTRStructInit(&TIM_BDTRInitStruct);
    TIM_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
    TIM_BDTRInitStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
    TIM_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Enable;
    TIM_BDTRConfig((TIM_TypeDef *)tim, &TIM_BDTRInitStruct);
}
示例#2
0
文件: config.c 项目: EGQM/foc_esc
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);
}
示例#3
0
/**
  * @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);
}
示例#4
0
/******************************************************************************
*	タイトル : 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;
}
/*
    Инициализация таймера и ШИМ
   
*/
extern "C" void hal_TIM2_Init(void)
{
  
     GPIO_InitTypeDef  GPIO_InitStructure;
     TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
     TIM_OCInitTypeDef TIM_OC_InitStructure;
     TIM_BDTRInitTypeDef TIM_BDTRInitStructure;


   
     //Initialize clocks for TIM2
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  
     
     //Initialize clocks for GPIOA, AFIO
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
     
     
     /*
     //Configure pin TIM2 CH1 = PA0 as alternative function push-pull
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
     GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
           */   
     //GPIO_Init(GPIOA, &GPIO_InitStructure);   
     
     
     //Configure TIM2 time base
     TIM_DeInit(TIM2);
     TIM_TimeBaseStructInit( &TIM_TimeBase_InitStructure );
     TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
     TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBase_InitStructure.TIM_Period = 65000;   
     TIM_TimeBase_InitStructure.TIM_Prescaler = 0;

     TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);
     
     
     
     
      TIM_OCStructInit( &TIM_OC_InitStructure );
      TIM_OC_InitStructure.TIM_Pulse        = 130;
      TIM_OC_InitStructure.TIM_OCMode       = TIM_OCMode_PWM1;
      TIM_OC_InitStructure.TIM_OutputState  = TIM_OutputState_Enable;
      TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Enable;

      //TIM_OC1Init(TIM2, &TIM_OC_InitStructure);
     
  
      
      // Automatic Output enable, Break, dead time and lock configuration   
      TIM_BDTRStructInit(&TIM_BDTRInitStructure);
      TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;   
      //TIM_BDTRConfig(TIM2, &TIM_BDTRInitStructure); 
      
      
 
     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);    /* Enable the TIM Update Interrupt */
     
     
     /* 1 bit for pre-emption priority, 3 bits for subpriority */
     NVIC_SetPriorityGrouping(1); 

       /* Enable the TIM2 Interrupt */
     NVIC_SetPriority(TIM2_IRQn, 0x01); /* 0x00 = 0x01 << 3 | (0x00 & 0x7*/
     
     NVIC_EnableIRQ(TIM2_IRQn);          /* Enable TIM2 interrupt */
  
     
 
     
     
     TIM_Cmd(TIM2, ENABLE);  /* TIM counter enable */          
     
     return;
  
}