コンセプト+コード
1. 出力比較
OC (Output Compare) 出力比較 出力比較は、
CNT と CCR レジスタの値の関係を比較することにより、出力レベルを 1 に設定したり、0 に設定したり、動作を反転したりすることができ、特定の周波数とデューティ サイクルの PWM 波形を出力するために使用されます。
アドバンストタイマと汎用タイマの両方に4つのアウトプットコンペアチャネルがあり、
アドバンストタイマの最初の3チャネルにはデッドゾーン生成機能と相補出力機能が追加されています。
2. PWMの原理
PWM (Pulse width Modulation) パルス幅変調
慣性のあるシステムでは、一連のパルスの幅を変調することで必要なアナログ パラメータを等価的に取得でき、モータの速度制御などの分野でよく使用されます PWM パラメータ :
周波数
= 1 / TS
デューティ サイクル = TON / TS (合計時間に対するハイ レベルの比率)、デューティ サイクルが 50%、ハイ レベル = 5V、ロー レベル = 0V の場合、アナログ電圧は 2.5V になります。 分解能率 =
デューティサイクル変更ステップ、つまり精度。
PWM の基本構造:
CNT カウントが CCR 未満の場合はハイ レベルに設定され、CNT が CCR より大きい場合はロー レベルに設定されます。CNT=ARR がイベントをトリガーすると、カウント値は 0 に戻り、新しいサイクルが開始されます。 、PWM信号を連続的に出力できるようになります。したがって、 CCR 値の設定はデューティ サイクルと密接に関係していることがわかります。
PWM 周波数: Freq = CK_PSC / (PSC + 1) / (ARR + 1)
CK_PSC はプリスケーラー周波数で、通常はシステム周波数です。PSC は分周係数、ARR はオートリロードレジスタの最大カウント値です。
PWM デューティ比: Duty = CCR / (ARR + 1)
CCR は、アウトプットコンペア出力 PWM の制限された比較値です。
PWM分解能: Reso = 1 / (ARR + 1)
3. 出力PWM
例として、定時アトミック PWM 実験を取り上げます。TIM3 の CH2 チャネルを使用して、PB5 ポートで PWM 波を出力します。
1. PWMの初期化
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5
//设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
//溢出时间time=(arr+1)*(psc+1)/144000000
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_Pulse = 50;
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
ここで最も重要なことは次のとおりです。
1. この関数のパラメータは arr と psc で、それぞれ自動リロード レジスタの値とプリスケーラ係数を表します。これら 2 つのパラメータに従って、PWM の周波数とデューティ サイクルを計算できます。
2. この関数では、まずタイマー TIM3 と GPIOB ペリフェラルのクロック、および GPIO の多重化機能モジュールのクロックを有効にします。次に、GPIO_PinRemapConfig 関数を使用して、TIM3_CH2 信号を GPIOB.5 ピンにマップします。
ここで質問があります。なぜ AFIO 多重化機能モジュールのクロックを設定するのですか? 以下の図に
示すように、PB5 のデフォルトの多重化機能は I2C1_SMBA/SPI3_MOSI、I2S3_SD であり、その再定義機能は TIM3_CH2 であるため、単純かつ直接的に再利用することはできず、再マッピングを設定する必要があることがわかります。
3. TIM_OCInitTypeDef 構造体を通じて TIM3 のチャネル 2 を初期化し、タイマー モードを PWM2 として選択し、比較出力を有効にし、出力極性をハイ レベルに設定し、デューティ サイクルを 50% に設定します。
最後に、TIM_OC2PreloadConfig 関数を使用して CCR2 上の TIM3 のプリロード レジスタを有効にし、TIM_Cmd 関数を使用して TIM3 を有効にします。
2. 指定周波数のPWM波を出力
TIM3_Int_Init(5999,0);
//TIM3_PWM_Init(5999,0);//不分频。PWM 频率=96000/(5999+1)=16KHz
基準PWM 周波数: Freq = CK_PSC / (PSC + 1) / (ARR + 1)、ここで私のチップ システム周波数は 96MHz、CK_PSC に対応、ARR はカウント値、PSC はプリスケーラー値、式に代入して取得します。 : 周波数 F=16000Hz=16KHz。
したがって、このコードは 16KHz の固定周波数の PWM 波を出力します。
3. 可変デューティサイクルによる PWM 波形の出力
TIM3_Int_Init(5999,0);
u16 pulse=400;
TIM_SetCompare2(TIM3,pulse);
タイマ TIM3 の場合、CCR2 レジスタの値の範囲は 0 ~ ARR です。つまり、コンペア レジスタの値はオートリロード レジスタの値より大きくすることはできません。したがって、デューティ比を設定する際には、入力されたデューティ比の値を、計算によって対応するコンペアレジスタの値に変換する必要があります。つまり、pulse の値は 0 ~ 5999 の間でのみ設定できます。ここで呼び出される関数は、チャネル 2 に対応するコンペア レジスタ CCR2 である TIM_SetCompare2()関数であることに注意してください。ch3 の場合、TIM_SetCompare3 () 関数を呼び出す必要があります。このようにして、PWM 波のデューティ サイクルが変更されます。