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

[ATTINY2313] [C] Problem z zaprogramowaniem PWM

ADI-mistrzu 11 Cze 2008 16:43 4517 8
REKLAMA
  • #1 5235897
    ADI-mistrzu
    Poziom 30  
    Witam!
    Tak naprawdę dopiero wgłębiam się z mikroprocesory i języki programowania na nie.
    Obecnie bawię się ATTINY2313 i na nim ucze się tej sztuki, doszedłem do zabawy z PWM i podczas kompilowania programu wykrzacza mi takie cudo.
    [ADI_PLD-SYSTEM ~]# avr-gcc -mmcu=attiny2313 program.c -o program
    
    /tmp/ccOY9wl4.o: In function `main':
    program.c:(.text+0x7c): undefined reference to `PWM_out'

    Programuje na linuksie (PLD Th) pod konsolą.
    program wygląda następująco:
    
    #include <avr/io.h>                // dostęp do rejestrów
    #include <avr/interrupt.h>        // funkcje sei(), cli()
    #include <avr/interrupt.h>       // definicje SIGNAL, INTERRUPT
    
    #if defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \
        defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \
        defined(__AVR_ATmega163__) || defined(__AVR_ATmega16__) || \
        defined(__AVR_ATTINY2313__)
    #define PWM_out(value)        OCR1A=value
    #endif
    
    #ifdef __AVR_ATTINY2313__
    #define PWM_out(value)        OCR1=value
    #endif
    
    uint16_t pwm=512;                // zmienna zawiarająca wartość wypełnienia
    
    void delay(void)                // prosta pętla opóźniająca
    {
      unsigned int i;
      for(i=0;i<50000;i++);
    }
    
    int main(void)                        // program główny
    {
      DDRD = 0x00;                // PORTD jako wejścia dla przycisków
      PORTD = 0xFF;                // podciągaj wejścia PORTD
    
    #if defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \
        defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \
        defined(__AVR_ATmega163__) || defined(__AVR_ATmega16__) || \
        defined(__AVR_ATTINY2313__)
      sbi(DDRD,PD5);                 // ustawienie kierunku wyjscia PWM
    #endif
    #ifdef __AVR_ATTINY2313__
      sbi(DDRB,PB3);                 // ustawienie kierunku wyjscia PWM
    #endif
    
      TCCR1A = _BV(COM1A1)|_BV(COM1A0)|_BV(WGM10)|_BV(WGM11);
                                      // czasomierz 1 w trybie 10 bitowego PWM
      TCCR1B = _BV(CS00);                 // czasomierz 1 taktowany F_CPU
      pwm=512;                        // przypisz wartość początkową PWM
      while(1)                        // pętla nieskończona
      {
        PWM_out(pwm);                // wpisz pwm do OCR1
    
        if (bit_is_clear(PIND,PD3))// jeżeli zwarto PD3 z masą
        {
          delay();                        // czekaj chwilę
          if (++pwm==1024) pwm=1023;// zwiększ i ogranicz pwm
        }
        if (bit_is_clear(PIND,PD2))// jeżeli zwarto PD2 z masą
        {
          delay();                        // czekaj chwilę
          if (--pwm==0xFFFF) pwm=0;        // zmniejsz i ogranicz pwm
        }
      }
    }
    
    

    Jak zdefiniuje go jako AT90S2313 to ok kompilacja przechodzi i PWM_out mu nie przeszkadza.

    Prosił bym o wyrozumiałość, dopiero tego się uczę korzystając z przeróżnych informacji, booków i programów znajdujących się w necie.

    Pozdrawiam
  • REKLAMA
  • Pomocny post
    #2 5236264
    ZbeeGin
    Poziom 39  
    Przecież w Tiny2313 rejestry PWM są takie same jak w 2313 classic. Zatem po co tak kompikujesz:

    #if defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \ 
        defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \ 
        defined(__AVR_ATmega163__) || defined(__AVR_ATmega16__) || \ 
        defined(__AVR_ATTINY2313__) 
    #define PWM_out(value)        OCR1A=value 
    #endif 
    
    #ifdef __AVR_ATTINY2313__ 
    #define PWM_out(value)        OCR1=value 
    #endif


    Ale główny błąd polega na tym, że nazwę procesora napisałeś niezgodnie z definicją. Ma być:
    defined(__AVR_ATtiny2313__)
  • #3 5236276
    BoskiDialer
    Poziom 34  
    Po szybkim spojrzeniu do pliku <avr/io.h> można zauważyć, że nie ma czegoś takiego jak __AVR_ATTINY2313__, jest: __AVR_ATtiny2313__ (wielkość liter). Jak to poprawisz, to pojawi się problem z redefiniowaniem PWM_out (oba #if'y będą spełnione) oraz może się pojawić komunikat o braku sbi(io, bit);, który trzeba będzie zastąpić przez io|=_BV(bit);
  • REKLAMA
  • #4 5236810
    ADI-mistrzu
    Poziom 30  
    Hm... no fakt, był problem z wielkością liter. A co z tym PWM'em zrobić ?
    To przyznam że skądś ściągnąłem =P
  • REKLAMA
  • #5 5239798
    ZbeeGin
    Poziom 39  
    ADI-mistrzu napisał:
    Hm... no fakt, był problem z wielkością liter. A co z tym PWM'em zrobić ?

    A jaki jest problem z "tym PWM'em"? Przecież napisałem wcześniej, że rejestry nazywają się tak samo i dodatkowo są w tym samym miejscu.
  • #6 5239869
    ADI-mistrzu
    Poziom 30  
    No problem jest taki ze dalej wywala to:
    program.c:12:1: warning: "PWM_out" redefined
    program.c:8:1: warning: this is the location of the previous definition
    
  • Pomocny post
    #7 5239927
    BoskiDialer
    Poziom 34  
    usuń z pierwszego #if'a część defined(__AVR_ATtiny2313__) - wtedy tylko drugi #if będzie spełniony. Możesz też zastosować konstrukcję #else lub #elif.
  • REKLAMA
  • #8 5240279
    ZbeeGin
    Poziom 39  
    Myślę, że koledze mogło chodzić raczej o taką konstrukcję warunku preprocesora:
    #if defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \ 
        defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \ 
        defined(__AVR_ATmega163__) || defined(__AVR_ATmega16__) || \ 
        defined(__AVR_AT90S2313__) 
    #define PWM_out(value)        OCR1A=value 
    #endif 
    
    #ifdef __AVR_ATtiny2313__ 
    #define PWM_out(value)        OCR1B=value 
    #endif

    gdyż w Tiny2313 mamy dwa rejestry OCR licznika TIMER1. Jednakże dalsza część programu na to nie wskazuje. Brak komentarza dla tych linii pozwala Nam się tylko domyślać o co właściwie mogło chodzić.
  • #9 5240312
    ADI-mistrzu
    Poziom 30  
    Pomogło to co napisał BoskiDialer z usunięciem defined attiny2313 w #if.

    Kompilacja i całe wgranie przeszło bez przeszkód, teraz mogę tym poeksperymentować i się tego nauczyć.

    Dzięki wam wielkie za pomoc!
REKLAMA