PWM出力
1. PWMの概要
パルス幅変調(PWM、パルス幅変調)は、パルス幅変調と略され、マイクロプロセッサのデジタル出力を使用してアナログ回路を制御する非常に効果的な技術です。つまり、パルス幅を制御するために、PWMの原理は次のようになります。
図では、タイマーがアップカウントPWMモードで動作しており、CNT <CCRxの場合は0を出力し、CNT> = CCRxの場合は1を出力すると仮定すると、上のPWMダイアグラムが得られます。CNT <CCRxの場合、IOポート出力低レベル、CNT> = CCRxの場合、IOポートは高レベルを出力し、CNT値がARRに達すると、ゼロにリセットされ、再びカウントアップして、ループします。CCRxの値を変更するとPWM出力のデューティサイクルを変更でき、ARRの値を変更するとPWM出力の周波数を変更できます
2つの出力モードがあります:PWM1とPWM2
出力極性:アクティブハイおよびアクティブロー
2.ハードウェア設計
この実験では、TIM3のチャネル1を介してPWM信号を出力し、D7インジケーターの輝度を制御します
- D7インジケーター
- タイマーTIM3
ここでは、TIM3のCH1チャネルに対応するピンがPA6であるため、開発ボード上のLEDはPA6に接続されていません。このチャネルをLEDに接続されたIOポートにマッピングする場合は、GPIO多重化機能の再マッピング機能を使用する必要があります。 PA6をPC6に再マップ
3.ソフトウェア設計
3.1 STM32CubeMX設定
- RCCは外部HSEを設定し、クロックは72MHzに設定され、APB1タイムクロックに搭載されたTIM3クロックは72MHzです。
- TIM3を選択し、タイマークロックソースを内部クロックソースに設定し、チャネル1をPWMモードに設定します(PA6が自動的にオンになるのに対応し、PC6 TIM3_CH1を選択して再マッピングを完了する必要があります)、タイマー割り込みを自分でオンにするかどうかを選択します
-
プリスケーラ係数は72-1に設定され、カウントアップし、自動リロード値は500-1に設定されます。タイマークロック周波数は1MHz、タイマー周期は1us、タイマーオーバーフロー周期(つまりPWM周期)は500 * 1です。 = 500us、オーバーフロー周波数(つまりPWM周波数)は1 / 500us = 2KHz
-
PWMモード選択PWM1、パルスのデフォルトは0、PWM極性は低レベルに設定されている(LEDが低レベルで点灯しているため)
- プロジェクト名を入力し、プロジェクトパス(中国語以外)を選択し、MDK-ARM V5を選択します。IPごとに「.c / .h」ファイルのペアとして生成されたペリフェラルの初期化を確認します。「コードを生成」をクリックしてプロジェクトコードを生成します
3.2 MDK-ARMプログラミング
- tim.cファイルでタイマーの初期化関数を確認できます
void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {
0};
TIM_MasterConfigTypeDef sMasterConfig = {
0};
TIM_OC_InitTypeDef sConfigOC = {
0};
htim3.Instance = TIM3;
htim3.Init.Prescaler = 72-1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 500-1;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK){
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK){
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK){
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK){
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){
Error_Handler();
}
__HAL_TIM_DISABLE_OCxPRELOAD(&htim3, TIM_CHANNEL_1);
HAL_TIM_MspPostInit(&htim3);
}
- CCR1の値を定期的に変更してPWMデューティサイクルを変更するコードをメイン関数に記述します
int main(void){
/* USER CODE BEGIN 1 */
uint8_t dir = 1;
uint16_t ledpwmval = 0;
/* USER CODE END 1 */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //开启定时器PWM输出
/* USER CODE END 2 */
while (1){
HAL_Delay(10);
if(dir)
ledpwmval++;
else
ledpwmval--;
if(ledpwmval > 300)
dir = 0;
if(ledpwmval == 0)
dir = 1;
TIM3->CCR1 = ledpwmval; //更改CCR1的值来改变PWM的占空比
}
}
4.ダウンロードの確認
コンパイルが完了したら、開発ボードにダウンロードします。D7インジケーターライトが暗いから明るいに変わり、次に明るいから暗いに変わり、呼吸するライトの効果を示します。