www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

PWM in Atmega32-nastavljanje frekvence in duty cycla

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Osnove programiranja AVR-jev
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
rakec14
Član
Član



Pridružen-a: Ned 20 Sep 2009 10:50
Prispevkov: 11
Aktiv.: 0.06
Kraj: Celje

PrispevekObjavljeno: Čet Sep 27, 2012 1:04 am    Naslov sporočila:  PWM in Atmega32-nastavljanje frekvence in duty cycla Odgovori s citatom

Pozdravljeni!

Sem začetnik v programiranju AVR-jev in delu s C-jem. Zanima me, kako napisati kodo za Atmega32, da bi lahko nastavljal frekvenco in duty cycle PWM-ja z gumboma + in - . To je moja koda (malo sposojena, malo napisana), ki ne dela.

Koda:

 
#include <avr/io.h>
#include <util/delay.h>


   
  void pwm_init ()
   {
   
     TCCR1A = (1<<COM1A1) | (1<<WGM11);//Clear OC1A on compare, bottom
     TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS12);//Fast PWM top=ICR1 , 256 prescaler   
    ICR1=0x0014; // set TOP
    OCR1A=0x00FF; // set duty cycle
   
     DDRD |= (1<<PD5);// set PD5 as output    
   }
   
 
  void main ()
   {
    uint8_t duty;
   duty = 0;
   
    uint8_t freq;
    freq = 0;
 
   
    while(1)
    {
        // increment duty
        if (PD0)
        {
        if (duty <= 245)
          {
          //increment duty by 10
          duty = duty + 10;
                
             // set the duty in OCR1A
             OCR1A = duty;
             
         }_delay_ms(35);
        }
     
       
     
        // decrement duty
        if (PD1)
        {
        if (duty >= 10) 
         {
          //decrement duty by 10
             duty = duty - 10;
                 
             // set the duty in OCR1A
             OCR1A = duty;
          _delay_ms(35);
         }
         
         
        }
      
      
      
      
      
      //increment freq
      if (PD2)
      {
        if (freq >=1) 
          {
          //increment freq by 10
          freq = --freq;
         
         
          //set the freq in ICR1
          ICR1 = freq;
          _delay_ms(35);
         }
         
         
         
         
         // decrement freq
        if (PD3)
        {
        if (freq <= 18) 
         {
          //decrement freq by 10
             freq = ++freq;
                 
             // set the freq in ICR1
             ICR1 = freq;
          _delay_ms(35);
         }
         
         
        }
      
      }
     
        // repeat this forever
    }
   
   
   }



Že vnaprej se vam zahvaljujem za pomoč!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
urosg
Član
Član



Pridružen-a: Pet 27 Apr 2007 14:30
Prispevkov: 565
Aktiv.: 2.56

PrispevekObjavljeno: Čet Sep 27, 2012 7:12 am    Naslov sporočila:   Odgovori s citatom

Sicer sam ne delam nič z ATMega ampak programiram kaj drugega, iz samega stališča osnovne zanke bi rekel da napak ni, bolj se mi poraja vprašanje če je inicializacija in nastavitev I/O pinov pravilna.

Poleg tega imaš sicer definirano funkcijo "pwm_init()" vendar je niti ne pokličeš na začetku main().

Za lažjo pomoč naprej bo pripomoglo tudi to če boš priložil shemo vezja, ki ga imaš, saj bomo le tako lahko točno videli, če naslavljaš prave pine.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
gumby
Član
Član



Pridružen-a: Sob 28 Apr 2007 12:32
Prispevkov: 4066
Aktiv.: 18.41

PrispevekObjavljeno: Čet Sep 27, 2012 8:53 am    Naslov sporočila:   Odgovori s citatom

PD0..PD3 niso dejanska stanja na pinu, ampak samo indeks bita v registrih.
_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
rakec14
Član
Član



Pridružen-a: Ned 20 Sep 2009 10:50
Prispevkov: 11
Aktiv.: 0.06
Kraj: Celje

PrispevekObjavljeno: Čet Sep 27, 2012 10:26 am    Naslov sporočila:   Odgovori s citatom

Spremenil sem vhodne pine na port B in vključil pwm_init() v main zanko, vendar vseeno ne da nič od sebe. Program preizkušam na programatorju STK500. Na PORTB imam priključene tipke, na PORTD pa ''ledice''.

Popravljena koda:
Koda:

 
#include <avr/io.h>
#include <util/delay.h>


   
  void pwm_init ()
   {
   
     TCCR1A = (1<<COM1A1) | (1<<WGM11);//Clear OC1A on compare, bottom
     TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS12);//Fast PWM top=ICR1 , 256 prescaler   
    ICR1=0x0014; // set TOP
    OCR1A=0x00FF; // set duty cycle
   
     DDRD |= (1<<PD5);// set PD5 as output    
   
    DDRB = 0x00;                //PORTB as input
    PORTB = 0x0F;                //enable pull ups for pins 0, 1, 2, 3
   
   }
   
 
  int main (void)
   {
    uint8_t duty;
   duty = 0;
   
    uint8_t freq;
    freq = 0;
   
   pwm_init;
 
   
    while(1)
    {
        // increment duty
        if (PINB == 0x01)
        {
        if (duty <= 245)
          {
          //increment duty by 10
          duty = duty + 10;
                
             // set the duty in OCR1A
             OCR1A = duty;
             
         }_delay_ms(35);
        }
     
       
     
        // decrement duty
        if (PINB == 0x02)
        {
        if (duty >= 10) 
         {
          //decrement duty by 10
             duty = duty - 10;
                 
             // set the duty in OCR1A
             OCR1A = duty;
          _delay_ms(35);
         }
         
         
        }
      
      
      
      
      
      //increment freq
      if (PINB == 0x04)
      {
        if (freq >=1) 
          {
          //increment freq by 10
          freq = --freq;
         
         
          //set the freq in ICR1
          ICR1 = freq;
          _delay_ms(35);
         }
         
         
         
         
         // decrement freq
        if (PINB == 0x08)
        {
        if (freq <= 18) 
         {
          //decrement freq by 10
             freq = ++freq;
                 
             // set the freq in ICR1
             ICR1 = freq;
          _delay_ms(35);
         }
         
         
        }
      
      }
     
        // repeat this forever
    }
   
   
   }
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
lojzek
Član
Član



Pridružen-a: Pet 25 Jan 2008 8:00
Prispevkov: 3387
Aktiv.: 16.00

PrispevekObjavljeno: Čet Sep 27, 2012 10:41 am    Naslov sporočila:   Odgovori s citatom

@rakec14: če delaš z AVR Studiem, poiskusi program najprej v njegovem programskem simulatorju... Tam boš hitro videl (sploh pri tem kratkem programu), kje ga v temo brcaš..

Kot prvo mi pa niso tisti
Koda:
if (PINB == 0x01)

stavki všeč. Zakaj: ker običajno uporabljamo na vhodih interne pullup upore (normalna vrednost vhoda = 1 in tako bi PINB imel vrednost 0xFF, ko ni nič pritisnjenega), tipka pa vhod postavi na maso (vrednost vhoda = 0, torej 0b11111101 ali 0xFD).

In tako bi za uresničitev tega pogoja moral pritisniti tipke na vhodih PB0, PB2 - PB7 naenkrat.

Kapiš?

EDIT: nisem se pa poglagljal v registre in njihovo definicijo, ki jo izvedeš na začetku... Če so te stvari prav nastavljene, lahko hitro preveriš s simulatorjem in datasheetom...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
tilz0R
Član
Član



Pridružen-a: Čet 31 Maj 2012 15:39
Prispevkov: 898
Aktiv.: 5.65
Kraj: Črnomelj

PrispevekObjavljeno: Pet Sep 28, 2012 3:15 pm    Naslov sporočila:   Odgovori s citatom

ampak funkcije pwm_init() še vedno nisi klical v glavnem programu Smile
_________________
Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
rakec14
Član
Član



Pridružen-a: Ned 20 Sep 2009 10:50
Prispevkov: 11
Aktiv.: 0.06
Kraj: Celje

PrispevekObjavljeno: Ned Sep 30, 2012 3:06 pm    Naslov sporočila:   Odgovori s citatom

Sem dal pwm_init; v glavno zanko, ampak še kar ne dela. Ne vem, če nimam narobe definiran ICR1, ampak ne vem, kako bi ga moral nastaviti.


Koda:

 
#include <avr/io.h>
#include <util/delay.h>


   
  void pwm_init ()
   {
   
     TCCR1A = (1<<COM1A1) | (1<<WGM11);//Clear OC1A on compare, bottom
     TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS12);//Fast PWM top=ICR1 , 256 prescaler   
    ICR1=0x0014; // set TOP
    OCR1A=0x00FF; // set duty cycle
   
     DDRD |= (1<<PD5);// set PD5 as output    
   
    DDRB = 0x00;                //PORTB as input
    PORTB = 0x0F;                //enable pull ups for pins 0, 1, 2, 3
   
   }
   
 
  int main (void)
   {
   
   
   
   uint8_t duty;
   duty = 0;
   
    uint8_t freq;
    freq = 0;
   
   
 
   
    while(1)
    {
   
       pwm_init;
       
      // increment duty
        if (PINB == 0x01)
        {
        if (duty <= 245)
          {
          //increment duty by 10
          duty = duty + 10;
                
             // set the duty in OCR1A
             OCR1A = duty;
             
         }_delay_ms(35);
        }
     
       
     
        // decrement duty
        if (PINB == 0x02)
        {
        if (duty >= 10) 
         {
          //decrement duty by 10
             duty = duty - 10;
                 
             // set the duty in OCR1A
             OCR1A = duty;
          _delay_ms(35);
         }
         
         
        }
      
      
      
      
      
      //increment freq
      if (PINB == 0x04)
      {
        if (freq >=1) 
          {
          //increment freq by 10
          freq = --freq;
         
         
          //set the freq in ICR1
          ICR1 = freq;
          _delay_ms(35);
         }
         
         
         
         
         // decrement freq
        if (PINB == 0x08)
        {
        if (freq <= 18) 
         {
          //decrement freq by 10
             freq = ++freq;
                 
             // set the freq in ICR1
             ICR1 = freq;
          _delay_ms(35);
         }
         
         
        }
      
      }
     
        // repeat this forever
    }
   
   
   }
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
tilz0R
Član
Član



Pridružen-a: Čet 31 Maj 2012 15:39
Prispevkov: 898
Aktiv.: 5.65
Kraj: Črnomelj

PrispevekObjavljeno: Ned Sep 30, 2012 3:08 pm    Naslov sporočila:   Odgovori s citatom

pwm_init kliči samo 1x, torej preden začneš z while zanko.

in pa kliči jo kot funkcijo, torej
Koda:
pwn_init();

_________________
Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
lojzek
Član
Član



Pridružen-a: Pet 25 Jan 2008 8:00
Prispevkov: 3387
Aktiv.: 16.00

PrispevekObjavljeno: Pon Okt 01, 2012 7:19 am    Naslov sporočila:   Odgovori s citatom

Neutral A mojega posta pa nisi ne prebral in ne upošteval? Eh?
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
rakec14
Član
Član



Pridružen-a: Ned 20 Sep 2009 10:50
Prispevkov: 11
Aktiv.: 0.06
Kraj: Celje

PrispevekObjavljeno: Pon Okt 01, 2012 8:43 pm    Naslov sporočila:   Odgovori s citatom

Lojzek, sem prebral, vendar nisem vedel, kako bi spremenil. Ka si mislil tako:
Koda:

#define F_CPU 1000000UL
 
#include <avr/io.h>
#include <util/delay.h>


   
  void pwm_init ()
   {
   
     TCCR1A = (1<<COM1A1);//Clear OC1A on compare, bottom
     TCCR1B = (1<<WGM13) | (1<<CS12);//phase&frequency PWM top=ICR1 , 256 prescaler   
    ICR1=0x0000; // set TOP
    OCR1A=0x0000; // set duty cycle
   
     DDRD |= (1<<PD5);// set PD5 as output    
   }
   
 
  int main (void)
   {
    pwm_init();
   
    uint16_t duty;
   duty = 0;
   
    uint16_t freq;
    freq = 0;
 
   
    while(1)
    {
        // increment duty
        if (!(PIND&0xO1))
        {
        if (duty <= 58981)
          {
          //increment duty by 10
          duty = duty + 6555;
                
             // set the duty in OCR1A
             duty = OCR1A;
             
         }_delay_ms(35);
        }
     
       
     
        // decrement duty
        if  (!(PIND&0xO2))
        {
        if (duty >= 6555) 
         {
          //decrement duty by 10
             duty = duty - 6555;
                 
             // set the duty in OCR1A
             duty = OCR1A;
          _delay_ms(35);
         }
         
         
        }
      
      
      
      
      
      //increment freq
      if  (!(PIND&0xO4))
      {
        if (freq <= 58981) 
          {
          //increment freq by 10
          freq = freq + 6555;
         
         
          //set the freq in ICR1
          freq = ICR1;
          _delay_ms(35);
         }
         
         
         
         
         // decrement freq
        if  (!(PIND&0xO8))
        {
        if (freq <= 6555) 
         {
          //decrement freq by 10
             freq = freq - 6555;
                 
             // set the freq in ICR1
             freq = ICR1;
          _delay_ms(35);
         }
         
         
        }
      
      }
     
        // repeat this forever
    }
   
   
   }
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
lojzek
Član
Član



Pridružen-a: Pet 25 Jan 2008 8:00
Prispevkov: 3387
Aktiv.: 16.00

PrispevekObjavljeno: Tor Okt 02, 2012 6:05 am    Naslov sporočila:   Odgovori s citatom

A simulacijo programa si pa poizkusil? Tam lahko tudi tipke pritiskaš, spreminjaš vrednosti spremenljivk,... Seveda če delaš z aVR studiem

Drugače pa jaz preverjam stanje enega vhoda npr. takole:

Koda:
if(bit_is_clear (PINB, 1))
{
.
}

ali pa nasprotna verzija:
Koda:
if (bit_is_set (PINB,1))
{
.
}


Ta princip deluje tudi na spremenljivkah, ne samo na vhodih/izhodih. Mi preverjanje stanja bita z maskami ni tako "razumljivo"
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
rakec14
Član
Član



Pridružen-a: Ned 20 Sep 2009 10:50
Prispevkov: 11
Aktiv.: 0.06
Kraj: Celje

PrispevekObjavljeno: Tor Okt 16, 2012 11:04 am    Naslov sporočila:   Odgovori s citatom

V simulaciji se mi PORTB nič ne spremeni.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Osnove programiranja AVR-jev Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 493 dni


Powered by phpBB © 2001, 2005 phpBB Group