Povečevanje delaya

Moderator: tilz0R

Povečevanje delaya

OdgovorNapisal/-a zan95 » 04 Jul 2016, 01:46

Pozdravljeni!

Zadnje čase sem se začel malce bolj ukvarjati s C-jem (popoln začetnik) oz. se ga predvsem dobro naučiti, pa se mi je ustavilo pri povečevanju delaya. Zaporedoma prižigam posamezne barve na RGB traku z določenim zamikom. Ta zamik pa želim z vsakim novim štetjem zanke povečati za n-krat oz. za n milisekund. Poskušal sem z novo funkcijo in for zanko pa nikakor ni šlo. Če dam break ali return, ostane delay na 100ms, če pa ne pa se zanka zvrti in imam 1 sekundo. Poskušal sem tudi s for zanko v main kodi, pa sem dobil enak rezultat. Ne razumem, kako bi ohranil prejšnjo vrednost delaya in ji prištel novo? :(
Ali ima for zanka v funkciji sploh učinek, da povečuje delay ali samo šteje in delay ostaja enak? Vrednosti v funkciji _delay_ms pa morajo na mojo žalost biti samo konstante.

Prosil bi za pomoč. Hvala! :_bow

Moja funkcija
Koda: Izberi vse
void delay_cont ()
{           int f;
      for(f=0; f<10; f++)
      {
         _delay_ms(100);
      break;
      }
}

Tole je v main funkciji:
Koda: Izberi vse
for(i=0;i<11;i++)
      {
         PORTA =0;
         //PORTA = 0xC0; // PA6/7
         PORTA = 0x40;
         delay_cont();
         PORTA =0;
         PORTA = 0x80;
         delay_cont();
         PORTA =0;
         PORTB = 0x04;// PB2
         delay_cont();
         PORTB =0;
         
      }

Nasvet: za preglednješe prikazano programsko kodo v prispevku uporabi funkcijo Code ("gumb" zraven bold, italic, Quote... v urejevalniku prispevka).
moderator
zan95
 
Prispevkov: 428
Pridružen: 27 Jan 2015, 23:46
Zahvalil se je: 284 krat
Prejel zahvalo: 76 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 14

Re: Povečevanje delaya

OdgovorNapisal/-a radix » 04 Jul 2016, 02:17

Beseda break kjerkoli v zanki povzroči izstop iz nje. Pri for zankah je break povsem nepotreben, saj se zanka neha izvajati, ko pogoj ni več izpolnjen.

Funkcija, ki bi ponovila _delay_ms(100); n-krat bi izgledala nekako tako:
Koda: Izberi vse
void delay_cont(int n) {
   for(int i = 0; i<n; i++) {
      _delay_ms(100);
   }
}

Sedanja funkcija void delay_cont () vedno ponovi zakasnitev samo enkrat, ali pa, če odstranimo break, desetkrat. Nikjer sploh ni načina, da bi "vedela", kolikokrat se je že izvedla...
radix
 
Prispevkov: 1547
Pridružen: 04 Feb 2015, 20:19
Kraj: Ljubljana
Zahvalil se je: 243 krat
Prejel zahvalo: 372 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 27

Re: Povečevanje delaya

OdgovorNapisal/-a igo » 04 Jul 2016, 06:50

Rešitev je čisto enostavna z uporabo globalne spremenljivke.
Tisti " int f; " daj ven iz funkcije in ga daj nekam nad void setup(); v glavnem programu, torej izven vseh funkcij, da postane globalen.

S tem se v RAM pomnilniku ne bo rezerviral prostor za f ob vsakem klicu funkcije ter se po izstopu iz funkcije sprostil, temveč se bo rezerviral ob zagonu programa in ostal rezerviran.

To pomeni, da si lahko takšne globalne spremenljivke deliš med posameznimi funkcijami. Ena nekje nastavi fmax (maksimalen f), druga čisto drugje nastavi fmin (minimalen f), spet tretja pa vsebuje for zanko oblike
for (f=fmin; f < (fmax+1); f++)
{ ... }

Globalne spremenljivke si lahko podajaš med funkcijami, in potem nastopajo v raznih števcih, for zankah, while zankah, if pogojih, ...

Lokalne spremenljivke so pa definirane znotraj funkcij in jih po uporabi zavržeš.

Jaz imam vedno globalno definirane byte i, j, k, l, unsigned int x, y, u, v in unsigned long ul32a, ul32b in z njimi naredim 75% vsega. Ostali so še razni globalni števci in nekaj lokalnih spremenljivk.
V bistvu lokalne spremenljivke uporabljam samo znotraj funkcij, ki jih kličem s parametri.
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
igo
 
Prispevkov: 1662
Pridružen: 11 Apr 2015, 13:38
Kraj: Krško
Zahvalil se je: 192 krat
Prejel zahvalo: 444 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 43

Re: Povečevanje delaya

OdgovorNapisal/-a zan95 » 04 Jul 2016, 12:22

Hvala za odgovore, se bom lotil zadeve.
zan95
 
Prispevkov: 428
Pridružen: 27 Jan 2015, 23:46
Zahvalil se je: 284 krat
Prejel zahvalo: 76 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 14

Re: Povečevanje delaya

OdgovorNapisal/-a Kroko » 04 Jul 2016, 12:40

@igo - ne vem, če je nasvet, naj uporablja globalne spremenljivke z imeni i, j, k, l, x, y, u, v dober. Verjamem, da zate to dela. Da bi se pa začetnik tako naučil pa ni prav.
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje delaya

OdgovorNapisal/-a zan95 » 04 Jul 2016, 12:47

@radix
Se pravi, moram tudi določiti vrednosti i-ja in n-ja, če ne želim, da se delay povečuje vnedogled? Potem to funckijo normalno kličem kot sem jo do sedaj?
zan95
 
Prispevkov: 428
Pridružen: 27 Jan 2015, 23:46
Zahvalil se je: 284 krat
Prejel zahvalo: 76 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 14

Re: Povečevanje delaya

OdgovorNapisal/-a igo » 04 Jul 2016, 14:16

@Kroko: se strinjam, da imena mojih globalnih spremenljivk niso ravno nek presežek. V bistvu ta imena uporabljam samo za spremenljivke, ki se v vsaki funkciji "same" inicializirajo
for(i=0; ...), ... , x=nek začasni vmesni rezultat, ... y=neka ADC vrednost, ... , kjer je predhodna vrednost povsem nepomembna.
Čisto zato, da ni treba v vsaki funkciji pisati int x; in komplicirati po RAM-u.

Spremenljivke, ki se prenašajo med funkcijami, imajo imena sestavljena iz njihovega pomena in so dosti bolj izvirna.
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
igo
 
Prispevkov: 1662
Pridružen: 11 Apr 2015, 13:38
Kraj: Krško
Zahvalil se je: 192 krat
Prejel zahvalo: 444 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 43

Re: Povečevanje delaya

OdgovorNapisal/-a rafaellsi » 04 Jul 2016, 15:53

Če prav zastopim problem, bi bila lahko rešitev tudi nekat takega:

Koda: Izberi vse
void delay_cont () {
      static int f = 0;
     
      f++;
     _delay_ms(f*100);
     
     if (f > 32000) {     
          f=0;
     } 

}
}
rafaellsi
 
Prispevkov: 424
Pridružen: 19 Jan 2015, 01:44
Kraj: Gorenjska
Zahvalil se je: 22 krat
Prejel zahvalo: 46 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 49

Re: Povečevanje delaya

OdgovorNapisal/-a radix » 04 Jul 2016, 16:03

zan95 je napisal/-a:@radix
Se pravi, moram tudi določiti vrednosti i-ja in n-ja, če ne želim, da se delay povečuje vnedogled? Potem to funckijo normalno kličem kot sem jo do sedaj?
Ni mi jasno, ali hočeš, da se delay ob vsakem klicu funkcije poveča, ali ne.

Primer funkcije, ki sem jo podal zgoraj vzame en integer (int n) in tolikokrat ponovi delay. Kratnost ponovitve funkcije za zakasnitev se nastavi ob klicu funkcije.
Če vzamemo funkcijo:
Koda: Izberi vse
void delay_cont(int n) {
   for(int i = 0; i<n; i++) {
      _delay_ms(100);
   }
}
in jo kličemo tako,
Koda: Izberi vse
void delay_cont(5);
bo petkrat izvršila zakasnitev 100 ms in končala z izvajanjem. Seveda lahko konstanto 5 nadomestimo tudi s spremenljivko. Če tako funkcijo damo v originalno kodo, kjer je klicana po vsaki spremembi PORTA/B, je potrebno potem zakasnitve ročno povečevati ob vsakem klicu.
radix
 
Prispevkov: 1547
Pridružen: 04 Feb 2015, 20:19
Kraj: Ljubljana
Zahvalil se je: 243 krat
Prejel zahvalo: 372 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 27

Re: Povečevanje delaya

OdgovorNapisal/-a igo » 04 Jul 2016, 18:32

Koda: Izberi vse
#define kPavzaMax 150;  // konstanta Maksimalna Pavza
#define kPavzaMin 40; // konstanta Minimalna Pavza

#define vhPavzaGor  vhodni pin
#define vhPavzaDol
#define izhRGB izhodni pin
// Splosno:
byte i; // 8-bitni splosni stevec

// Namensko:
byte PavzaRGB; // kPavzaMin <= PavzaRGB <= kPavzaMax


void setup()
{
 PavzaRGB = kPavzaMin; // zacetna vrednost
 Nastavi ustrezne pine, da so vhodi oziroma izhodi
}

void loop // GLAVNA ZANKA
{

  pBereVhode();
  pPavzaRGB();

} // loop

// ======= PODPROGRAMI

void pBereVhode() // podprogram, ki bere Vhode
{
 if((vhPavzaGor == 1) && (PavzaRGB < kPavzaMax))
 {
  PavzaRGB++; // Ce ni vecja od dovoljene, Tipka za povecanje pavze poveca pavzo
 }
 if((vhPavzaDol == 1) && (PavzaRGB > kPavzaMin))
 {
  PavzaRGB--; // Ce ni manjsa od dovoljene, Tipka za zmanjsanje pavze zmanjsa pavzo
 }
} // pBereVhode


void pPavzaRGB() // Podprogram za Pavzo RGB
{
 for(i=0; i < PavzaRGB +1; i++)
 {
  Delay_ms(10); // 10 ms * PavzaRGB
 }
 if(izhRGB == 1)
  {
   izhRGB =0; // spremeni stanje izhoda iz 1 na 0
 else
   {
    izhRGB = 1; // spremeni stanje izhoda iz 0 v 1
   }
} // pPavzaRGB
Približno tako naj bi izgledala struktura programa, da je lepo pregledna.
Samo definiraj pine in bi moralo delovati. To je osnova, ti pa nadgrajuj.
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
igo
 
Prispevkov: 1662
Pridružen: 11 Apr 2015, 13:38
Kraj: Krško
Zahvalil se je: 192 krat
Prejel zahvalo: 444 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 43

Re: Povečevanje delaya

OdgovorNapisal/-a zan95 » 04 Jul 2016, 19:23

Hvala za vse vaše odgovore. Zadevo sem tudi z vašo pomočjo uspel rešiti takole:
Koda: Izberi vse
for(i=0;i<10;i++)
      {
         PORTA =0;
         //PORTA = 0xC0; // PA6/7
         PORTA = 0x40;
         delay_cont(i);
         PORTA =0;
         PORTA = 0x80;
         delay_cont(i);
         PORTA =0;
         PORTB = 0x04;// PB2
         delay_cont(i);
         PORTB =0;
         
      }


in pa še funkcija:
Koda: Izberi vse
void delay_cont (int x)
{   
   int i;
   
      for(i=0; i<x; i++)
      {
         _delay_ms(100);
      }
   
}
zan95
 
Prispevkov: 428
Pridružen: 27 Jan 2015, 23:46
Zahvalil se je: 284 krat
Prejel zahvalo: 76 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 14

Re: Povečevanje delaya

OdgovorNapisal/-a zan95 » 04 Jul 2016, 19:32

@rafaellsi sem poskušal s podobnimi variantami pa sem kot rezultat dobil errorje, ki so na sliki.
Nimate dovoljenj za ogled prilog tega prispevka.
zan95
 
Prispevkov: 428
Pridružen: 27 Jan 2015, 23:46
Zahvalil se je: 284 krat
Prejel zahvalo: 76 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 14

Re: Povečevanje delaya

OdgovorNapisal/-a igo » 04 Jul 2016, 19:39

Koda: Izberi vse
#define kRGBpavzaMax 150;  // konstanta Maksimalna Pavza
#define kRGBpavzaMin 40; // konstanta Minimalna Pavza

#define izhRGB   nek izhodni pin

// Splosno:
byte i; // 8-bitni splosni stevec

// Namensko:
byte RGBpavza; // kRGBpavzaMin <= RGBpavza <= kRGBpavzaMax
byte RGBsmer; // 0 narasca; 1 upada

void setup()
{
 RGBpavza = kRGBpavzaMax; // zacetna vrednost
 //Nastavi ustrezne pine, da so vhodi oziroma izhodi
}

void loop // GLAVNA ZANKA
{

  pRGBlogika(); // pripravi spremenljivko za pavzo
  pRGBpavza(); // pocaka in spremeni izhod

} // loop

// ======= PODPROGRAMI

void pRGBlogika() // podprogram, ki pripravi vse v zvezi z RGB
{
 if((RGBsmer == 0) && (RGBpavza < kRGBpavzaMax))
 {
  RGBpavza++; // Ce je smer Narascanje in ni vecja od dovoljene, poveca pavzo
 }
 if((RGBsmer == 1) && (RGBpavza > kRGBpavzaMin))
 {
  PavzaRGB--; // Ce je smer Upadanje in ni manjsa od dovoljene, zmanjsa pavzo
 }
 if(RGBpavza == kRGBpavzaMax)
  {
   RGBsmer = 1; // nastavi smer na Upadanje
  }
 if(RGBpavza == kRGBpavzaMin)
  {
   RGBsmer = 0; // nastavi smer na Narascanje
  }
} // pRGBlogika


void pRGBpavza() // Podprogram za Pavzo RGB
{
 for(i=0; i < RGBpavza+1; i++)
 {
  Delay_ms(10); // 10 ms * RGBpavza
 }
 if(izhRGB == 1) // ce je 1 ...
  {
   izhRGB = 0; // ... spremeni stanje izhoda iz 1 na 0
 else // sicer je 0 in ...
   {
    izhRGB = 1; // ... spremeni stanje izhoda iz 0 v 1
   }
} // pRGBpavza
Sem komaj zdaj opazil, da še nimaš vhodov.
Samo pravilno definiraj izhod (odvisno od prevajalnika, zato sem pustil prazno) in bi moralo delovati.
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
igo
 
Prispevkov: 1662
Pridružen: 11 Apr 2015, 13:38
Kraj: Krško
Zahvalil se je: 192 krat
Prejel zahvalo: 444 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 43

Re: Povečevanje delaya

OdgovorNapisal/-a gumby » 04 Jul 2016, 19:46

zan95 je napisal/-a:...pa sem kot rezultat dobil errorje, ki so na sliki.


Kot prvo definiraj F_CPU, preden vključiš delay.h (primer za 8MHz clock):
Koda: Izberi vse
#define F_CPU 8000000UL
#include <util/delay.h>


Kot drugo, funkcija _delay_ms() in _delay_us() je mešanica čaranja z makroji in asm ukazov, zato potrebuje konstanto za parameter. Ti imaš tam spremenljivko in ti javlja napako "__builtin_avr_delay_cycles expects a compile time integer constant". Poleg tega moraja biti vklopljena optimizacija, drugače ne bo delalo. Tule imaš malo branja na to temo.
my brain hurts
Uporabniški avatar
gumby
 
Prispevkov: 2858
Pridružen: 14 Jan 2015, 19:49
Kraj: Lendava
Zahvalil se je: 123 krat
Prejel zahvalo: 786 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 80

Re: Povečevanje delaya

OdgovorNapisal/-a zan95 » 04 Jul 2016, 20:43

@igo
Izhode sem imel določene, le nisem prilepil tistega dela kode.

@gumby
Tudi, ko sem definiral, so bile napake iste (je še star screenshot, kjer sem pozabil nekaj malenkosti, F_CPU imam 1000000UL). Se bom z veseljem lotil branja Hvala za priporočilo.
zan95
 
Prispevkov: 428
Pridružen: 27 Jan 2015, 23:46
Zahvalil se je: 284 krat
Prejel zahvalo: 76 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 14

Re: Povečevanje delaya

OdgovorNapisal/-a gumby » 04 Jul 2016, 20:47

Daj nov screenshot, ker mi ne vidimo, kake napake ti javlja ;)
my brain hurts
Uporabniški avatar
gumby
 
Prispevkov: 2858
Pridružen: 14 Jan 2015, 19:49
Kraj: Lendava
Zahvalil se je: 123 krat
Prejel zahvalo: 786 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 80

Re: Povečevanje delaya

OdgovorNapisal/-a zan95 » 04 Jul 2016, 20:52

Ne, sedaj je vse okej in stvar dela :D odgovoril sem le rafaellsi-ju, da mi je pri izvedbah podobnim njegovi javljalo take napake. Če se ne motim ima tudi on uporabljeno spremenljivko v kodi.
zan95
 
Prispevkov: 428
Pridružen: 27 Jan 2015, 23:46
Zahvalil se je: 284 krat
Prejel zahvalo: 76 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 14


Vrni se na C in sorodni jeziki

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost