我已经有一段时间研究如何通过atmega32的快速pwm模式控制电机(控制其速度)了。我需要使用8位Timer0,因为其他计数器也有其他用途。我想我知道如何为该任务初始化计时器:

void initial_io (void){
    DDRC = 0xFF;
    DDRB = 0xFF;
    PORTA = (1<<PA4)|(1<<PA5);
    TCCR0 = (1<<WGM01)|(1<<WGM00); // PWM mode : Fast PWM.
    TCCR0 = (1<<CS02)|(1<<CS00); // PWM clock = CPU_Clock/1024
}

但是随之而来的问题。我根本不知道下一步该做什么,我该做什么。

我确切的项目是驾驶具有加速功能的遥控汽车。因此,当我要求汽车前进时,它必须从 parking 加速到最大速度,然后再加上固定加速度。我不知道任何大会,因此如果可以帮助我,请用C语言进行。任何帮助将不胜感激。

最佳答案

好吧,我想您可以将所有端口B和C引脚都输出。另外,您无需在AVR上进行任何组装。仅汇编的内容可作为avr-libc中的宏使用。

建立

首先,您设置的TCCR0错误。您必须一次设置所有位,或者必须使用读-修改-写操作(通常使用TCCR0 |= _BV(bit_num);设置一个位,或者使用TCCR0 &= ~_BV(bit_num);清除它)。 (_BV(N)是一个avr-libc宏,它比您使用的(1<<N)东西更清晰,但功能相同。)此外,您还缺少由COM00和COM01位设置的PWM输出的极性。现在,您(隐式地)使它们禁用了PWM输出(断开了OC0)。

因此,我假设您想要一个正向PWM,即较大的PWM输入值会导致较大的高输出占空比。这意味着需要设置COM01并需要清除COM00。 (请参见ATmega32(L)数据表的第80-81页。)这将导致设置行:

TCCR0 = _BV(WGM01) | _BV(WGM00) // PWM mode: Fast PWM.
      | _BV(COM01)              // PWM polarity: active high
      | _BV(CS02) | _BV(CS00);  // PWM clock: CPU_Clock / 1024

占空比

现在我们开始实际的占空比生成。计时器0非常愚蠢,并且将其BOTTOM链接到0,将TOP链接到0xFF。这意味着每个PWM周期为PWM_Clock / 256,并且由于您将PWM_Clock设置为CPU_Clock / 1024,因此该周期为CPU_Clock / 262144,对于8 MHz CPU时钟约为33 ms。因此,每个PWM时钟,该计数器从0递增到255,然后循环回到0并重复。

实际的PWM由表40中的OC电路生成。对于COM0*设置,它表示:



这意味着每次计数器向上计数时,它都会将计数值与OCR0寄存器进行比较,如果匹配,它将OC0输出引脚驱动到GND。当计数器回绕为0时,它将引脚驱动至VCC。

因此,要设置占空比,只需将与该占空比对应的值写入OCR0:
OCR0 = 0;   // 0% duty cycle: always GND.
OCR0 = 64;  // 25% duty cycle
OCR0 = 128; // 50% duty cycle
OCR0 = 172; // 67% duty cycle
OCR0 = 255; // 100% duty cycle; always VCC. See below.

最后一种情况可以解决PWM的一个常见问题:可能的占空比设置数总是比计数步数多一。在这种情况下,有256个步骤,并且如果对于这些步骤中的0、1、2…256,输出可能是VCC,则提供257个选项。因此,它们使100%害羞的情况消失了,而不是防止0%或100%的情况发生。表40的注1表示:



还有一件事:如果在PWM周期的中间写入OCR0,它只会等到下一个周期。

模拟加速度

现在,要获得所需的“恒定加速度”,您需要具有某种标准时基。 TOV0(定时器0溢出)中断可能有效,或者您可以使用其他定时器或某种外部引用。您将使用此标准时基来知道何时更新OCR0

恒定的加速度仅表示速度随时间线性变化。更进一步,这意味着对于每个更新事件,您需要将速度更改为恒定值。这可能只是saturation arithmetic:
#define kAccelStep 4
void accelerate_step() {
    uint8_t x = OCR0;
    if(x < (255 - kAccelStep))
        OCR0 = x + kAccelStep;
    else
        OCR0 = 255;
}

只要对每个时间步执行这样的操作,您就会获得恒定的加速度。可以使用类似的算法进行减速,甚至可以使用更高级的算法来模拟非线性函数或补偿电动机无法立即达到PWM规定速度的事实。

关于c - 如何以atmega 32 pwm控制电机,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19657850/

10-09 01:59