3

現在、STM32F429ZI Nucleo-144 ボードで STM32F4 を使用しています。このマイクロコントローラを使用して、直交エンコーダ インターフェイスを介してロータリー エンコーダの位置を評価しようとしています。ドキュメントを見ると、これはタイマーで行われます。A/B エンコーダ出力を micro の PA6 と PC7 に接続していますが、カウントがずれているように見えます。

デバッグ中に、エンコーダー出力の 1 つをマイクロコントローラーに接続し、モーターを動かすと、エンコーダー ラインの 1 つだけが接続されているにもかかわらず、カウントが増加/減少することに気付きました。TI1 と TI2 の両方のエッジをカウントしているので、これは発生しないはずです。下の図を正しく読んでいる場合、ラインの 1 つが内部プルアップを使用して High に保持されているため、もう一方の入力のクロック パルスはアップ/ダウン/アップ/ダウンし、実際には 2 つの異なるカウント間を循環しているはずです。ただし、エンコーダーを回転させている場合、方向に応じてカウントが増加または減少し続けます。

エンコーダ入力が 1 つしか接続されていないのにエンコーダ カウントが変化するのはなぜですか? コードだけでなく、アクティブなカウントが 1 つだけであることを証明するスコープ トレースも添付されています。

編集: また、極性を BOTH EDGE から RISING EDGE に変更しようとしましたが、メリットはありません。

ここに画像の説明を入力

ここに画像の説明を入力

#include "stm32f4xx_hal.h"
#include "encoder_test.h"

GPIO_InitTypeDef  GPIO_InitStruct;
TIM_HandleTypeDef Timer_InitStruct;
TIM_Encoder_InitTypeDef Encoder_InitStruct;

void EncoderTest_Init()
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_TIM3_CLK_ENABLE();

    /**TIM3 GPIO Configuration
    PA6     ------> TIM3_CH1
    PC7     ------> TIM3_CH2
    */

    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    Timer_InitStruct.Instance = TIM3;
    Timer_InitStruct.Init.Period = 0xFFFF;
    Timer_InitStruct.Init.CounterMode = TIM_COUNTERMODE_UP;
    Timer_InitStruct.Init.Prescaler = 1;
    Timer_InitStruct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    Encoder_InitStruct.EncoderMode = TIM_ENCODERMODE_TI12;
    Encoder_InitStruct.IC1Filter = 0x00;
    Encoder_InitStruct.IC1Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
    Encoder_InitStruct.IC1Prescaler = TIM_ICPSC_DIV1;
    Encoder_InitStruct.IC1Selection = TIM_ICSELECTION_DIRECTTI;
    Encoder_InitStruct.IC2Filter = 0x00;
    Encoder_InitStruct.IC2Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
    Encoder_InitStruct.IC2Prescaler = TIM_ICPSC_DIV1;
    Encoder_InitStruct.IC2Selection = TIM_ICSELECTION_DIRECTTI;

    if (HAL_TIM_Encoder_Init(&Timer_InitStruct, &Encoder_InitStruct) != HAL_OK)
    {
        while (1);
    }

    if (HAL_TIM_Encoder_Start_IT(&Timer_InitStruct, TIM_CHANNEL_1) != HAL_OK)
    {
        while (1);
    }
}


void TIM3_IRQHandler()
{
    HAL_TIM_IRQHandler(&Timer_InitStruct);
}
4

1 に答える 1