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 

Začetniški problem v C-ju pri AVR-ju
Pojdi na stran Prejšnja  1, 2, 3 ... 13, 14, 15 ... 27, 28, 29  Naslednja
 
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
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.98
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Ned Feb 21, 2010 6:01 pm    Naslov sporočila:   Odgovori s citatom

sortaj je napisal/a:

Koda:

      for(int i = 128; i >1; i -= i/2)



Če sem prav razbral, je problem v tej vrstici. Poskusi tako:
Koda:

      for(int i = 128; i >=1; i -= i/2)


LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Samo87
Član
Član



Pridružen-a: Pet 25 Jan 2008 2:14
Prispevkov: 462
Aktiv.: 2.35
Kraj: Kamnik

PrispevekObjavljeno: Ned Feb 21, 2010 8:54 pm    Naslov sporočila:   Odgovori s citatom

Naredil sem kodno ključavnico, ki sicer pravilnio deluje, vendar sem eno stvar programsko zelo nerodno rešil. Vrednosti tipk shranjujem v char geslo[], in ko se vpiše prava koda (štirje pravilni znaki), se na LCD izpiše "ODKLENJENO", v nasprotnem primeru pa "ZAKLENJENO". Problem je, da ne znam v enem if stavku pravilno postavit pogoja, da bi se celotni znakovni niz primerjal, ampak znam primerjati le posamezno spremenljivko v nizu.
Tako imam za primer pravilne kode "1234" napisano kodo:
Koda:

if (geslo[0]=='1')
{
   if (geslo[1]=='2')
   {
      if (geslo[2]=='3')
      {
         if (geslo[3]=='4')
         {
         lcd_gotoxy(0,0);
         LCDputs("ODKLENJENO");
         }
         else
         {
         lcd_gotoxy(0,0);
         LCDputs("ZAKLENJENO");
         }
      }
      else
      {
      lcd_gotoxy(0,0);
      LCDputs("ZAKLENJENO");
      }
   }
   else
   {
   lcd_gotoxy(0,0);
   LCDputs("ZAKLENJENO");
   }
}
else
{
lcd_gotoxy(0,0);
LCDputs("ZAKLENJENO");
}


Kako bi to izvedel v enem if stavku?
Hvala!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
silvo_v
Član
Član



Pridružen-a: Pon 11 Jul 2005 22:00
Prispevkov: 146
Aktiv.: 0.66
Kraj: Domžale

PrispevekObjavljeno: Ned Feb 21, 2010 9:14 pm    Naslov sporočila:   Odgovori s citatom

Mogoče takole:

Koda:
 if (geslo[0]=='1' && geslo[1]=='2' && geslo[2]=='3' && geslo[3]=='4')
         { ...


Lp
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Samo87
Član
Član



Pridružen-a: Pet 25 Jan 2008 2:14
Prispevkov: 462
Aktiv.: 2.35
Kraj: Kamnik

PrispevekObjavljeno: Ned Feb 21, 2010 9:41 pm    Naslov sporočila:   Odgovori s citatom

Sem prepričan, da sem točno takole tudi že preizkusil, pa takrat ni delovalo... No, sedaj sem še enkrat tako poizkusil, pa začuda deluje! Izgleda, da sem prejšnjič pozabil enojne narekovaje, ali pa kaj drugega...
Hvala Silvo!
No, pa vseeno me zanima, če se da tudi cel niz primerjat? Nekaj v tem stilu if(geslo[]=="1234")?
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.98
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Pon Feb 22, 2010 4:51 am    Naslov sporočila:   Odgovori s citatom

strcmp.

LP!
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.: 19.74

PrispevekObjavljeno: Pon Feb 22, 2010 8:03 am    Naslov sporočila:   Odgovori s citatom

Za strcmp() ne pozabi dodat na koncu niza še znak '\0'. Niz mora bit dolg vsaj 5 znakov, torej "char geslo[5];".

Sicer pa geslo lahko že pri branju pretvoriš v integer (ali BCD) in se na ta način izogneš uporabi char[].

_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Samo87
Član
Član



Pridružen-a: Pet 25 Jan 2008 2:14
Prispevkov: 462
Aktiv.: 2.35
Kraj: Kamnik

PrispevekObjavljeno: Pon Feb 22, 2010 8:19 pm    Naslov sporočila:   Odgovori s citatom

Eto, sem naredil s strcmp(). Hvala!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Samo87
Član
Član



Pridružen-a: Pet 25 Jan 2008 2:14
Prispevkov: 462
Aktiv.: 2.35
Kraj: Kamnik

PrispevekObjavljeno: Sob Mar 13, 2010 7:18 pm    Naslov sporočila:   Odgovori s citatom

Živ! Imam vprašanje. Na EasyAVR5 imam Atmega16, uporabljen je zunanji kristal 10.240 MHz in sprogramiral sem uro z alarmom. Vse deluje kot mora, le natančnost je zelo slaba. V enem dnevu prehiti za približno 16 sekund!! Zdaj pa me zanima, kaj bi bil lahko vzrok za tako veliko napako. Ali je možno, da je kristal tako nenatančen? V programu mi timer2 skrbi samo za sekundni interval:
Koda:
ISR(TIMER2_OVF_vect)
{
TCNT2 = 6;
overflow_counter_sec++;    //na vsake 0.025s se poveča
if(overflow_counter_sec==40)    //40 * 0.025s = 1s
   {
   overflow_counter_sec=0;    //reset števca
   sec++;    //povečanje sekund
   if(sec==60) {sec=0; min++; if(min==60) {min=0; hour++; if(hour==24) hour=0;}}
   }
}

Preescaler je 1024, torej bi po moje moralo vse štimat. Imate kak nasvet?
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.: 19.74

PrispevekObjavljeno: Sob Mar 13, 2010 8:37 pm    Naslov sporočila:   Odgovori s citatom

Navadni kristali imajo točnost nekje 50ppm, kar na dan znese nekaj čez 4 sekunde. 16 sekund na dan je pa 185ppm - dvomim, da je kristal tako netočen.

Poglej v sumulatorju, na koliko ciklov se ti sproži prekinitv in potem preračunaj...

_________________
Tule nisem več aktiven.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
int47
Član
Član



Pridružen-a: Pon 15 Dec 2003 0:10
Prispevkov: 2066
Aktiv.: 9.30
Kraj: Ljubljana

PrispevekObjavljeno: Sob Mar 13, 2010 8:47 pm    Naslov sporočila:   Odgovori s citatom

Problem je čas od postavitve prekinitvene zastavice timerja, do (programskega) vpisa nove vrednosti v timer2.

Min. potreben čas lahko oceniš in popraviš program. Vendar na odzivni čas vpliva tudi program, ki ga uC izvaja.
Bolje bi bilo, če bi vpis nove vrednosti v timer izvedel hardver (CTC).
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Samo87
Član
Član



Pridružen-a: Pet 25 Jan 2008 2:14
Prispevkov: 462
Aktiv.: 2.35
Kraj: Kamnik

PrispevekObjavljeno: Ned Mar 14, 2010 1:52 pm    Naslov sporočila:   Odgovori s citatom

@gumby
Torej ni kristal. Hm, simulatorja pa še nisem nikoli uporabljal. Se bom poglobil v zadevo.

@int47
Če prav razumem: Zastavica se postavi točno ob preskoku TCNT2 iz 255 na 0. Problem pa naj bi bil čas od te točke, pa dokler se v prekinitveni rutini ne vpiše začetna vrednost 6 v TCNT2?

Kako pa naj ocenim ta čas? Se ta čas tudi lahko ugotovi s simulacijo?

Ta projekt je sicer le učenje C-ja in spoznavanje AVR-jev, ampak vseeno bi rad, da stvar deluje brez napak.

int47 je napisal/a:
Bolje bi bilo, če bi vpis nove vrednosti v timer izvedel hardver (CTC).

Lahko predlagaš kako konkretno rešitev?
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
int47
Član
Član



Pridružen-a: Pon 15 Dec 2003 0:10
Prispevkov: 2066
Aktiv.: 9.30
Kraj: Ljubljana

PrispevekObjavljeno: Ned Mar 14, 2010 3:04 pm    Naslov sporočila:   Odgovori s citatom

Čas lahko ugotoviš s simulacijo, ali štetjem ukazov in ciklov.
Problem je, da ta čas ni nujno vedno enak:

uC mora najprej zaključiti ukaz, ki se trenutno izvaja (ne trajajo vsi ukazi enako dolgo).
Če v prekinitveni rutini nisi (ponovno) omogočil prekinitev, so le te onemogočene do zaključka prekinitvene rutine.
Če sta hkrati aktivni dve prekinitveni zastavici, se bo izvršila tista, ki ima večjo prioriteto.

CTC = način delovanja timerja: (8 bit timer/counter2 with... -> Modes of operation -> Clear timer on compare match.

Svoj del napake lahko prispeva tudi netočnost kristala.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Samo87
Član
Član



Pridružen-a: Pet 25 Jan 2008 2:14
Prispevkov: 462
Aktiv.: 2.35
Kraj: Kamnik

PrispevekObjavljeno: Ned Mar 14, 2010 5:41 pm    Naslov sporočila:   Odgovori s citatom

Aha. No, rad bi razčistil še nekaj stvari: Torej, program se izvaja. In ko se izpolni pogoj za prekinitev, se postavi zastavica za to prekinitev. Program potem takoj po zaključenem ukazu, ki ga je takrat izvajal, skoči v prekinitveno rutino. Takrat se ta zastavica tudi pobriše, program pa ne glede na karkoli, najprej izvede celo prekinitveno rutino in se potem vrne v glavni program, če vmes ni bila postavljena kaka zastavica. Če pa je že vmes spet izpolnjen pogoj za prekinitev (taisto, ali kako drugo), se zastavica spet postavi, torej se takoj po izvedeni prekinitvi spet izvede prekinitev (taista ali katerakoli druga). Če pride do tega, da se med prekinitvijo izpolnita pogoja za dve različni prekinitvi, se torej postavita dve zastavici. Potem pa se najprej izvede tista prekinitev, ki ima večjo prioriteto, potem pa takoj še druga. Potem se naprej izvaja glavni program. Ali je tako, kot sem napisal, ali kaj narobe razumem?

Citiram:
Če v prekinitveni rutini nisi (ponovno) omogočil prekinitev, so le te onemogočene do zaključka prekinitvene rutine.

Tega sedaj ne razumem čisto. Za kakšno omogočenje gre tukaj? Ali je to mišljeno tako, da se tudi sama prekinitev lahko zaustavi, če je izpolnjen pogoj za kako drugo prekinitev?

Citiram:
Če sta hkrati aktivni dve prekinitveni zastavici, se bo izvršila tista, ki ima večjo prioriteto.

Torej, kot sem zgoraj napisal, se po prvi prekinitvi, ki ima večjo prioriteto, izvede še druga prekinitvena rutina?

Saj vem, da mora to tudi v datasheetu pisat, ampak včasih je težko točno razumet, za kaj gre. In ko ne veš točno, kako se program izvaja, prihaja do takih napak.

Sem pa še malo gledal po forumu in sem zasledil rešitev v čipu PCF8385, kateri odpravi še težave z izpadom napajanja, saj se ti čas ohrani.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
int47
Član
Član



Pridružen-a: Pon 15 Dec 2003 0:10
Prispevkov: 2066
Aktiv.: 9.30
Kraj: Ljubljana

PrispevekObjavljeno: Ned Mar 14, 2010 9:54 pm    Naslov sporočila:   Odgovori s citatom

Citiram:
Ali je tako, kot sem napisal, ali kaj narobe razumem?

Mislim, da bo kar prav.

Citiram:
Ali je to mišljeno tako, da se tudi sama prekinitev lahko zaustavi, če je izpolnjen pogoj za kako drugo prekinitev?

Ja. Za čas trajanja prekinitve uC globalno onemogiči prekinitve (bit I v SREG).
Če v prekinitveni rutini ponovno omogočiš prekinitve, se lahko izvrši druga prekinitev v času trajanja prve prekinitvene rutine.

Na žalost 8 bit AVR ne pozna prioritet prekinitev v stilu: Izvajanje prekinitve z nižjo prioriteto lahko prekine le prekinitev z višjo.

Citiram:
Torej, kot sem zgoraj napisal, se po prvi prekinitvi, ki ima večjo prioriteto, izvede še druga prekinitvena rutina?

Ja, če je ustrezna prekinitvena zastavica/bit še aktivna.
Prekinitev se bo izvedla samo 1x. uC si zapomni samo, da je bila prekinitvena zastavica postavljena, ne pa kolikokrat je bila postavljena.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Samo87
Član
Član



Pridružen-a: Pet 25 Jan 2008 2:14
Prispevkov: 462
Aktiv.: 2.35
Kraj: Kamnik

PrispevekObjavljeno: Ned Mar 14, 2010 11:21 pm    Naslov sporočila:   Odgovori s citatom

Hvala int47, sedaj razumem situacijo Smile

Še nekaj mi je padlo na pamet. V tej aplikaciji trenutno 16 bitni timer1 uporabljam le za indikacijo dolžine pritiska na tipko, ker se mi je to zdelo z njim najenostavejše izvest. Če bi timer1 prevzel vlogo za "sekunde++", bi enostavno naredil eno prekinitev na sekundo, brez kakega overflow števca, ker je na razpolago 16 bitov.
Koda:
ISR(TIMER1_OVF_vect)  //kristal 10.240 MHz, preescaler 1024
{
TCNT1 = 65536 - 10000;
sec++;
}

V tem primeru bi bilo "tako čez prst" 40x manjša napaka, saj se je moralo s timerjem2 pravočasno izvest 40 prekinitev, da je bila ena sekunda točna, tu pa se mora le ena sama prekinitev točno izvest. Pa če še med vsemi ostalimi prekinitvami ponovno omogočim prekinitve, mislim da bom rešil zadevo.

Ko bo čas, bom izvedel tako, kot sem napisal, pa potem poročam rezultat.
LP
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
Pojdi na stran Prejšnja  1, 2, 3 ... 13, 14, 15 ... 27, 28, 29  Naslednja
Stran 14 od 29

 
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: 49 dni


Powered by phpBB © 2001, 2005 phpBB Group