我在tim3上遇到了正交编码器模式的问题。
1)tim3在第一个信号的每个上升沿计数。 CNT寄存器计数,我用1hz读取值,然后设置 寄存器为0.
一切看起来不错但是......
当我查看oscilloscope时,频率是其中的一半 来自CNT register output (1hz)的值。
为什么?
2)tim3计数第一个信号的两个边沿。 CNT register output (1 hz)完全错误
我的配置是:
GPIO_InitTypeDef sInitEncoderPin1;
sInitEncoderPin1.Pin = pin1Encoder.pin; // A GPIO_PIN_6
sInitEncoderPin1.Mode = GPIO_MODE_AF_PP;
sInitEncoderPin1.Pull = GPIO_PULLUP;
sInitEncoderPin1.Speed = GPIO_SPEED_HIGH;
sInitEncoderPin1.Alternate = altFunctionEncoder; // GPIO_AF2_TIM3
GPIO_InitTypeDef sInitEncoderPin2;
sInitEncoderPin2.Pin = pin2Encoder.pin; // A GPIO_PIN_7
sInitEncoderPin2.Mode = GPIO_MODE_AF_PP;
sInitEncoderPin2.Pull = GPIO_PULLUP;
sInitEncoderPin2.Speed = GPIO_SPEED_HIGH;
sInitEncoderPin2.Alternate = altFunctionEncoder; // GPIO_AF2_TIM3
HAL_GPIO_Init(GPIOA, &sInitEncoderPin1);
HAL_GPIO_Init(GPIOA, &sInitEncoderPin2);
encoderTimer.Init.Period = 0xffff;
encoderTimer.Init.Prescaler = 0;
encoderTimer.Init.CounterMode = TIM_COUNTERMODE_UP;
encoderTimer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
encoderTimer.Init.RepetitionCounter = 0;
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 1);
encoder.EncoderMode = TIM_ENCODERMODE_TI1;
encoder.IC1Filter = 0x0f;
encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING; // TIM_INPUTCHANNELPOLARITY_BOTHEDGE
encoder.IC1Prescaler = TIM_ICPSC_DIV1;
encoder.IC1Selection = TIM_ICSELECTION_DIRECTTI;
encoder.IC2Filter = 0x0f;
encoder.IC2Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
encoder.IC2Prescaler = TIM_ICPSC_DIV1;
encoder.IC2Selection = TIM_ICSELECTION_DIRECTTI;
HAL_TIM_Encoder_Init(&encoderTimer, &encoder);
HAL_TIM_Encoder_Start_IT(&encoderTimer, TIM_CHANNEL_ALL);
答案 0 :(得分:0)
oscilloscope screenshot 显示大约416 Hz的频率。
first shell output (非常粗略!)高两倍(问题已经指出)。 由于显示的配置
,这似乎对我几乎是正确的encoder.EncoderMode = TIM_ENCODERMODE_TI1;
选择“ X2分辨率编码器模式”,该模式在每个信号周期内以2 CNT
个增量计数。
在有关的应用笔记中
timer overview,
(第4.3.4节/图7)有一个说明图,详细说明了编码器模式如何工作。
second screenshot
TIM3配置错误导致的结果:
编码器模式(TIM_ENCODERMODE_TI1
)假定两个通道仅在定向侧面上交替触发(请参见上面的AN链接)。
如果两个通道之一触发的事件是 配置
encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE,
计数器将仅向上计数一个位置,然后“识别”一个“反转”事件(=方向改变)。 请记住
65535u = 0xFFFF = -1
第二个屏幕截图仅显示值-1、0,+ 1,这完全符合此说明。
问题仍然在于,为什么第一张屏幕截图显示了800
和822
之间的(可重现)测量结果。
我认为
这可以解释为什么前两个值看起来像废话(0
:尚未启动TIM3。545
:在外壳程序输出计时器期间已启动TIM3)。
丢弃前两个测量样本,被测信号频率的平均值和标准偏差分别为
808,9091 +/- 0,5950 [每秒X2增量]
404,4545 +/- 0.2975 [Hz]
对应于一个周期
2,4331 +/- 0,003 [ms]。
因此,测得的频率太低了约11 Hz,即测得的周期太高了近30 µs,这个误差显然超出了统计噪声。
该问题提示此错误可能来自哪里:
CNT寄存器递增计数,我以1 Hz的值读取该值,然后将寄存器设置为0。
CNT
值。CNT
的值重置为零,
由于已读取CNT
的值,因此放弃进一步的增量。这暗示软件在(3.)和(4.)之间需要30 µs,这在STM32F4上将花费大量时间。
编辑:我刚刚重新检查了示波器的屏幕截图。该错误是可见的,但我相信它比我最初的想象要小(通过计算图片中的侧面)。