STM32学習メモ_7 タイマー割り込み:出力比較

出力比較

モーター関連の方が重要です。

OC 出力コンペア (IC はインプット キャプチャ、CC はこれら 2 つのユニットを指します)。特定の周波数とデューティ サイクルで PWM 波形を出力するために使用されます。

画像-20230425203158414

右下の 4 つは CCR です。汎用タイマとアドバンスト タイマのみが備えており、cnt カウンタを共有しています。アドバンスト カウンタの最初の 3 つの ccr レジスタには、デッドゾーン比較機能と相補出力機能もあり、三相モータを駆動できます。

PWM(パルス幅変調)パルス幅変調は、慣性のあるシステムにおいて、一連のパルスの幅を変調することで必要なアナログパラメータを等価的に得ることができ、モーターの速度制御などの分野でよく使用されます。

画像-20230429212942091

一定の周波数に応じて0と1を設定し、モーターの総合速度を変更します。LEDも同様で、私たちが見ていると「明るい」と感じますが、実は一定の周期で点滅することで明るさが異なります。

周期 Ts、デューティ サイクル Ton/Ts (1 に設定された時間がサイクル全体の割合を占めます)、周波数 = サイクルの逆数、分解能はデューティ サイクル変更ステップです。

画像-20230429213917384

入力モード:

モデル 説明
氷結 CNT=CCRの場合、REFは元の状態のまま
試合時のアクティブレベル CNT=CCR の場合、REF はアクティブレベルに設定されます。
試合時の非アクティブレベル CNT=CCR の場合、REF は無効レベルに設定されます。
マッチ時のレベル反転 CNT=CCR の場合、REF レベルが反転します。
非アクティブレベルに強制される CNT と CCR は無効であり、REF は強制的に無効なレベルに設定されます
強制的にアクティブレベルに設定 CNT と CCR は無効です。REF は強制的にアクティブ レベルになります。
PWMモード1 アップカウント:CNT<CCRの場合、REFはアクティブレベルに設定され、CNT≧CCRの場合、REFはインアクティブレベルに設定されます。 ダウンカウント:CNT>CCRの場合、REFはインアクティブレベルに設定され、CNT≦CCRの場合、REFはインアクティブレベルに設定されます。アクティブレベル
PWMモード2 アップカウント:CNT<CCRの場合、REFがインアクティブレベル、CNT≧CCRの場合、REFがアクティブレベル、ダウンカウント:CNT>CCRの場合、REFがアクティブレベル、CNT≦CCRの場合、 REFは非アクティブレベルに設定されます

入力断時などの強制モード。

極性は TIMx_CCER で設定することもできます。

全体的な処理ロジック:

画像-20230429220013581

画像-20230429233415904

周波数周期は通常のタイマーと同じで、デューティ比も分かりやすくなっています。

分解能は arr の最小値の逆数です。

高度なタイマーについては、当面は違いを理解してください。

画像-20230430000755685

2つの相補出力はプッシュプル回路に接続でき、デッドゾーン生成回路により2つの真空管のスイッチングに一定の遅延が生じます。

サーボ:角度を入力すると、サーボは一定の角度で停止します。周期20ms、ハイレベル幅0.5~2.5ms。

画像-20230430002606313

ステアリングギアの三隅、±ポール、信号線。(5V) 信号線内に駆動回路がございますので直接接続可能です。

DC モーターは、順電流で正転し、逆電流で逆転します。直接駆動することはできず、TB6612 チップによって駆動する必要があります。

2つのプッシュプル回路とH型回路、そして中間のモーターで構成されています。左上から右下への流れと、ちょうど真ん中を通過して右上から左下への流れが逆になります。

画像-20230430004135017

画像-20230430004207178

VM:駆動回路。

VCC: 制御回路、例えば当社の 3.3v の 32。

PWMA PWMB は 2 つの信号端子で、他の 2 つのピンは任意の GPIO ポートに接続できます。PWM 制御周波数の変更は、IN を 1 つの状態に保つだけです。

STNDBY スタンバイ制御ピン。スタンバイ用に接地され、動作するために VCC に接続されます。

コード: PWM LED 呼吸ライト

TIM GPIO をオンにし、タイムベースユニットを設定し、出力比較ユニット (CCR 値、モード、極性選択、出力のイネーブル) を設定し、プッシュプル出力 GPIO を設定し、カウンタを開始します。

関数:

画像-20230430043729585

初期化して初期値を割り当てます。

画像-2023043004381​​9308

強制出力ですが、デューティ サイクル 100% 0% に置き換えることができるため、一般的には使用されません。

画像-20230430050239274

最初にシャドウ レジスタにロードされます。CCR はすぐには更新されません。

画像-20230430123446162

高速イネーブル、クリアリファレンス。

画像-20230430123557436

出力チャンネルの極性を設定します。N は相補です。ここでの設定はすべて初期化中に行われ、これらの機能は個別に変更できます。

画像-20230430123802337

出力イネーブルパラメータを個別に設定します。

画像-20230430123847995

アウトプットコンペアモードを個別に設定します。

画像-20230430123932130

呼吸ランプなど、デューティ サイクルは常に変化するため、ccr レジスタを個別に変更することがより重要です。

画像-20230430124030903

これは、高度なタイマーを有効にするために使用されます。

ここでどのピンを選択するかは、以下に基づいて決まります。

画像-20230130163347869

PA0 は TIM2 と CH1 のピンです。競合を避けるために、AFIO を使用して他のピンを多重化することもできます。

データ レジスタ ピンを切断して代替機能に接続するには、GPIO を代替機能 AF_PP に設定する必要があります。

画像-20230430171804667

まず、ccr レジスタの値を指定して簡単な初期化関数を作成します。これにより、pwm 出力は変化しない固定値になり、表示結果は LED の明るさが ccr に応じて明るく/暗くなります。私たちが与える価値。

void PWM_Init(void){
    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    TIM_InternalClockConfig(TIM2);
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period=100-1;
    TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
    
    //PA0对应定时器2,oc channel1.
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);//防止漏赋初值出错,而且再更改想改的赋值简单一些
    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_Low;
    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse=50;//ccr
    TIM_OC1Init(TIM2,&TIM_OCInitStructure);
    
    TIM_Cmd(TIM2,ENABLE);
}

期間を 100 に設定します。ccr/100 の値はデューティ サイクルで、現在の設定は 50% の明るさです。10 に設定すると、明るさは 10% になります。

keil 独自のオシロスコープを使用して、a0 の出力波形を確認します。

画像-20230501002825514

TIM_SetCompare1(TIM2,i) を通じて ccr 値を変更できます。

while(1){
    
    
        for(i=0;i<100;i++){
    
    
            TIM_SetCompare1(TIM2,i);
            Delay_ms(10);
        }
        for(i=100;i>0;i--){
    
    
            TIM_SetCompare1(TIM2,i);
            Delay_ms(10);
        }
    }

ピンの再マッピング

画像-20230130163347869

図に示すように、TIM2_CH1 を PA15 に再マッピングできます。

まずAFIOを有効にする必要があります。RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

AFIO 再マッピング機能は以前に紹介しました。void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)最初に選択するパラメータは何ですか?

データシートには次のように書かれています。

画像-20230501011958981

画像-20230501012245153

したがって、部分的な再マッピング 1 または完全な再マッピングを選択できます。

次に、PA15 の元の機能をキャンセルする必要があります。

画像-20230501025047724

1 つ目: NoJTRST デバッグ、つまり PB4 のみをキャンセルします。

2 つ目: PA15、PB3、および PB4 の 3 つの JTAG デバッグ ポートをキャンセルします。

3 番目: JTAG と SWJ のポートのロックを解除します。一度焼き付けられると、ボードは stlink 経由でダウンロードできなくなるため、決して使用しないでください。シリアルポートを使用して対処する必要があります。

コードは GPIO ピンを変更し、AFIO の再マッピングを追加しただけです。

void PWM_Init(void){
    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    
    GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    TIM_InternalClockConfig(TIM2);
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period=100-1;
    TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
    
    //PA0对应定时器2,oc channel1.
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);//防止漏赋初值出错,而且再更改想改的赋值简单一些
    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_Low;
    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse=50;//ccr
    TIM_OC1Init(TIM2,&TIM_OCInitStructure);
    
    TIM_Cmd(TIM2,ENABLE);
}

コード: PWM サーボ

5Vはブレッドボードではなくstlinkに接続されています。

LED 呼吸ライトと比較して、回転角度は固定デューティ サイクル値によって決定できます。

画像-20230501033352391

周波数: 1/20ms=50Hz、つまり 72M/(arr+1)*(psc+1)=50

ccr と arr+1 は互いに比例します。たとえば、周期を 200-1 に設定し、psc を 7200-1 に設定すると、それに比例して ccr を 5 10 15 20 25 に設定できます。

もちろん、このような角度はあまり直感的ではありませんが、ラッパー関数を作成し、角度を渡し、対応する角度を回転させることができます。

コード: DC モーター

モータードライバーモジュールが必要です。

画像-20230514111855619

AN は方向を制御し、GPIO に接続するだけで、PWMA は PWM 出力に接続します。

前の出力と比較すると違いはありませんが、速度を制御するために ccr パラメーターを指定しています。AN の 2 つの GPIO ピンを初期化する必要があり、初期化後、1 つの SetBits と 1 つの ResetBits を使用してステアリングを制御します。

void Motor_Init(){
    
    
    
    //方向控制的引脚:AN设置
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    PWM_Init();
}

void Motor_SetSpeed(int8_t speed){
    
    

    if(speed>0){
    
    
        //方向脚一高一低
        GPIO_SetBits(GPIOA, GPIO_Pin_4);
        GPIO_ResetBits(GPIOA, GPIO_Pin_5);
        TIM_SetCompare3(TIM2,speed);
    }
    else{
    
    
        GPIO_SetBits(GPIOA, GPIO_Pin_5);
        GPIO_ResetBits(GPIOA, GPIO_Pin_4);
        TIM_SetCompare3(TIM2,-speed);
    }
}

回転時にブザーのようなノイズが発生しますが、周波数を上げる、つまりプリスケーラと周期のパラメータを下げることで解決し、周波数が上がります。

おすすめ

転載: blog.csdn.net/jtwqwq/article/details/130669006