1

我试图弄清楚如何随着时间的推移使 LED 变暗(时间由用户定义,我们称之为 rampUp)。我将 arduino 与 adafruit breakout PWM-Servo-Driver ( http://www.adafruit.com/products/815 ) 与库一起使用:https ://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library

这个突破有 4095 步(0-4095)所以现在我的问题:

我希望能够获取一个变量( int 分钟)并将其发送到一个方法,该方法将 LED 从 0 调暗到 4095,在一段时间内以相等的光强度增加。我希望每次增加时增加 1。

那么如何在不使用 delay() 的情况下编写方法呢?

void dimLights(int rampUp){
  // some code to regulate the increase of the third value in setPWM one step at a time over a period of rampUp(int in minutes)
  led.setPWM(0,0,4095);
}

不想使用 delay() 的原因是因为它会暂停/停止程序的其余部分。

4

1 回答 1

0

我最近实际上实现了一些接近的东西:

void loop() {
    /* ... */
    if (rampUp != 0)
        led.setPWM(0,0,rampUp);
}

void led_update() {
    // here you can prescale even more by using something like
    // if (++global_led_idx == limit) {
    //   global_led_idx = 0;
    ++rampUp;
}

void start() {
    TCCR1B |= _BV(WGM12);
    // set up timer with prescaler = FCPU/1024 = 16MHz/1024 ⇒ 60ms
    TCCR1B |= _BV(CS12) | _BV(CS10);
    TCCR1B &= ~_BV(CS11);

    // initialize counter
    OCR1A = 0x0000;

    // enable global interrupts
    sei();
    // enable overflow interrupt
    TIMSK1 |= _BV(OCIE1A);
}

void TAGByKO_LED::stop() {
    TIMSK1 &= ~_BV(OCIE1A);
    rampUp = 0;
}

ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) {
    led_update();    
}

然后你可以打电话start()来启动计时器,或者stop()停止它。你可以阅读更多关于我在这里使用的寄存器和ISR声明的文档。请注意,要真正理解AVR 是最棘手的事情之一,即便如此,您也总是需要备有备忘单或数据表。

您也可以将@sr-richie 的解决方案与计时器一起使用,但仅在dimLights()函数中设置变量,并且led.setPWM()仅在loop().

于 2014-02-07T11:10:31.163 回答