STM32 は複数のステッピング モーターを制御します: HAL ライブラリに基づいて シングル タイマー マルチ チャネル割り込みのパルス数の精密制御 + マルチ タイマー シングル チャネル割り込みのパルス数の精密制御


前回の記事では、HAL ライブラリのタイマー割り込みに基づいて閉ループ ステッピング モーターの駆動を実現し、タイマー割り込みコールバックを使用してステッピング モーターのパルス数の正確な制御を実現しました。
複数のステッピングモーターを制御する場合も原理や方法は単体のステッピングモーターと同じです 前回の記事で紹介しましたが、実装に問題があるかもしれないのでこのブログに記録する予定です。将来のピットで。

使用されるハードウェア:
MCU: STM32F407ZGT6
ステッピング モーター ドライバー: Emm42_V4.0 ステッピング モーター クローズド ループ ドライバー
ステッピング モーター: 42 個のステッピング モーター
(および電源ボードとモデル航空機バッテリー)

1. 複数のステッピングモーターを直接制御

複数のステッピングモーターを直接制御する場合は、ステッピングモータードライバーの制御方法をマスターするだけで済みます。
知りたい場合は、前の記事「STM32 制御ステッピング モーター: HAL ライブラリ タイマー割り込み + パルス数の正確な制御に基づく閉ループ ステッピング モーター ドライブ」に直接ジャンプできます。
CubeMx の構成とプログラムの分析はリンク先の記事に記録されており、4 つのステッピング モーターを制御するコードが添付されています。記事の 3 番目の部分では、STM32F407 タイマー割り込み制御ステッピング モーター プログラムの主要な初期化プログラムとロジックの分析が含まれてますプログラム。

2. シングルタイマーマルチチャネル割り込みパルス数の正確な制御

このプログラムにより得られる効果は、4 つのステッピング モーターが同時に回転し、3 秒ごとに 1 周した後に停止することです。

1. CubeMx の構成、1 回転パルス数、その他の問題

シングルタイマー、マルチチャンネルCubeMx の構成は前の記事と同じなので、ここでは詳しく説明しません。リンクは上記にあります。
さらに、ステッピング モーターの 1 回転に必要なパルス数の計算タイマーの初期化ステッピング モーターの有効化、パルス、および方向関数の設計についても、前の記事で詳細に分析しました。

2. メインプログラム

前回の記事4のプログラムを継承し、閉ループステッピングモーターがパルス数を正確に制御し、割り込みコールバック関数が修正されています。なお、ここではタイマ判定の基準をチャネル判定に変更しましたが、他のタイマを使用する場合には、チャネル判定の前にタイマ判定の前提条件を追加することも可能です。

if(htim->Instance == htim2.Instance)	// 确认是否为步进电机脉冲中断的回调。

この判定条件にチャネル判定と内部ロジックプログラムを書き込むだけです。

割り込みコールバック関数プログラム:

/* ============================== 步进电机PWM中断回调函数 ============================== */
int Motor1_PWM_num = 0;		// 电机1当前脉冲数
int Motor2_PWM_num = 0;		// 电机2当前脉冲数
int Motor3_PWM_num = 0;		// 电机3当前脉冲数
int Motor4_PWM_num = 0;		// 电机4当前脉冲数

int road_PWM_num = 3200 * 1;	// 步进电机目标脉冲数(一圈3200脉冲)

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    
    
	if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)	// 通道1
	{
    
    
		Motor1_PWM_num ++;
		if(Motor1_PWM_num >= road_PWM_num)
		{
    
    
			Motor1_PWM_num = 0;	// 跑完目标圈数了,重置当前值
			HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_1);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
	if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)	// 通道2
	{
    
    
		Motor2_PWM_num ++;
		if(Motor2_PWM_num >= road_PWM_num)
		{
    
    
			Motor2_PWM_num = 0;	// 跑完目标圈数了,重置当前值
			HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_2);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
	if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)	// 通道3
	{
    
    
		Motor3_PWM_num ++;
		if(Motor3_PWM_num >= road_PWM_num)
		{
    
    
			Motor3_PWM_num = 0;	// 跑完目标圈数了,重置当前值
			HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_3);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
	if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)	// 通道4
	{
    
    
		Motor4_PWM_num ++;
		if(Motor4_PWM_num >= road_PWM_num)
		{
    
    
			Motor4_PWM_num = 0;	// 跑完目标圈数了,重置当前值
			HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_4);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
}

メインプログラム:
タイマーが初期化された後、マイクロコントローラーに 1 秒の遅延を与えました。この時点でステッピング モーターが遅延なく直接駆動されると、一部のステッピング モーターがウェイクアップできない可能性があるため、この遅延が必要です。プログラムにより実現される機能は上記の通りであり、プログラムは以下の通りである。

int main(void)
{
    
    
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
  Motor_PWM_MX_TIM2_Init();		// 定时器2初始化
	
  HAL_Delay(1000);		// 必须存在的延时,可长不可太短

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	Motor1_pwm_Set(50);
	HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
	Motor1_course(1);
	Motor1_enable();

	Motor2_pwm_Set(50);
	HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_2);
	Motor2_course(1);
	Motor2_enable();

	Motor3_pwm_Set(50);
	HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_3);
	Motor3_course(1);
	Motor3_enable();

	Motor4_pwm_Set(50);
	HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_4);
	Motor4_course(1);
	Motor4_enable();

	HAL_Delay(3000);
  }
  /* USER CODE END 3 */
}

3. マルチタイマーシングルチャンネル割り込みによりパルス数を正確に制御

1. CubeMxの構成

タイマの構成は次のとおりです。
ここに画像の説明を挿入ここに画像の説明を挿入
上図に示すように、タイマ 2、3、4、5 の構成は同じです。
また、外部水晶発振器をオンにすることを忘れないでください。
ここに画像の説明を挿入

クロック番号の設定は次のとおりです。
ここに画像の説明を挿入
次に、ピンのハイ レベル出力を設定します。
ここに画像の説明を挿入 ここに画像の説明を挿入ここに画像の説明を挿入
完了です。

2. プログラム設計思想とメインプログラム

マルチステッピング モーターのパルス数を正確に制御するマルチタイマー シングル チャネルの実装は、上記の方法とは異なります。HAL_TIM_PWM_PulseFinishedCallback の PWM 割り込みコールバック関数を使用せず、HAL_TIM_PeriodElapsedCallback の TIM タイマ カウント オーバーフローの割り込みコールバック関数を使用します。
この方法では、タイマーの原理を使用して PWM を生成します。つまり、プリスケーラー後の各カウントは PWM 方形波に対応します。つまり、パルスを送信するたびにカウント オーバーフローが発生します。 PWMダウンを生成するために使用されます。カウンタのオーバーフロー数 = パルス数
このメソッドのタイマー初期化構成では、初期化後にフラグをクリアする必要があります。つまり、次のコードを追加します。

__HAL_TIM_CLEAR_IT(&htimx, TIM_IT_UPDATE);	// 清空标志位
// htimx对应下文中的htim2、htim3、htim4、htim5

タイマーは合計 4 つあり、クリアするには 4 つのタイマーのフラグ ビットを追加する必要があります。
同様に、タイマー割り込みの開始関数と停止関数は、次の 2 つの関数に置き換える必要があります。

HAL_TIM_Base_Start_IT(&htimx);	// 中断开启
HAL_TIM_Base_Stop_IT(&htimx);	// 中断停止
// htimx对应下文中的htim2、htim3、htim4、htim5

割り込みコールバック関数プログラム:

/* ============================== 步进电机PWM中断回调函数 ============================== */
int Motor1_PWM_num = 0;		// 电机1当前脉冲数
int Motor2_PWM_num = 0;		// 电机2当前脉冲数
int Motor3_PWM_num = 0;		// 电机3当前脉冲数
int Motor4_PWM_num = 0;		// 电机4当前脉冲数

int road_PWM_num = 3200 * 1;	// 步进电机目标脉冲数(一圈3200脉冲)

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    
    
	if(htim->Instance == TIM2)	// 定时器2(步进电机1PWM)
	{
    
    
		Motor1_PWM_num ++;
		if(Motor1_PWM_num >= road_PWM_num)
		{
    
    
			Motor1_PWM_num = 0;
			HAL_TIM_Base_Stop_IT(&htim2);
			HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
	if(htim->Instance == TIM3)	// 定时器3(步进电机2PWM)
	{
    
    
		Motor2_PWM_num ++;
		if(Motor2_PWM_num >= road_PWM_num)
		{
    
    
			Motor2_PWM_num = 0;
			HAL_TIM_Base_Stop_IT(&htim3);
			HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
	if(htim->Instance == TIM4)	// 定时器4(步进电机3PWM)
	{
    
    
		Motor3_PWM_num ++;
		if(Motor3_PWM_num >= road_PWM_num)
		{
    
    
			Motor3_PWM_num = 0;
			HAL_TIM_Base_Stop_IT(&htim4);
			HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_1);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
	if(htim->Instance == TIM5)	// 定时器5(步进电机4PWM)
	{
    
    
		Motor4_PWM_num ++;
		if(Motor4_PWM_num >= road_PWM_num)
		{
    
    
			Motor4_PWM_num = 0;
			HAL_TIM_Base_Stop_IT(&htim5);
			HAL_TIM_PWM_Stop(&htim5, TIM_CHANNEL_1);	// 停止输出PWM
			//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10);	// 点灯(调试用的,不管)
		}
	}
}

main 関数を記述する前に、ステッピング モーター 1 を例として、ステッピング モーターの PWM 設定関数を変更する必要があります。

/* ============================== 步进电机脉冲设置 ============================== */

void Motor1_pwm_Set(int motor1_n)
{
    
    
   Motor1_sConfigOC.Pulse = motor1_n;
   HAL_TIM_PWM_ConfigChannel(&htim2, &Motor1_sConfigOC, TIM_CHANNEL_1);
}

メイン プログラム:
同様に、ステッピング モーターが起動しなくなるのを防ぐために、初期化後に小さな遅延を追加する必要があります。
プログラムによって実現される機能はシングルタイマーマルチチャンネルと同じで、ステッピングモーターは3秒以内に正確に1回転して停止し、そのサイクルが継続します。

int main(void)
{
    
    
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
  Motor1_TIM2_Init();
  Motor2_TIM3_Init();
  Motor3_TIM4_Init();
  Motor4_TIM5_Init();

  HAL_Delay(1000);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		Motor1_pwm_Set(50);
		HAL_TIM_Base_Start_IT(&htim2);
		HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
		Motor1_enable();
		
		Motor2_pwm_Set(50);
		HAL_TIM_Base_Start_IT(&htim3);
		HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
		Motor2_course(1);
		Motor2_enable();
		
		Motor3_pwm_Set(50);
		HAL_TIM_Base_Start_IT(&htim4);
		HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
		Motor3_course(1);
		Motor3_enable();
		
		Motor4_pwm_Set(50);
		HAL_TIM_Base_Start_IT(&htim5);
		HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
		Motor4_course(1);
		Motor4_enable();
		
		HAL_Delay(3000);
  }
  /* USER CODE END 3 */
}

4. プログラムリンク

プログラムはパッケージ化され、csdn のリソースにアップロードされています。
CSDN: HAL ライブラリに基づくシングルタイマー マルチチャネル割り込みはパルス数を正確に制御します (4 ステッピング モーター) CSDN
: HAL ライブラリに基づくマルチタイマー シングル チャネル割り込みはパルス数 (4 つのステッピング モーター) を正確に制御しますステッピング モーター) は、
次のリンクからダウンロードすることもできます。

HAL ライブラリに基づくシングルタイマー マルチチャネル割り込み精密制御パルス数 (4 ステッピング モーター):
リンク: https://pan.baidu.com/s/1uQG8ll_PjbqnKCArs-p0lQ
抽出コード:
HAL ライブラリに基づく 8rdk マルチタイマー シングル-チャネル割り込みパルス数の正確な制御 (4 ステッピングモーター):
リンク: https://pan.baidu.com/s/1tYNfGQKdSbJEK-Tf7GAb9A
抽出コード: du7b

私は学生で現在勉強中です、この記事は私の勉強メモとも言えるものです、間違っていたらご指摘ください。

おすすめ

転載: blog.csdn.net/xztli/article/details/127201347