//ポートをAFで使用する場合の設定
void Init_af_port(GPIO_TypeDef *port,uint16_t pin,uint8_t af,uint16_t mode){
	GPIO_InitTypeDef GPIO_InitStructure;					//GPIO初期化のための構造体
//	uint8_t pin;

	RCC_PeriphClock_GPIO(port);
	GPIO_StructInit(&GPIO_InitStructure);					//初期化用構造体にパラメータをセットしていくため、いったん初期値に戻す

	if((mode&0x0f) == PORT_PP){
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//出力ポートのタイプをプッシュプルに指定する
	}else if((mode&0x0f )== PORT_OD){
		GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;		//出力ポートのタイプをプッシュプルに指定する
	}

	if((mode&0xf0) == PORT_PULL_UP){
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	}else if((mode&0xf0) == PORT_PULL_DOWN){
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
	}else if((mode&0xf0) == PORT_PULL_NO){
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	}

	GPIO_InitStructure.GPIO_Pin = pin;						//設定するピンを指定する(スイッチのピン・アクティブハイ)
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;		//指定したピンを出力に指定する
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;		//GPIOのスピードを100MHz(最高速)にセットする
	GPIO_Init(port, &GPIO_InitStructure);					//PORT設定入力

	GPIO_PinAFConfig(port,Pin_select_source(pin),af);
}
Exemple #2
0
/******************************************************************************
*	タイトル : USART設定
*	  関数名 : Init_USART
*	   引数1 : USART_TypeDef型 *USARTx  USART番号
*	   引数2 : unsigned int型 baudrate  ボーレート
*	   引数3 : GPIO_TypeDef型 *GPIOx_TX  TXポート
*	   引数4 : uint16_t型 pin_TX  TXピン
*	   引数5 : GPIO_TypeDef型 *GPIOx_RX  RXポート
*	   引数6 : uint16_t型 pin_RX  RXピン
*	  作成者 : 石井岳史
*	  作成日 : 2014/11/12
******************************************************************************/
void Init_USART(USART_TypeDef *USARTx,unsigned int baudrate, GPIO_TypeDef *GPIOx_TX ,uint16_t pin_TX, GPIO_TypeDef *GPIOx_RX, uint16_t pin_RX){
	//構造体変数を宣言
	USART_InitTypeDef 	USART_InitStructure;
	NVIC_InitTypeDef 	NVIC_InitStructure;

	//モジュールストップ状態の解除
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_PeriphClock_USART(USARTx);
	//GPIOの設定
	Init_port(GPIO_Mode_AF,GPIOx_TX,pin_TX,GPIO_PuPd_NOPULL,GPIO_OType_PP);
	Init_port(GPIO_Mode_AF,GPIOx_RX,pin_RX,GPIO_PuPd_NOPULL,GPIO_OType_PP);

	//PINをオルタネィテブファンクションに割り当て

	GPIO_PinAFConfig(GPIOx_TX, Pin_select_source(pin_TX), GPIO_af_USART_select(USARTx));//USART1 TX/PB6
	GPIO_PinAFConfig(GPIOx_RX, Pin_select_source(pin_RX), GPIO_af_USART_select(USARTx));//USART1 RX/PB7


	//USART1の設定
	USART_InitStructure.USART_BaudRate 				= baudrate;							//ボーレートの設定
	USART_InitStructure.USART_WordLength 			= USART_WordLength_8b;				//ビット長
	USART_InitStructure.USART_StopBits 				= USART_StopBits_1;					//ストップビットの長さ
	USART_InitStructure.USART_Parity 				= USART_Parity_No;					//パリティの有無
	USART_InitStructure.USART_HardwareFlowControl 	= USART_HardwareFlowControl_None;	//ハードウェアフロー制御の有無
	USART_InitStructure.USART_Mode 					= USART_Mode_Rx | USART_Mode_Tx;	//送信受信の選択
	USART_Init(USARTx, &USART_InitStructure);											//USART1の設定
	USART_Cmd(USARTx, ENABLE);															//USART1周辺回路の有効化
	USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);										//USART1周辺回路の割込み有効化

	//割り込み設定
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);							//優先度のビット設定
	NVIC_InitStructure.NVIC_IRQChannel 						= USART_irqn_select(USARTx);	//有効化するIRQチャンネルの指定
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 	= 2;			//割り込みの優先順位(グループ)の指定。0が最優先
	NVIC_InitStructure.NVIC_IRQChannelSubPriority 			= 0;			//割り込みの優先順位(サブ)の指定。0が最優先
	NVIC_InitStructure.NVIC_IRQChannelCmd 					= ENABLE;		//割り込みの有効化
	NVIC_Init(&NVIC_InitStructure);											//割り込み設定
}
Exemple #3
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;
}
Exemple #4
0
void Init_CAN(int can_num,uint8_t CAN_Mode,GPIO_TypeDef *tx_port,uint16_t tx_pin,GPIO_TypeDef *rx_port,uint16_t rx_pin){

	/* Define InitTypeDef ---------------------------------------------------*/
	CAN_InitTypeDef 		CAN_InitStructure;

	/* initialize InitTypeDef -----------------------------------------------*/
	CAN_StructInit(&CAN_InitStructure);
	/* Supply clock source --------------------------------------------------*/
	if(can_num == 1){
		CAN_DeInit(CAN1);
		RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN1, ENABLE);
	}else if(can_num == 2){
		CAN_DeInit(CAN2);
		RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN2, ENABLE);
	}
	/* Define gpio_config ---------------------------------------------------*/
	
	Init_port(GPIO_Mode_AF,tx_port,tx_pin,GPIO_PuPd_UP,GPIO_OType_PP);
	Init_port(GPIO_Mode_AF,rx_port,rx_pin,GPIO_PuPd_UP,GPIO_OType_PP);

	if(can_num == 1){
		GPIO_PinAFConfig(tx_port, Pin_select_source(tx_pin), GPIO_AF_CAN1);//Tx
		GPIO_PinAFConfig(rx_port, Pin_select_source(rx_pin), GPIO_AF_CAN1);//Rx
	}else if(can_num == 2){
		GPIO_PinAFConfig(tx_port, Pin_select_source(tx_pin), GPIO_AF_CAN2);//Tx
		GPIO_PinAFConfig(rx_port, Pin_select_source(rx_pin), GPIO_AF_CAN2);//Rx
	}
	/* Set up CAN function -------------------------------------------------*/
	/* タイムトリガ通信モードの有効化・無効化を設定する */
	CAN_InitStructure.CAN_TTCM 		= ENABLE;

	/* 自動バスオフ管理(Automatic Bus-Off Management)の有効化・無効化を設定する */
	CAN_InitStructure.CAN_ABOM 		= DISABLE;

	/* 自動再起動モードの有効化・無効化を設定する  */
	CAN_InitStructure.CAN_AWUM 		= DISABLE;

	/* 自動再送信禁止を有効化・無効化する DISABLE: 自動再送信禁止を無効化(つまり再送信は有効) ENABLE: 自動再送信禁止。正常に送信されなくても送信は1回だけ行われる */
	CAN_InitStructure.CAN_NART 		= DISABLE;

	/* 受信FIFOロックモードの有効化・無効化を設定する */
	CAN_InitStructure.CAN_RFLM 		= DISABLE;

	/* 送信FIFOの送信順序を指定する。DISABLE:メッセージIDで送信順序が決定される  ENABLE:ソフトウェアで送信要求が発生された順番で送信される */
	CAN_InitStructure.CAN_TXFP 		= DISABLE;

	/* CANのModeを設定する */
//	CAN_InitStructure.CAN_Mode 		= CAN_Mode_Normal;
	CAN_InitStructure.CAN_Mode 		= CAN_Mode;

	/* 再同期ジャンプ幅(CANハードウェアが再同期を行う際のビット幅)を時間単位の数で設定する */
	CAN_InitStructure.CAN_SJW 		= CAN_SJW_1tq;

	/* CANビットタイミングレジスタ(CAN_BTR)のTS1[3:0]を設定する。 */
	CAN_InitStructure.CAN_BS1 		= CAN_BS1_6tq;

	/* CANビットタイミングレジスタ(CAN_BTR)のTS2[2:0]を設定する */
	CAN_InitStructure.CAN_BS2 		= CAN_BS2_7tq;

	/* ボーレートプリスケーラ設定する 1〜1024 APB1=42MHz*/
	CAN_InitStructure.CAN_Prescaler	= 3;
	//1Mbps

	if(can_num == 1){
		CAN_Init(CAN1, &CAN_InitStructure);
	}else if(can_num == 2){
		CAN_Init(CAN2, &CAN_InitStructure);
	}



#ifdef USE_INTERRUPT_CAN_RX
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

	if(can_num == 1){
		NVIC_Configuration(CAN1_RX0_IRQn);
		CAN_ITConfig(CAN1, CAN_IT_FMP0,ENABLE);//message pending Interrupt
		/*
		CAN_ITConfig(CAN1, CAN_IT_EWG, ENABLE);//Error passive Interrupt
		CAN_ITConfig(CAN1, CAN_IT_EPV, ENABLE);//Error passive Interrupt
		CAN_ITConfig(CAN1, CAN_IT_BOF, ENABLE);//Bus-off Interrupt
		CAN_ITConfig(CAN1, CAN_IT_LEC, ENABLE);//tLast error code Interrupt
		CAN_ITConfig(CAN1, CAN_IT_ERR, ENABLE);//Error Interrupt
		*/
	}else if(can_num == 2){
		NVIC_Configuration(CAN2_RX0_IRQn);
		CAN_ITConfig(CAN2, CAN_IT_FMP0,ENABLE);//message pending Interrupt
		/*
		CAN_ITConfig(CAN2, CAN_IT_EWG, ENABLE);//Error passive Interrupt
		CAN_ITConfig(CAN2, CAN_IT_EPV, ENABLE);//Error passive Interrupt
		CAN_ITConfig(CAN2, CAN_IT_BOF, ENABLE);//Bus-off Interrupt
		CAN_ITConfig(CAN2, CAN_IT_LEC, ENABLE);//tLast error code Interrupt
		CAN_ITConfig(CAN2, CAN_IT_ERR, ENABLE);//Error Interrupt
		*/
	}
#endif

#ifdef USE_INTERRUPT_CAN_TX
	if(can_num == 1){
		CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);//Transmit mailbox empty Interrupt
	}else if(can_num == 2){
		CAN_ITConfig(CAN2, CAN_IT_TME, ENABLE);//Transmit mailbox empty Interrupt
	}
#endif

}