STM32アドバンストタイマー出力PWM波

素人なので間違い等ありましたらご指摘ください。

目次

1. タイマのピン配置図

2.全体の枠組み

2.1 タイムベースモジュール

2.2 コンペアレジスタ

2.3 デッドゾーンジェネレータ

2.4 出力制御

3. 構造

4. プログラミング

5.説明


1. タイマのピン配置図

2.全体の枠組み

注: アドバンストタイマは、一般タイマのインプットキャプチャ機能、出力比較機能に加え、プログラマブルデッドゾーン相補出力機能、繰り返しカウンタ機能、ブレーキ(サーキットブレーク)機能を追加しています。本記事では出力比較機能のみを取り上げます。

アドバンストタイマのフレームワークを、タイムベースモジュール、比較レジスタ、デッドゾーンジェネレータ、出力制御の4つの部分に分けます。

2.1 タイムベースモジュール

アドバンスト タイマ クロック ソースは 4 つありますが、ここでは内部クロック ソースのみを紹介します。

 タイムベースユニットのフレームは図のとおりです

これを 4 つの部分に分割します。 1. プリスケーラー PSC。1 ~ 65536 の周波数分割を実現できます。2. カウンタ CNT: アップカウント モード、ダウンカウント モード、アップ/ダウン (中央揃え) カウント モードの 3 つのカウント モード。3. 自動リロードレジスタ ARR および 4. リピートカウンタ RCR

ここで基本的なタイマーと異なるのは、3 つのカウント モードと繰り返しカウンターです。

平たく言えば、ループは 0 (または最大値) から始まり、上方向 (または下方向) にカウントされます。最大値 (または 0) に達すると、割り込みまたはイベントが発生します。繰り返しカウンターが使用される場合、特定の回数がカウントされ、その回数に応じて割り込み1またはイベントが発生します。カウントアップまたはカウントダウンはカウントモードによって異なります。

今回はPWM波を出力するため割り込みを使う必要はなく、カウント機能だけで十分です。

2.2 コンペアレジスタ

カウンタ CNT の値と比較レジスタ CCR の値が等しい場合、出力リファレンス信号 OCxREF の極性が変化します。OCxREF=1 (ハイレベル) を有効レベル、OCxREF=0 (ローレベル) をフラットといいます。を無効レベルといいます。

ここで出力される信号は OCxREF です。

デッドゾーンジェネレーターに入る前に、出力比較モードを設定することができ、PWM 波を出力する場合、PWM1 と PWM2 の 2 つのモードから選択できます。

2.3 デッドゾーンジェネレータ

デッド ゾーン ジェネレーターを通過すると、デッド ゾーンを持つ 2 つの相補信号 OCx_DT と OCxN_DT が生成されます。デッド ゾーン制御が追加されない場合、出力制御回路に入力される信号は直接 OCxREF になります。

単純な PWM 波についてはここでは詳しく紹介しません。

2.4 出力制御

デッド ゾーン ジェネレーターによって出力される信号は 2 つのチャネルに分割され、1 つは元の信号で、もう 1 つは反転信号であり、レジスタ CCER のビット CCxP および CCxNP によって具体的に制御されます。極性選択信号を OCx 端子から外部端子 CHx/CHxN に出力するかどうか (つまり有効にするか) は、レジスタ CCER の CxE/CxNE ビットで設定します。

3. 構造

typedef struct
{
  uint16_t TIM_Prescaler;        //时钟预分频,对应PSC
                                 
  uint16_t TIM_CounterMode;      //时钟计数模式,对应3中计数方法
                                 
  uint16_t TIM_Period;           //定时器周期,对应ARR寄存器
                                                             
  uint16_t TIM_ClockDivision;    //时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤 
                                 //波器,采样时钟频率分频比。可以选择 1、2、4 分频。

  uint8_t TIM_RepetitionCounter; //重复计数器,对应RAR
                                                                 
} TIM_TimeBaseInitTypeDef;       

typedef struct
{
  uint16_t TIM_OCMode;          //输出模式,PWM1及PWM2,对应寄存器CCMR1->OCxM
                             
  uint16_t TIM_OutputState;     //比较输出使能,对应CCER->CCxE
                             
  uint16_t TIM_OutputNState;    //比较互补输出使能,对应CCER->CCxNE
                              
  uint16_t TIM_Pulse;           //脉冲宽度,即比较寄存器的值,对应CCR1
                             
  uint16_t TIM_OCPolarity;      //输出极性,对应CCER->CCxP

  uint16_t TIM_OCNPolarity;     //互补输出极性,对应CCER->CCxP

  uint16_t TIM_OCIdleState;     //空闲状态比较输出状态,对应CR2->OIS1

  uint16_t TIM_OCNIdleState;    //空闲状态下比较互补输出状态,对应CR2->OIS1N
                               
} TIM_OCInitTypeDef;

 pwm の設定に使用される主な構造は 2 つあり、1 つはタイムベース初期化構造、もう 1 つは出力比較構造、およびタイムベース初期化構造です。

出力比較の構造は、以下に示す図のレジスタに対応します。

 ただし、これら 2 つの構造に加えて、レジスタも有効にする必要があります。 

BDER->MOE レジスタに対応し、公式の紹介は次のとおりです

 出力ピンを有効にするだけです

4. プログラミング

要約すると、プログラミングの目標は次のとおりです。

1. チャネルの GPIO ピンを構成します。

2. 2 つの構造を構成する

3. クロックソースを有効にし、出力チャネルを有効にします。

次のプログラムは、1Khz、デューティ サイクル 40% の PWM 波を構成します。

void advance_tim1_gpio_config(void)
{
	//1.结构体
	GPIO_InitTypeDef GPIO_InitStructure;
	
	//2.开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	//3.配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		
	//4.初始化
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//5.使能(无)	
}

void advance_tim1_mode_config()
{
	//1.结构体,时基结构体及输出比较结构体
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	//2.开时钟,TIM1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	
	//3.配置及初始化
	/*--------------------时基结构体初始化-------------------------*/
	// PWM 信号的频率 F = TIM_CLK/{(ARR+1)*(PSC+1)}
	
	TIM_TimeBaseStructure.TIM_Period = 9;	                      //ARR寄存器的值
	TIM_TimeBaseStructure.TIM_Prescaler = 7199;	                  //PSC分频的值
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //向上计数
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;                //重复计数器为0
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
	
	/*--------------------输出比较结构体初始化-------------------*/
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;             //输出模式:PWM1
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_Pulse = 4;			                  //设置占空比
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //有效电平
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;  //空闲时比较输出状态
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);

	//4.使能,此处使能为将内部时钟作为TIM1时钟源的使能
	TIM_Cmd(TIM1, ENABLE);									      //使能计数器
	TIM_CtrlPWMOutputs(TIM1, ENABLE);				              //使能输出通道
}

注: ARR レジスタと PSC レジスタは 0 からカウントを開始するため、値を 1 減らす必要があります。

PWM波周波数=TIM_CLK/{(ARR+1)*(PSC+1)}

このうち、TIM1 は APB2 に実装されており、APB2 は一般的に 72Mhz であるため、TIM_CLK は一般的に APB2 の周波数になります。

デューティ サイクル=TIM_OCInitStructure.TIM_Pulse/(ARR+1)

PWM 波形を個人的に設定するには、通常は次の手順に従います。

1. PWM波の周波数を確認する

2. PWM波形の精度を確認(ARRレジスタに相当)

3. デューティ サイクル TIM_OCInitStructure.TIM_Pulse を確認します。

さらに、デューティ サイクルを特別に変更する (つまり、TIM_OCInitStructure.TIM_Pulse の値を変更する) 関数がありますが、これまで知らなかったので、自分で作成しました (この落とし穴は避けてください)。

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);

5.説明

この記事で説明したレジスタに加えて、TIM_OC1PreloadConfi() などのいくつかのプリロード関数もあります。

待てよ、この関数は CCMR->OC1PE に相当しますが、この関数は当面必要ないので詳しくは紹介しません。 

公式の説明は次のとおりです。また、タイムベース ユニットの場合、特定のレジスタの下にシャドウが存在します。対応するシャドウ レジスタについては詳しく説明しません。

PWM波形制御ESCについては後日記事を掲載します。

参考文献には、「STM32F10x-中国語リファレンス マニュアル」および「STM32 ライブラリ開発実践ガイド - Wildfire ガイド開発ボードに基づく」が含まれます。

おすすめ

転載: blog.csdn.net/qq_62573253/article/details/126335766
おすすめ