Pause/Unterbrechung beim PWM fading einfügen

OP #4548355
Hallo,
folgendes Script funktioniert bereits prima.
1
int
2
main(void)
3
{
4
        uint16_t delay = DELAY_MIN;
5
        uint8_t dir = 0;
6

7
        /* setup */
8
        DDRB = 0b00000001; // set LED pin as OUTPUT
9
        PORTB = 0b00000001; // set LED pin to HIGH
10

11
        /* loop */
12
        while (1) {
13

14
        PORTB &= ~(_BV(LED_PIN)); // LED off
15
                _delay_loop_2(delay);
16

17
                PORTB |= _BV(LED_PIN); // LED on
18
                _delay_loop_2(DELAY_MAX - delay);
19

20
                if (dir) { // fade-in
21
                        if (++delay >= (DELAY_MAX - 1)) dir = 0;
22
      
23
                } else { // fade-out
24
            if (--delay <= DELAY_MIN) dir = 1;
25
                }
26
        }
27
}

Es handelt sich dabei um eine LED, die an und aus gefadet wird.
Nun möchte ich aber, das die LED für X Sekunden aus bleibt und dann 
wieder heller wird.
Kann mir jemand sagen wie und wo ich das einbauen muss?

Vielen Dank
Gast
Servus,
was du machen willst, nennt sich pollen, wenn dieses Programm fkt., dann 
könntest du diese Aufgabe mit einer ISR erledigen.
1
        /* loop */
2
        while (1) {
3
/*
4
        PORTB &= ~(_BV(LED_PIN)); // LED off
5
                _delay_loop_2(delay);
6

7
                PORTB |= _BV(LED_PIN); // LED on
8
                _delay_loop_2(DELAY_MAX - delay);
9
*/
10
       
11
            if (dir) { // fade-in           
12
                for(; delay >= DELAY_MAX; delay++){
13
                   pwm+=1; //hier die richtigen Register setzen!
14
                _delay_loop_2(100); //100ms delay
15
                }
16
                dir=0; //led tauscht den Zustand
17

18
            } else { // fade-out
19
                for(; delay == 0; delay--){
20
                   pwm+=1; //hier die richtigen Register setzen!
21
                _delay_loop_2(100); //100ms delay          
22
                }
23
                dir=1; //led tauscht den Zustand
24
            }
25
        }//end loop

Du müssest nur noch die Ausgänge der LED richtig initialisieren!

mfg
(Firma: Vescomp)
Jens S. schrieb:
> Kann mir jemand sagen wie und wo ich das einbauen muss?
1
                } else { // fade-out
2
            if (--delay <= DELAY_MIN) dir = 1; <== HIER
3
                }
 etwa so:
1
                } else { // fade-out
2
                    if (--delay <= DELAY_MIN) {
3
                        PORTB &= ~(_BV(LED_PIN)); // LED off
4
                       _delay_loop_2(2000); //2000ms delay - Wenn's geht
5
                       dir = 1;
6
                    }
7
                }
Ich hab mal auf die Schnelle was zusammengestrickt, dürfte so gehen als 
Beispiel:
1
/* Name: main.c
2
 * Author: <insert your name here>
3
 * Copyright: <insert your copyright message here>
4
 * License: <insert your license reference here>
5
 */
6

7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
#include <avr/sleep.h>
10

11
//globals
12
volatile uint16_t myInt = 0;
13
volatile uint8_t upDown = 0;
14

15
//functions
16
void setUpAvr(void);
17

18
int main(void)
19
{
20
    setUpAvr();
21
    
22
    for(;;){
23
        /* insert your main loop code here */
24
    set_sleep_mode(SLEEP_MODE_IDLE);
25
    sleep_mode();
26
    }
27
    return 0;   /* never reached */
28
}
29

30
void setUpAvr(void){
31
    /* insert your hardware initialization here */
32
  
33
    //PWM Pin als Ausgang definieren
34
    DDRB |= (1 << PB0);
35
    //setUp Timer0
36
    TIMSK0 |= (1 << TOIE0);
37
    TCCR0A |= (1 << COM0A1)|(1 << WGM01)|(1 << WGM00);
38
    TCCR0B |= (1 << CS00);
39
    OCR0A = 0;
40
    //enable interrupts
41
    sei();
42
}
43
ISR(TIMER0_OVF_vect){
44
  myInt++;
45
  if (myInt >=15) {
46
    if (OCR0A < 255 &&
47
      upDown == 0) {
48
      OCR0A++;
49
    }else if (OCR0A != 0) {
50
      OCR0A--;
51
      upDown = 1;
52
    } else {
53
      upDown = 0;
54
    }
55

56
    myInt = 0;
57
  }
58
}
Das dürfte die PWM an OCR0A immer von 0 auf 255 hochlaufen lassen und 
anschließend runter laufen lassen. Läuft der ATtiny13 mit 1 MHz dann 
dürfte der Zustand myInt = 15 ca. alle 4 ms auftreten. Das PWM-Register 
wird damit also alle 4 ms um eins erhöht/erniedrigt. Um also die PWM 
somit von 0% auf 100% zu bekommen braucht es damit eine Zeit von ca. 1 
Sekunde.

Das soll nur als Beispiel dienen, hab ich eben so ohne Kontrolle aus dem 
Bauch heraus runtergekritzelt.

EDIT:

Der Sleep-Kram ist meinem 08/15-Standard geschuldet und nicht wirklich 
erforderlich aber auch nicht ganz unvorteilhaft ;)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.