【问题标题】:How to count time in C for ATMega8 with clock 16MHz如何在 C 中计算时钟为 16MHz 的 ATMega8 的时间
【发布时间】:2015-01-22 14:17:24
【问题描述】:

如何计算中断时间并将其设置为全局变量? 我的微控制器是 Atmega8,F_CPU 是 16MHz,编程语言是 C。 我知道的很少,下面那一行是时钟的初始化。

TCCR1B |= (1 << CS10);

这一行确实如此,全局变量“a”得到循环的值除以“xxx”。但是必须为 xxx 分配什么值?

a = TCNT1/xxx;

PS1:我想在推进式 LED 显示屏中计算我的螺旋桨的最后一圈,并将此值提供给下一个中断以正确显示图像。

PS2:为了做延迟,我使用函数:_delay_ms()。

【问题讨论】:

  • 不应该是(16 * 1000)吗?只是猜测。
  • 首先我尝试了这个值,但它给了我的螺旋桨错误的方式
  • 您需要什么分辨率?您似乎不知道,这使得这种无法正确回答。你在做螺旋桨的航位推算吗?什么 RPM?
  • 这个函数_delay_ms(1.6) 正在做延迟满转时间。但我不知道螺旋桨的全转是否等于 1.6ms。而且我不知道 RPM,因为风扇上没有任何注释。
  • 分辨率为 180 角

标签: c time count avr interruption


【解决方案1】:

首先使用_delay_ms 不是进行正确计时的好方法。

我建议如下: 使用 timer1 测量转子的频率。 当您获得位置中断(假设每转一个)时,将当前计时器值写入变量。在以下每个中断上计算周期计数器的差异(正确考虑溢出)。

现在您有了每转的周期数。我现在将以某种方式设置第二个计时器,计数器最高值(CTC 模式)与您测量的周期数除以显示器的角分辨率相同。因此,在溢出中断中,您可以将新数据锁存到 LED。

一个例子:

前提/假设:

  • F_CPU(和实际时钟)16MHz
  • 显示分辨率:200 角
  • 转子速度:137Hz
  • 定时器 1 预分频器 = 4(否则每转会溢出多次)

使用此值,您应该得到 29197 Timer-Ticks 的差异,转换为每转 116788.3 CPU-Cycles。除以 200 行,每个部分有 583.94 个周期。这个数字对于 8 位计数器来说太大了。使用预分频器 2 给出 291.97 - 仍然太大。因此,您必须使用(希望)4 的下一个更大的预分频器,以获得 145.98。 向上舍入到 146 和 -1,因为 0 也被计算在内。 所以我建议使用 145 作为这个计数器的最高值。这种考虑必须以编程方式实施。获取周期值并增加预分频器,只要它不适合您的 8 位。

整个程序如下所示:

volatile uint16_t oldTimer=0;
volatile uint16_t newTimer=0;
volatile uint8_t  flag=0; // bit 1 = push new data, bit 2 = new revolution measurement

ISR(Postional Interupt){
 oldTimer = newTimer;
 newTimer = TCNT1;
 flag |= 2;
}

ISR(timer2_overflow){
  latchDataToOutput();
  flag |= 1;
}

int main()
{
  while(1){
    if(flag & 2){
      calcNewTimer2Timing();
      flag &= ~2;
    }
    if(flag & 1){
      OutputDataToShiftRegister();
      flag &= ~1;
    }

  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    相关资源
    最近更新 更多