logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega8][C] PWM - sterowanie led, prośba o sprawdzenie

soulreaver1 29 Kwi 2009 19:57 4520 8
  • #1 6471702
    soulreaver1
    Poziom 21  
    Witam.

    Napisałem programik sterujący led, w założeniu miało to powodować efekt "pulsującego" światła. Program się skompilował z trzema ostrzeżeniami i nie wiem czy to będzie działać czy nie (na razie nie mam jeszcze układu i programatora). Proszę o sprawdzenie czy to ma szansę działać.

    AVR-GCC + AVR Studio 4.15

    
    #include <avr/io.h>
    #include <util/delay.h>
    #define F_CPU 8000000
    #define PWMout OCR1A
    unsigned short int pwmVal;
    
    int main(void)
    { while(1)
    {
    TCCR1A=0xA3;
    TCCR1B=0x09;
    TCNT1=0x000;
    
    for(pwmVal=0; pwmVal<1023; pwmVal++);
    {
    	_delay_ms(2);
    }
    for(pwmVal=1023; pwmVal>0; pwmVal--);
    {
    	_delay_ms(2);
    }
    PWMout=pwmVal;
      }
    }
    


    log kompilatora:



    
    Build started 29.4.2009 at 19:46:32
    avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT PWMLED.o -MF dep/PWMLED.o.d  -c  ../PWMLED.c
    In file included from ../PWMLED.c:2:
    d:/programs/wnavr/lib/gcc/../../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for <util/delay.h>"
    ../PWMLED.c:3:1: warning: "F_CPU" redefined
    d:/programs/wnavr/lib/gcc/../../avr/include/util/delay.h:86:1: warning: this is the location of the previous definition
    avr-gcc -mmcu=atmega8 -Wl,-Map=PWMLED.map PWMLED.o     -o PWMLED.elf
    avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  PWMLED.elf PWMLED.hex
    avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex PWMLED.elf PWMLED.eep || exit 0
    avr-objdump -h -S PWMLED.elf > PWMLED.lss
    
    AVR Memory Usage
    ----------------
    Device: atmega8
    
    Program:     132 bytes (1.6% Full)
    (.text + .data + .bootloader)
    
    Data:          2 bytes (0.2% Full)
    (.data + .bss + .noinit)
    
    
    Build succeeded with 3 Warnings...
    
    
  • Pomocny post
    #2 6472097
    Dr.Vee
    VIP Zasłużony dla elektroda
    A sprawdzić w symulatorze to nie łaska?

    F_CPU powinno być zdefiniowane przed włączeniem nagłówka util/delay.h

    Poza tym program nie będzie działał tak jak chcesz - PWMout powinno być aktualizowane w obu pętlach.

    Pozdrawiam,
    Dr.Vee
  • #3 6472622
    soulreaver1
    Poziom 21  
    
    #define F_CPU 8000000
    #include <avr/io.h>
    #include <util/delay.h>
    #define PWMout OCR1A
    unsigned short int pwmVal;
    
    int main(void)
    { while(1)
    {
    TCCR1A=0xA3;
    TCCR1B=0x09;
    TCNT1=0x000;
    
    for(pwmVal=0; pwmVal<1023; pwmVal++);
    {
       _delay_ms(2);
    }
    PWMout=pwmVal;
    
    for(pwmVal=1023; pwmVal>0; pwmVal--);
    {
       _delay_ms(2);
    }
    PWMout=pwmVal;
      }
    } 


    teraz będzie ok? Jak można to sprawdzić na symulatorze?
  • #4 6472682
    Dr.Vee
    VIP Zasłużony dla elektroda
    Dr.Vee napisał:
    PWMout powinno być aktualizowane w obu pętlach.

    Pozdrawiam,
    Dr.Vee
  • Pomocny post
    #5 6472699
    zdebel
    Poziom 15  
    Jak Dr. Vee powiedział, przypisanie ma być W pętli, bo tak to zobacz, jak sie pierwsza wykona to po jakims tam czasie (2 * 1023 milisekund) dasz na PWM wartosc 1023, potem znów śpisz przez 2 * 1023 milisekund i przypisujesz zero PWMout, wrzuć przypisanie do obu pętli i powinno pulsować :)

    ------------
    za długo pisałem :D
  • #6 6473829
    soulreaver1
    Poziom 21  
    
    #define F_CPU 8000000
    #include <avr/io.h>
    #include <util/delay.h>
    #define PWMout OCR1A
    unsigned short int pwmVal;
    
    int main(void)
    { while(1)
    {
    TCCR1A=0xA3;
    TCCR1B=0x09;
    TCNT1=0x000;
    
    for(pwmVal=0; pwmVal<1023; pwmVal++);
    {
       _delay_ms(2);
       PWMout=pwmVal;
    }
    
    
    for(pwmVal=1023; pwmVal>0; pwmVal--);
    {
       _delay_ms(2);
      PWMout=pwmVal;
    }
    
       }
    }
    
  • #7 9092973
    adams03
    Poziom 12  
    Witam serdecznie. Co poprawić w kodzie aby wykorzystywać 3xPWM z płynną zmianą, bo jak dotąd pwm od t1 działa płynnie a przy t2 przycina, co poprawić ??

    
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    
    #include "iocompat.h"           /* Note [1] */
    
    enum { UP, DOWN };
    
    ISR (TIMER1_OVF_vect)           /* Note [2] */
    {
        static uint16_t pwm;        /* Note [3] */
        static uint8_t direction;
    
        switch (direction)          /* Note [4] */
        {
            case UP:
                if (++pwm == TIMER1_TOP)
                    direction = DOWN;
                break;
    
            case DOWN:
                if (--pwm == 0)
                    direction = UP;
                break;
        }
    OCR2 = pwm;
        OCR1A = pwm;                  /* Note [5] */
    	OCR1B = pwm;
    	
    }
    
    void
    ioinit (void)                   /* Note [6] */
    {
        /* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). */
       TCCR2  = 0x69;
        TCCR1A = 0xA3;
    	TCCR1B = 0x09;
    	
    
    
        /*
         * Start timer 1.
         *
         * NB: TCCR1A and TCCR1B could actually be the same register, so
         * take care to not clobber it.
         */
        TCCR1B |= TIMER1_CLOCKSOURCE;
        /*
         * Run any device-dependent timer 1 setup hook if present.
         *
    #if defined(TIMER1_SETUP_HOOK)
        TIMER1_SETUP_HOOK();
    #endif
    
        * Set PWM value to 0. */
        OCR1A = 0;
    
        /* Enable OC1 as output. */
        DDROC = _BV (OC1);
    	DDRB = 0x0E;
        /* Enable timer 1 overflow interrupt. */
        TIMSK = _BV (TOIE1);
        sei ();
    }
    
    int
    main (void)
    {
    
        ioinit ();
    
        /* loop forever, the interrupts are doing the rest */
    
        for (;;)                    /* Note [7] */
           sleep_mode();
    
        return (0);
    }
    
    


    Dodano po 20 [minuty]:

    I pomogłem sobie sam :]

    Mianowicie zmienna pwm jest 16bit dla t1 ok, ale t2 jest 8bit.

    Pozdrawiam.
  • Pomocny post
    #8 9096800
    mgiro
    Poziom 22  
    soulreaver1 Musisz w rejestrze DDR portu z którego korzystać ustawić nóżki procka jako wyjścia. Poczytaj w dokumentacji.
  • #9 9219082
    bullyman
    Poziom 11  
    siema ja to robię tak i ładnie pulsuje, może Ci się przyda;)

    #include <avr/io.h>
    #include <util/delay.h>
    #define time 2
    
    void main()
    {
    	DDRB |= _BV(PB3);
    	TCCR2 =(1<<COM21)|(1<<WGM20)|(1<<CS10);
    	
    	while(1)
    	{
    	 unsigned char i=0;
    	 
    		for(i=0;i<250;i++)
    		{
    		OCR2 = i;
    		_delay_ms(time);
    		}
    		for(i=250;i>0;i--)
    		{
    		OCR2 = i;
    		_delay_ms(time);
    		}
    }
    }
    
REKLAMA