STM8 脉冲计数器

问题描述

我正在开发直流电机的控制。这个电机有一个编码器,根据它的运动产生脉冲。

我需要通过监控脉冲数来控制电机轴的圈数。

我正在为此应用程序使用 SMT8S103F3。

这个想法是使用 Timer1 作为脉冲计数器。为此,我将定时器配置为接收外部信号,在本例中为编码器脉冲,并且每个脉冲必须增加计数器。

我遵循了文档 ST RM0016 第 17.4.3 章。但是,该应用程序不起作用。计数器未递增。

遵循开发的代码

#

有什么想法吗?

如果定时器不是此应用的最佳选择,如何实现脉冲计数器?

脉冲频率为 700kHz。

解决方法

解决了。

要在 stm8 引脚上使用定时器,必须写入选项字节以更改引脚的功能。 这是通过编写 AFR0 来实现的。

使用定时器 1 通道 2 的定时器配置如下。

void config_counter(){
  TIM1_CNTRH = 0;
  TIM1_CNTRL = 0; //Reset counter
  TIM1_IER = 0; //Interrupt disabled
  TIM1_SR1 = 0; //Clear Interrupt
  TIM1_CCMR2 |= 1<<0; //External pulse source T1C2
  TIM1_CCER1 &= ~(1<<5); //Rising edge
  TIM1_SMCR |= (7<<0); //External Clock Source
  TIM1_SMCR |= (6<<4); //T1C2 Input Source
  TIM1_CR1 &= ~(1<<0); //Counter disabled
  
  return;
}

,

TIM1_CR1 |= ~(1<<0); //Counter disabled 不会禁用计数器。它保持 CEN 不变,并将所有其他位设置为 1 - 包括 OPM。你想要 &= 代替。 set_counter_updown 也一样。

,

这个问题有两种可能的解决方案。

带定时器的解决方案要求定时器的时钟输入与电机脉冲相关联,这需要一些外部硬件连接,我不知道您是否有可用的连接。好处是您只需读取计时器值即可了解圈数,并且使用预分频器可以缩放您的输入。缺点是定时器的数量通常是有限的(你只有一个或两个定时器),而且定时器总是被配置为计算电机转数,你不能用它做其他事情。

另一种解决方案是为电机脉冲关联一条中断线并编写中断处理程序。您需要(通过硬件)将中断与电机脉冲相关联,因此当您收到中断时,中断处理程序增加一个变量

一旦你有了这个......你只需要检查变量值是什么,因为变量的更新只是反映了电机转动了多少次。

volatile long loops = 0;

void motor_pulse_handler()
{
    loops++;
}

int main()
{
    /* this function installs the handler to be called each time the motor starts a new turn. */
    install_handler(MOTOR_PULSE_INTERRUPT,motor_pulse_handler);
    ...
    for (;;) {
        printf("\rloops: %ld",loops);
        usleep(10000);
    }
}     

函数install_handler是一个强烈依赖于硬件的函数。它通常由开发系统作为库函数提供,因为它需要了解一些处理器架构才能实现。您首先需要在操作中断相关控件时完全禁用中断。然后它必须激活以在相应中断线中的脉冲上中断 cpu(这是在参数列表中包含 MOTOR_PULSE_INTERRUPT 的原因,这应该使用适当的值 #defined使电机脉冲选定信号,而不是其他信号)最后它必须再次重新启用中断。当中断进入时,您的函数将在处理器可以执行的一系列操作的中间被调用。

通常,安装中断处理程序是一个两阶段的过程。实际调用的例程不是您传递给 install_handler 的例程,而是执行某些硬件操作的不同例程。中断处理程序在中断被禁止的情况下被调用,它应该:

  • 保存所有 cpu 状态(寄存器、标志等),以便在最后恢复状态。
  • 屏蔽这个设备的中断,所以它不会再中断(中断没有被设备确认,所以如果你启用中断,cpu会再次中断)
  • 启用中断,以便其他更高优先级的中断可以从此时开始中断 CPU。
  • 调用用户中断处理程序,以便更新计数器。
  • 再次禁用中断。
  • 确认中断。这通常意味着读取一些芯片寄存器以向中断硬件指示此中断已被确认。这会重置设备,以便在您从中断返回时不会出于同样的原因再次中断。
  • 恢复寄存器和标志(所有 cpu 状态),以便我们可以返回到 cpu 被中断的点。
  • 从中断中返回。这通常是一个特殊的返回指令(不是用于从普通函数调用返回的指令)

此解决方案的优点是您可以卸载信号处理程序,这将停止计数过程。同样,只有实现某种机制来路由中断才有可能将中断线重用于其他事情(这个问题类似于定时器中的问题,其中脉冲到达所选定时器的输入)