www.elektronik.si
Začetniški problem v C-ju pri AVR-ju

www.elektronik.si -> Osnove programiranja AVR-jev

Avtor: upornikKraj: Celje PrispevekObjavljeno: Tor Feb 05, 2008 2:06 pm    Naslov sporočila:  Začetniški problem v C-ju pri AVR-ju
----------------------------------------------------------------------------
Imam en začetniški problem. Hotel sem napisati en preprost testni programček v C-ju, pa mi prevajalnik vedno najde neko napako, ker nisem vključil nekatere knjižnice.
Torej, katere so tiste nujno potrebne knjižnice, ki jih moram na začetku vključiti za samo delovanje? Program sem napisal v AVR Studio 4 z vgrajenim WINAvr-jem.
Krmilnik je ATMega8515. Poskusil sem prevesti tudi nekaj Sample programčkov iz interneta, pa je tudi vedno neka napaka.
Aja, pa še to me zanima...kako vem v kateri vrstici je napaka pri omenjenem programskem okolju? Npr., poskusil sem klikniti na napako, ki se je izpisala in sem mislil, da se bo označila vrstica v kateri je omenjena napaka pa se ni.

Hvala za odgovor!

Avtor: Sokrat PrispevekObjavljeno: Tor Feb 05, 2008 2:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Nobena ni nujno potrebna, program lahko napises tudi brez njih.

Ce imas v svojem programu vkljucene funkcije, ki so deklarirane v dolocenem headerju (.h), pa je doticni header seveda potrebno vkljuciti (#include).

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Tor Feb 05, 2008 5:02 pm    Naslov sporočila:  Re: Začetniški problem v C-ju pri AVR-ju
----------------------------------------------------------------------------
upornik je napisal/a:

Aja, pa še to me zanima...kako vem v kateri vrstici je napaka pri omenjenem programskem okolju? Npr., poskusil sem klikniti na napako, ki se je izpisala in sem mislil, da se bo označila vrstica v kateri je omenjena napaka pa se ni.

Če dvakrat klikneš na obvestilo za napako bi ti prevajalnik moral pokazati vrstico z napako.

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Tor Feb 05, 2008 5:15 pm    Naslov sporočila:  
----------------------------------------------------------------------------
upornik,
navedi točen opis napake.
Tudi jaz sem imel v pri povezavi AVR Studia in WinAVR-ja težave, če sem imel podobne, ti bom lahko pomagal.
Meni je javljalo napako, da ne najde datoteke *.o.d. Problem sem rešil tako, da sem ročno ustvaril mapo, ne spominjam pa se natančno ali je bila to mapa default ali dep.

Lp, Silvo

Avtor: upornikKraj: Celje PrispevekObjavljeno: Tor Feb 05, 2008 8:24 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:
Build started 5.2.2008 at 19:17:07
make: Makefile: No such file or directory
make: *** No rule to make target `Makefile'.  Stop.
Build failed with 2 errors and 0 warnings...

Tole mi napiše, ko prevedem...

Avtor: trotKraj: glej fogl PrispevekObjavljeno: Tor Feb 05, 2008 9:29 pm    Naslov sporočila:  
----------------------------------------------------------------------------
klik

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Tor Feb 05, 2008 9:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
upornik,

očitno nimaš makefile datoteke.

AVR studio samodejno naredi makefile datoteko pri ustvarjanju novega projekta.

Postopek je opisan v help-u AVR studia pod AVR Studio, Project, AVR GCC Project, Introduction, Getting Started, Creating a new project.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Sre Feb 06, 2008 12:38 am    Naslov sporočila:  
----------------------------------------------------------------------------
Sem ustvaril projekt po tem postopku, vendar je bil problem drugje. Pot do projekta je vsebovala besedo, v kateri je bila črka ž in je očitno zelo občutljiv na šumnike. Hvala za pomoč, verjetno vas bom še kaj vprašal, če se bo zalomilo Smile

Avtor: upornikKraj: Celje PrispevekObjavljeno: Sre Feb 06, 2008 3:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sedaj sem naletel na en drug problem. Rad bi uporabljal funkcijo delay, pa ne vem kako jo vključiti v program. Na začetku programa sem vključil delay knjižnico z ukazom #include <delay.h>, pa me je prevajalnik opozoril, da ta datoteka ne obstaja.
Nato sem preiskal vse mape in podatke v njih, ki so se ustvarile ob instalaciji, pa nisem nikjer našel omenjene knjižnice. Zanima me, ali moram te knjižnice dobiti iz interneta ali kje drugje in jih namestiti v mapo trenutnega projekta, ali kako drugače?
Če je to tako, bi bil vesel za kakšen link do knjižnic.

Hvala za odgovor!

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Sre Feb 06, 2008 3:39 pm    Naslov sporočila:  
----------------------------------------------------------------------------
delay ssi lahko nardiš sam; primer:

void delay(char d)
{
char i;
for(i=0;i<d;i++)
}

lahko dodaš še kakšen nop, v programu pa samo kličeš delay(123).



A lahko priporočim codevision? Zraven so vse osnovne knjižnice, uporaben GUI, help, wizard,...
Zastonj do 2k, če pa rabiš met licenco za firmo pa ni tako draga. Za učenje se da "popravit" da dela vse... in pa prihrani veliko živcev.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Sre Feb 06, 2008 4:24 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mislim, da sem celo že imel instaliran CodeVision pred nekaj dnevi, bom poskusil spet. Kaj pa če bi iz CodeVision-a skopiro knjižnico v svoj project file bi delovalo?
Namreč, meni se AVRStudio4 okolje kar dopade...

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Sre Feb 06, 2008 5:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ravno pišem kratke primerčke kode s komentarji za na spletno stran - napisano je za AVR Studio + WinAVR. Tole je moj primer Blinky-ja - vidi se tudi kako je vključen delay.h. Upam da ti bo ratalo oživeti zadevo.
Koda:
/*****************************************************
Project : Blinky 01
Version :
Date    :
Author  :

Chip type           : ATmega8
Clock frequency     : 1,000000 MHz
Memory model        :
External SRAM size  :
Data Stack size     :

Comments:
Program ni nič posebnega - na portu c.5 nam
na vsake pol sekunde za enak čas vklopi/izklopi
ledico - program je namenjen "oživljanju"
mikrokontrolerja oz. povezave

*****************************************************/

#define F_CPU 1000000


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


int main(void)
{
   // PC5 je izhod
   DDRC = 0x20;

   // glavna zanka
   while(1)
   {
      // z masko postavi PC5 na 1
      PORTC |= 0x20;

      // počakaj pol sekunde
      _delay_ms(500);

      // z masko postavi PC5 na 0
      PORTC &= ~0x20;

      // počakaj pol sekunde
      _delay_ms(500);
   }
}

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Feb 07, 2008 12:35 am    Naslov sporočila:  
----------------------------------------------------------------------------
Direktno sem skopiral tole kodo, le tisto vrstico kjer definiraš frekvenco sem izbrisal. Nato sem v Project Configuration nastavil tip ATMega8515 in frekvenco 4MHz. Program je začel delovati, vendar _delay_ms(500); traja cca. 3s.
Prevajalnik je vrnil eno opozorilo:
Koda:
c:/winavr-20071221/bin/../avr/include/util\delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"

Poleg tega se mi zdi pa čudno to, da je tale programček zasedel nekaj čez 40% pomnilnika.
Koda:
AVR Memory Usage
----------------
Device: atmega8515

Program:    3386 bytes (41.3% Full)
(.text + .data + .bootloader)

Data:          8 bytes (1.6% Full)
(.data + .bss + .noinit)


Build succeeded with 1 Warnings...

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Čet Feb 07, 2008 2:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Verjetno je vzrok obeh problemov, ki si ju opisal, da nimaš vključene optimizacije.

Pod Project Configuration nastavi Optimization - Os, (s=size).

Lp

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Feb 07, 2008 2:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Aha, sem vključil in je zdaj super. Omenjeni programček je zasedel le 138 Bajtov. Čas pa še vedno ni čisto realn. Sedaj traja 500ms okoli 2sekundi.
Je lahko razlog v tem, da je v knjižnici za delay definiran kristal 1MHz, sam pa uporabljam 4MHz? Takole izgleda:
Koda:

/** \file */
/** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops
    \code
    #define F_CPU 1000000UL  // 1 MHz
    //#define F_CPU 14.7456E6
    #include <util/delay.h>
    \endcode

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Čet Feb 07, 2008 3:34 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Seveda je potrebno za delay funkcijo povedati prevajalniku s kakšno frekvenco dela mikrokrmilnik, zato le popravi vrednost frekvence na 4M.

Sicer pa se je zakasnitev z uporabo delay funkcije dobro izogibati.

Lp

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Feb 07, 2008 3:58 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Kako pa se drugače naredi zakasnitev?

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Čet Feb 07, 2008 4:19 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Z uporabo timerja, samo pri takšnih preprostoh primerih se to skoraj ne splača. Delay funkcija je napisana tako, da sama preračuna zakasnitev glede na nastavljeno vrednost kristala - preberi si malo komentarje v delay.h pa boš laže našel napako.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Feb 07, 2008 9:27 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sem gledal v datasheetu, pa nisem našel...kako pri ATMega8515 izračunamo koliko časa se poraba npr. pri enem povečanju zanke za vrednost 1? Je to mogoče kar t=1/Fosc, ali kako drugače? Pa še to, a ima kdo mogoče napisano kakšno zakasnitev s timerjem?

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Pet Feb 08, 2008 1:55 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Domenius je napisal/a:
Z uporabo timerja, samo pri takšnih preprostoh primerih se to skoraj ne splača. Delay funkcija je napisana tako, da sama preračuna zakasnitev glede na nastavljeno vrednost kristala - preberi si malo komentarje v delay.h pa boš laže našel napako.


Strinjam se, da je v preprostih programih za zakasnitve najenostavneje uporabiti delay funkcijo. Če pa so zahteve programa, da lovi kakšne hitre spremembe na portih, je potrebno zakasnitve izvajati s pomočjo časovnikov.

Jaz to izvajam na takle način:

Koda:
#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned char delay;


/**********************      prekinitev timerja 0    **********************/

SIGNAL(SIG_OVERFLOW0)   // signal handler for tcnt0 overflow interrupt
 {
  TCNT0 = 61;      // 50 ms @ 4M
  ++delay;
 }


int main(void)
{
 DDRB = 0xff;
 
 TIMSK = 0x02;      // enable TCNT0 overflow
 TCNT0 = 61;      // 50 ms @ 4M
 TCCR0 = 0x05;      // count with cpu clock/1024
 
 sei();            // enable interrupts
 
 
  while (1)
   {
    if (delay==20)   // 1 sek   
    {
     delay=0;
     PORTB ^= 0xff;
    }

   }
 }


Lp

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Pet Feb 08, 2008 2:36 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Codevision ima v wizardu možnost nastaviti I2C in pa 2Wire(I2C). Preedvideva, da sta protokola enaka oz zelo podobna in pa da je prvi (I2C) softerski. Imam prav? Pri tem, da ima 2Wire tudi možnost generiranja prekinitev. Kdaj se te prekinitve prožijo? Ko je bit poslan, prejet, ko pride start sekvenca?
I2C ima za pošiljanje napisane funkcije.
Če hočem poslat byte (integer?)preko 2Wire, ga vpišem v register (kater?), ko pa byte prileti po busu se avtomatsko shrani v register(kter?) in se proži interrupt?

Avtor: upornikKraj: Celje PrispevekObjavljeno: Sre Feb 13, 2008 12:43 am    Naslov sporočila:  
----------------------------------------------------------------------------
Zdravo!

Mene pa zanima, zakaj mi WinAVR javi napako pri takšnem zapisu:
Koda:
PORTC.5=0;


Koda:
../7segmentni.c:12: error: expected ';' before numeric constant


Enako mi javi če uporabim naprimer PIND.x=y; Za probo sem omenjene zapise prevedel z CVAVR in so se prevedli brez problema...
Mogoče ve kdo, v čem je problem?

Hvala za odgovor!

Avtor: VolkDKraj: Divača (Kačiče) PrispevekObjavljeno: Sre Feb 13, 2008 1:15 am    Naslov sporočila:  
----------------------------------------------------------------------------
CodeVisionAVR govori drugačen dialekt jezika C. Obvlada bitne spremenljivke. WINAVR to ne zna. Sicer pa standarden C tega tudi nima.

CodeVisionAVR ima še cel kup drugih bombončkov, ki so dobri a z druge strani lahko slabi. Če se jih namreč naučiš uporabljati si na drugem prevajalniku hitro mrzel.

Avtor: trotKraj: glej fogl PrispevekObjavljeno: Sre Feb 13, 2008 9:06 am    Naslov sporočila:  
----------------------------------------------------------------------------
VolkD je napisal/a:
CodeVisionAVR govori drugačen dialekt jezika C. Obvlada bitne spremenljivke. WINAVR to ne zna.


V winavr gre to takole:
Koda:

struct {
uint8_t bit1: 1;
uint8_t bit2: 1;
} bitfield;

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Sre Feb 13, 2008 3:31 pm    Naslov sporočila:  
----------------------------------------------------------------------------
upornik je napisal/a:
Zdravo!

Mene pa zanima, zakaj mi WinAVR javi napako pri takšnem zapisu:
Koda:
PORTC.5=0;


Koda:
../7segmentni.c:12: error: expected ';' before numeric constant


Enako mi javi če uporabim naprimer PIND.x=y; Za probo sem omenjene zapise prevedel z CVAVR in so se prevedli brez problema...
Mogoče ve kdo, v čem je problem?

Hvala za odgovor!

Naredi tako kot je v mojem primeru na prejšnji strani - z maskami.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Sre Feb 13, 2008 4:30 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Domenious, mi lahko prosim malo bolj razložiš kaj se dogaja pri maski?

Koda:
// z masko postavi PC5 na 1
      PORTC |= 0x20;

 // z masko postavi PC5 na 0
      PORTC &= ~0x20;


Hvala za odgovor!

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Sre Feb 13, 2008 5:57 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Khm, Domenius, ne Domenious.
Če hočeš spremeniti stanje celega porta pošlješ nanj nek bajt oz. 8 bitov. Tukaj ni nič problemov z maskami. MSB bit spremeni PORTX.7, LSB bit poslanega bajta pa PORTX.0. Če pa hočeš spremeniti stanje samo enega pina brez da bi vplival na ostale moraš uporabit maske.
PORTC |= 0x20; v bistvu pomeni PORTC = PORTC | 0x20;, samo da je krajše napisano. Ta operacija postavi nek bit (0x20 je peti bit, ker je 0x20 enako 32 - 2 na 5 potenco je tudi 32, od tod torej peti bit) na 1. Tista črta pomeni logično operacijo OR. In ker je 0 OR X = X in 1 OR X = 1 se postavi bit samo tam kjer je enica, ostali pini pa ostanejo v takšnem stanju kot so.
Enako je pri PORTC &= ~0x20; - to pomeni PORTC = PORTC & ~0x20;. Ta operacija postavi pin na 0. Znak & pomeni logično AND operacijo, znak ~ pa negacijo. Namesto ~0x20 bi lahko napisal tudi 0xDF, je čisto enako, samo takšen način z negacijo se meni zdi bolj pregleden. Ker je 0 AND X = 0 in 1 AND X = X se pin postavi na nič samo tam kjer je ničla v poslanem bajtu, kjer so pa enice se pa stanje ohrani (X). Za boljše razumevanje tega napiši par programčkov z maskami in brez in jih testiraj v simulatorju AVR Studia pa boš videl razliko.
Napačno krmiljenje porta: če boš na port poslal 00000010 brez maske se bo drugi pin postavil na 1, ostali pa na 0 - če boš pa na npr. četrtem pinu spremljal stanje pina (vhodni pin) in bo pred pošiljanjem bajta na port stanje vhodnega pina 1 se bo pojavila napaka - ne programska ampak pri odčitavanju vrednosti.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Feb 14, 2008 3:29 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Se opravičujem za napačno napisano ime, sem dvakrat preveril, pa sem narobe napisal Confused
Aha, malo sem poskusil tele maske v programčkih, približno zastopim...
Kako pa npr. testiramo en vhodni pin, če je npr. nanj priključena tipka.
V Cvavr, ki podpira bitne spremenljivke testiraš tako:
Koda:
if(PIND.5==0)
{................}


Kako pa potem takšno testiranje zgleda v Winavr?

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Čet Feb 14, 2008 4:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Lahko tako da prebereš bajt s porta in ga z ustreznimi maskami obdelaš tako, da se gleda samo določen bit - ostali so vedno 0 ali 1, odvisno od mask. Lahko pa tudi na lažji način.
Koda:

if (bit_is_clear(PINB,1))
{
naredi nekaj;
}

Uporabiš lahko tudi bit_is_set(PINX, x), odvisno kako vežeš tipko.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Feb 14, 2008 5:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Predvidevam, da je ta "bit_is_clear(x,y)" neka že zapisana funkcija. Je zanjo v Winavr-ju potrebno vključiti katero dodatno knjižnico?

Avtor: tadej.ko2Kraj: sveta trojica PrispevekObjavljeno: Čet Feb 14, 2008 8:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
z maskami preverjaš podobno kot postavljaš:
ali je bit 5 postavljen?

if(PINB & 0x20)
{
neki();
};


drugače pa: 7 poglavje, 57 stran: http://fides.fe.uni-lj.si/~lrnv/racunalnistvo2/zapiskipredavanj.pdf

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Čet Feb 14, 2008 8:15 pm    Naslov sporočila:  
----------------------------------------------------------------------------
upornik je napisal/a:
Predvidevam, da je ta "bit_is_clear(x,y)" neka že zapisana funkcija. Je zanjo v Winavr-ju potrebno vključiti katero dodatno knjižnico?

Ne rabiš nobene knjižnice.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Tor Feb 26, 2008 11:29 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Lep pozdrav!

A mi lahko kdo da kakšen nasvet, kako bi na LCD zaslon izpisoval na najbolj enostaven način
vrednosti neke spremenljivke. Napisal sem si funkcijo lcd_izpis("besedilo"), ki pa izpisuje samo
ascii kode.

Koda:
 Primer:

int i;

for(i=0;i<100;i++)
{
_delay_ms(200);
izpis_vrednosti(i);
_delay_ms(200);
}


Torej, upam da ste me razumeli. Potrebujem nasvet, kako si napisati takole funkcijo.

Hvala za odgovore!

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Sre Feb 27, 2008 6:08 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Jaz spremenljivke izpisujem takole:

Koda:

void lcd_int (unsigned int val)
{
unsigned char s,d;   // stotice, desetice
unsigned int e;      // enice

  e=val/10;           // enice
  e=e*10;
  e=val-e;

  val=val/10;         // desetice
  d=val/10;
  d=d*10;
  d=val-d;

  val=val/10;         // stotice
  s=val/10;
  s=s*10;
  s=val-s;

  if(s==0) printch(' ');      // ce ni stotic jih ne izpise
  else printch(s+48);         // printch je funkcija za izpis ASCII znaka, ASCII 0 = 48
 
   printch(d+48);
   printch(e+48);
}



Lp

Avtor: upornikKraj: Celje PrispevekObjavljeno: Sre Feb 27, 2008 6:55 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Super funkcija, hvala Smile

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Sre Feb 27, 2008 8:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
a takole ne dela:

int var=14;
printf("i=%i",var);



ne vem, ponavadi dela, drugače pa uporabi sprintf...

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Sre Feb 27, 2008 9:35 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Jaz mam v knjižnici takšno funkcijo:

Koda:
static void inline strreverse(char* begin, char* end)
{
   char aux;
   while(end>begin)
      aux=*end, *end--=*begin, *begin++=aux;
}
   
void itoa(int value, char* str, int base)
{
   static char num[] = "0123456789abcdef";
   char* wstr=str;
   if (base<2 || base>16){ *wstr='\0'; return; }
   do *wstr++ = num[value%base]; while(value/=base);
   *wstr='\0';
   strreverse(str,wstr-1);
}


Uporabljaš itoa, strreverse je samo pomožna funkcija. Pretvori poljubno dolg integer, pazit moraš samo, da imaš dovolj prostora v char* str. base je številski sistem -- 2, 8, 10, 16 ...

LP!

Avtor: upornikKraj: Celje PrispevekObjavljeno: Pon Mar 03, 2008 12:48 am    Naslov sporočila:  
----------------------------------------------------------------------------
Spet imam en problem in sicer s Timerjem1. S pomočjo drugih rutin in primerov sem sestavil en programček, da bi z njim oživel timer1 v 16 bitnem načinu. Na zelo podoben način, le z ustreznimi spremembami mi deluje brez problemov Timer0 v 8 bitnem načinu in sem ga že uporabil v eni aplikaciji. Program s Timerjem1 pa se normalno prevede, le deluje ne, zato predvidevam da je nekaj narobe z nastavitvijo.
Uporabljam winavr prevajalnik in AVRmega8515.

Koda:
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>


volatile unsigned char delay;

/* signal handler for timer interrupt TOV1 */

ISR(TIMER1_OVF_vect)
{

TCNT1H=0x00;
TCNT1L=0x00;

delay++;

}

int main(void) {

/* use PortB for output (LED) */

DDRB=0xFF;
PORTB=0xFF;

// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off

TCCR1A=0x00;

// izberemo željeni delilnik   

//1:64
TCCR1B=0b00000011;

 
// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x04;

/*set timer counter initial value*/

TCNT1H=0x00;
TCNT1L=0x00;

ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
   

/* enable interrupts */

sei();


   while(1)
  {
     if(delay==2)
     {
       delay=0;                      //delay postavimo na nič
       PORTB ^= 0xFF;                //komplementiramo portb

     }
   }

}


Hvala za odgovor!

Avtor: PC_MasterKraj: Domžale , Blizu Ljubljane , Poštna 1230 PrispevekObjavljeno: Pet Apr 04, 2008 7:54 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ima kdo kakšno kodo , kjer ko pritisneš Tipko , ledica zasveti , in ko jo pritisneš še enkrat, ledica ugasne?

Hvala.

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Pet Apr 04, 2008 9:51 am    Naslov sporočila:  
----------------------------------------------------------------------------
Že prakrat napisano na forumu, malo pobrskaj.

Avtor: PC_MasterKraj: Domžale , Blizu Ljubljane , Poštna 1230 PrispevekObjavljeno: Pet Apr 04, 2008 2:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Na žalost ne najdem nič kar je čisti C pri AvrStudio GCC

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Pet Apr 04, 2008 2:22 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Vem da je nekje napisano kako to narediš v Bascomu - pretvorba v C nebi smela biti zahtevna, če se ti pa zdi da je, boš moral pa še malo potrenirati programiranje.

Avtor: PC_MasterKraj: Domžale , Blizu Ljubljane , Poštna 1230 PrispevekObjavljeno: Pet Apr 04, 2008 6:13 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Bascom je lahek , problem je kako določen pin definirati in potem kako sploh naredim takole :

Koda:

if PINB.2 = 1 do
   I = NOT I
end


PINB.2 je vhod , I je pa bitna spremenljivka , ki je pač vezana na en izhod.

Sicer ali NOT operacija sploh obstaja pri mikroprocesorjih? Sej alternativo imam že v glavi.

Avtor: jvolkKraj: okolica Divače PrispevekObjavljeno: Sob Apr 05, 2008 12:32 am    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:

if (PINB.2){
   I = !I;
}


To bi moralo delovati. Seveda moreš imet zgoraj definiran I kot ledico.

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Sob Apr 05, 2008 12:55 am    Naslov sporočila:  
----------------------------------------------------------------------------
PC_Master je napisal/a:
Sicer ali NOT operacija sploh obstaja pri mikroprocesorjih?

Nekatere stvari bi se zelo (in po nepotrebnem) zakomplicirale, če nebi mikrokontrolerji poznali operacije NOT - to je ena ključnih osnovnih bitnih operaciji.

Avtor: PC_MasterKraj: Domžale , Blizu Ljubljane , Poštna 1230 PrispevekObjavljeno: Sob Apr 05, 2008 8:40 am    Naslov sporočila:  
----------------------------------------------------------------------------
Aha , ker še res nikoli nisem videl nobene kode z operacijo NOT.

Avtor: Sokrat PrispevekObjavljeno: Sob Apr 05, 2008 9:35 am    Naslov sporočila:  
----------------------------------------------------------------------------
To je zato, ker se nikoli nisi videl nobene kode. Brez skrbi, tudi to bo enkrat na vrsti, ce prej ne obupas.

Avtor: PC_MasterKraj: Domžale , Blizu Ljubljane , Poštna 1230 PrispevekObjavljeno: Sob Apr 05, 2008 9:39 am    Naslov sporočila:  
----------------------------------------------------------------------------
Sem sem. Ne bom obupal ... mogoče preden HTE dostavi mojo pošiljko Rolling Eyes

Avtor: Sokrat PrispevekObjavljeno: Ned Apr 06, 2008 3:08 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ne bi rekel, sicer ne bi klatil takih neumnosti ("Aha , ker še res nikoli nisem videl nobene kode z operacijo NOT").

Nekatere arhitekture sploh nimajo direktnih ukazov za operiranje nad biti, ampak uporabljajo logicne operacije z masko, od katerih je negacija kljucna operacija (za brisanje bita).

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Ned Apr 06, 2008 11:19 am    Naslov sporočila:  
----------------------------------------------------------------------------
Negacija ni nujno potrebna za funkcijsko polnost sistema (lahko recimo uporabiš xor), je pa res najbolj uporabljana ...

LP!

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Ned Apr 06, 2008 11:22 am    Naslov sporočila:  
----------------------------------------------------------------------------
XOR funkcija pa pride iz enačbe: x'y|xy', kjer se spet uporablja negacija.

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Ned Apr 06, 2008 5:40 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Domenius je napisal/a:
XOR funkcija pa pride iz enačbe: x'y|xy', kjer se spet uporablja negacija.


Ja in? Lahko rečeš tudi obratno: namesto negacije je recimo x XOR 1.

Gre se za to, da za en procesor ni nujno, da ima možnost negacije, pa se da vseeno zračunati kakršnokoli že operacijo nad biti. Celo več opcij je, kako to narediti v hardveru ...

LP!

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Ned Apr 06, 2008 7:51 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hočem ti samo povedati, da je xor funkcija sestavljena iz and, or in not (zato se jim pa reče elementarne funkcije), gledano iz matematičnega vidika - kako je hadrwersko narejeno ne vem. Od tu relacija xor <-> not.

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Ned Apr 06, 2008 8:19 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Domenius je napisal/a:
Hočem ti samo povedati, da je xor funkcija sestavljena iz and, or in not (zato se jim pa reče elementarne funkcije), gledano iz matematičnega vidika - kako je hadrwersko narejeno ne vem. Od tu relacija xor <-> not.


Kar jaz govorim, je pa tole:

(and, not) je samo ena izmed izbir elementarnih funkcij oz. bolj pravilno eden izmed funkcijsko polnih sistemov. V logiki imaš namreč več čisto ekvivalentnih takih sistemov - tako kot lahko s kombinacijo AND in NOT izraziš katerokoli preklopno funkcijo, lahko isto narediš s kombinacijo XOR, AND in 1. Ali pa recimo samo z NOR operatorjem.

AND, OR, NOT so samo najbolj pogosti operatorji, vendar čisto matematično gledano nimajo nobene prednosti pred XOR. Teoretično imaš za dve spremenljivki na voljo 2^4 različnih funkcij, ki si jih lahko poljubno izbereš (no, tako da dobiš poln sistem). Praktično gledano to pomeni, da lahko za realizacijo preklopne funkcije uporabiš takorekoč karkoli imaš pri roki, tudi če nimaš nujno AND, NOT ali OR vrat.

Sicer je pa tole že čisto mimo teme ...

LP!

Avtor: sebavehKraj: Slovenska Bistrica PrispevekObjavljeno: Tor Maj 13, 2008 12:18 am    Naslov sporočila:  
----------------------------------------------------------------------------
Si bom kar tole temo izposodil.

Delam z ATmega16 in programiram v CodeVision (verzija 1.25.9)

Zanima pa me okoli vpisovanja in branja v notranji Eeprom. V Helpu je sicer razloženo kako se vpisuje in bere (s kazalci) ampak tam je prikazano samo za en podatek, oziroma za eno spremenljivko naenkrat.

V Main funkciji sem najprej definiral stavek:

Koda:
unsigned int eeprom *ptr_to_eeprom;    //kazalec na nek naslov 


Jaz bi pa rad vpisoval več spremenljivk, najraje eno za drugo. Do sedaj sem to naredil na dva načina:

Koda:

//////// koda za vpis:

ptr_to_eeprom = 0x00;                  //začni s tem naslovom
      *ptr_to_eeprom = minute;        //vrednost minut vpiši v vsebino kazalca
      ptr_to_eeprom++;                   //povečaj kazalec na naslednji naslov v eepromu
      *ptr_to_eeprom = desetice;       
      ptr_to_eeprom++;       
      *ptr_to_eeprom = sekunde;     
      ptr_to_eeprom++;     
      *ptr_to_eeprom = desetinke;

////// koda za branje:

ptr_to_eeprom = 0x00;                          //začni s tem naslovom
        minute = *ptr_to_eeprom;              //vsebino kazalva vpiši v spremenljivko minute
        ptr_to_eeprom++;                          //povečaj kazalec na naslednji naslov
        desetice = *ptr_to_eeprom;
        ptr_to_eeprom++;
        sekunde = *ptr_to_eeprom;
        ptr_to_eeprom++;         
        desetinke = *ptr_to_eeprom;

Tak način mi spremeni 8 mest v Eeprom pomnilniku, od x0 do xF Confused Nevem zakaj, če pa pričakujem da se bodo spreminjale le od x0 do x3 Question

Drugi način pa je takšen:
Koda:
 //////////// koda za vpis:

ptr_to_eeprom = (eeprom unsigned int*) 0x00;        //definiraj kazalec na prvi naslov
      *ptr_to_eeprom = minute;                            //vpiši podatek
      ptr_to_eeprom = (eeprom unsigned int*) 0x01;     //definiraj kazalec na drugi naslov
      *ptr_to_eeprom = desetice;     
      ptr_to_eeprom = (eeprom unsigned int*) 0x02;     
      *ptr_to_eeprom = sekunde;   
      ptr_to_eeprom = (eeprom unsigned int*) 0x03;   
      *ptr_to_eeprom = desetinke;   

/////// koda za branje:

ptr_to_eeprom = (eeprom unsigned int*) 0x00;               //definiraj kazalec na prvi naslov
        minute = *ptr_to_eeprom;                                 //preveri podatek
        ptr_to_eeprom = (eeprom unsigned int*) 0x01;       //definiraj kazalec na drugi naslov
        desetice = *ptr_to_eeprom;   
        ptr_to_eeprom = (eeprom unsigned int*) 0x02;   
        sekunde = *ptr_to_eeprom;     
        ptr_to_eeprom = (eeprom unsigned int*) 0x03;     
        desetinke = *ptr_to_eeprom;     

Tale drugi način pa mi spremeni le 5 mest v Eepromu, od x0 do x4. Kar se mi zdi malo boljše kot v prvem načinu, a še vedno en bit več kot sem pričakoval Confused Tudi tu se na zadnje mesto (x4) vpiše vrednost 0x00

Najbolj kar me zanima pri vsem tem je, kateri način je sploh primernejši za delo z eepromom? Če sploh kateri? Iskal sem že po različnih straneh, od avrfreakov do yahoo, pa nič konkretnega. Tole kar je zgoraj pa sem malo spocal skupaj, malo od tu in malo od tam. Sicer deluje, ampak se mi zdi nekam "na horuk" vse skupaj.

Na kak način ste vi ostali člani vpisovali podatke v eeprom, če je šlo za več spremenljivk naenkrat?

Avtor: spyKraj: Tržič PrispevekObjavljeno: Tor Maj 13, 2008 1:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Zakaj?

Zato ker uporabljaš integer tip spremenljivke in ti vpisuje dva byte-a v eeprom.
Za vpis enega samega byte-a v eeprom uporabi CHAR.

Takole v GCC jaz uporabljam in vpiše samo en byte na eno lokacijo:

spremenljivka = eeprom_read_byte ((unsigned char*)eeprom_naslov);

Drugi tvoj način ti verjetno povozi zgornji neuporabni byte, kar pa ni dobro.

Poskusi...

Avtor: sebavehKraj: Slovenska Bistrica PrispevekObjavljeno: Tor Maj 13, 2008 5:38 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Evo, sedaj sem v Main funkciji spremenil tip podatkov iz INT na CHAR:

Koda:
unsigned char eeprom *ptr_to_eeprom;


In pri vpisu teh štirih spremenljivk mi zasede 4 mesta v eeprom pomnilniku, kot je pričakovano. Hvala za pomoč!

Se mi pa dogaja še ena neprijetnost:

-Če želim nasloviti neko celico, nek naslov v eepromu, gre brez problema, če povečujem vrednost kazalca:
Koda:

ptr_to_eeprom = 0x00;     
      *ptr_to_eeprom = minute;     
      ptr_to_eeprom++;     
      *ptr_to_eeprom = desetice;       
      ptr_to_eeprom++;       
      *ptr_to_eeprom = sekunde;     
      ptr_to_eeprom++;     
      *ptr_to_eeprom = desetinke;


Žal pa ne gre neposredno izbrati naslova, naprimer:
Koda:

ptr_to_eeprom = 0x00;     
      *ptr_to_eeprom = minute;     
      ptr_to_eeprom = 0x01;                //tu mi javi napako
      *ptr_to_eeprom = desetice;       
      ptr_to_eeprom = 0x02;                //tu javi napako
      *ptr_to_eeprom = sekunde;     
      ptr_to_eeprom = 0x03;                 //in tu tudi
      *ptr_to_eeprom = desetinke;


V tem drugem primeru mi izpiše Error: a value od type 'int' can't be assigned to an entity of type 'eeprom unsigned char *' Čeprav bi po vsej logiki morala biti oba načina enaka?

Poskusil sem že z vsemi kombinacijami Int, Char... pa brez uspeha. Nevem zakaj sprejme le 0x00, ostalih 0x0n pa ne Question To se mi dogaja tako pri delu za branje, kot tudi za vpis v eeprom.

Avtor: spyKraj: Tržič PrispevekObjavljeno: Sre Maj 14, 2008 10:42 am    Naslov sporočila:  
----------------------------------------------------------------------------
Nekaj pogrešam. Klic funkcije za branje iz eeprom-a (ali vpis v njega). V tej kodi, ki si jo dal, samo prestavljaš vrednosti sem ter tja po ramu. Ni sledu, da bi se kaj zapisovalo v eeprom.

Hm...razen, če ni to spet fora CodeVision-a. Tega jaz ne uporabljam.

Glede na error pa poglej, kako imaš to definirano v knjižnici.

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Sre Maj 14, 2008 1:53 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Zakaj pa ne anrediš enostavno spremenljivke v eepromu? zakaj vse te kolobocije s pointerji? Pazi samo da ne boš uničil eeproma s prevelikim številom vpisov - torej uporabljaš normalne spremenljivke iz rama, ko pa treba pa pač te shraniš v eeprom:

Koda:

 
eeprom char eeure, eesek;         //narediš spremenjlivko v eepromu
char ure, sek;                            // spremenljivka v ramu

ure=34;                                    //prirediš vrednost v ram

eeure=ure;                                //prirediš vrednost v eeprom

eesek=33;                                 //direktno v eeprom

....







codevision ne rabi nobene funkcije za vpsi v eeprom, samo pred najavo spremenljivke daš besedico eeprom. Isto za flash.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Maj 23, 2008 11:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdrav!

Ravno se trudim s programiranjem mojega prvega uC in sicer sem uporabil ATTiny2313

Tu nekje na forumu sem našel in v Codevision skopiral to kodo (tistega, kar Codevisionov čarovnik avtomatsko doda na začetek, nisem skopiral):

Koda:
while(1)
   {
      // z masko postavi PA1 na 1
      PORTA |= 0x02;

      // počakaj pol sekunde
      delay_ms(1000);

      // z masko postavi PA1 na 0
      PORTA &= ~0x02;

      // počakaj pol sekunde
      delay_ms(500);
   }


Seveda sem jo malce preuredil, tako da je izhod na željenem pinu porta A (1)

In sedaj LEDica veselo utripa Very Happy

Sedaj me pa kot prvo zanima, kako dobim na tipkovnici tisto navpično črtico za ukazom PORTA (za katero domnevam, da vpiše 1 na željeno mesto - kot tudi domnevam, da & napiše 0)?

Kaj pomeni tisti znakec ~ ?

Kot drugo, bi pa rad vedel, kako naj naredim, da se bo tale programček izvajal samo takrat, ko držim pritisnjeno tipko- logično 1, npr na PORTD, pin PD4? Se pravi s katerim ukazom "potipam" željeni vhod in potem dovolim izvajanje programčka?

Na žalost, čisto začetniška vprašanja, Ampak o Cju in tudi o mikrojih nimam pojma, sem že bolj stare šole in v učnem programu teh zadev nisem videl niti od daleč.
Je res, da sem že gledal Help od Codevisiona, ampak rezultati tega so bolj kilavi.

Če bo sreča, pa bom imel v prihodnosti še marsikaj vprašati.

Branko

Avtor: mirkatmirKraj: Ribnica (JN75IR) PrispevekObjavljeno: Pet Maj 23, 2008 12:31 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:

Sedaj me pa kot prvo zanima, kako dobim na tipkovnici tisto navpično črtico za ukazom PORTA (za katero domnevam, da vpiše 1 na željeno mesto - kot tudi domnevam, da & napiše 0)?
Branko


ALT Gr + W

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Pet Maj 23, 2008 12:33 pm    Naslov sporočila:  
----------------------------------------------------------------------------
S tisto kodo ki jo čarovnik da nqa začetek ni nič narobe, zato jo komot uporabljaš. Svoj program pač pišeš naprej dol na koncu, v main, while(1).


Črto | dobiš z altgr+w. Pomeni pa OR nad biti spremenljivke. dve črti || bi pomenile logični OR nad dvema pogojema, v if stavku naprimer.
Z if stavkom lahko "potipaš vhod".

Koda:

              if( pogoj || nekdrug pogoj   && nek drug pogoj )
                  {
                       //če je rezultat vseh pogojev ^^ 1 se bo izvedla koda med {}
                   }

              else
                  {
                    //če je retultat pogojev 0, se izvede blok else
                   }




~ pomeni bitno negacijo, obrne vse bite v variabli.

Avtor: sebavehKraj: Slovenska Bistrica PrispevekObjavljeno: Pet Maj 23, 2008 3:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
Sedaj me pa kot prvo zanima, kako dobim na tipkovnici tisto navpično črtico za ukazom PORTA (za katero domnevam, da vpiše 1 na željeno mesto - kot tudi domnevam, da & napiše 0)?


Stisni tipki "AltGr" in "w"

Citiram:
Kaj pomeni tisti znakec ~ ?


Negacija, logični NOT. Vse enke spremeni v ničle in vse ničle spremeni v enke.

Citiram:
Kot drugo, bi pa rad vedel, kako naj naredim, da se bo tale programček izvajal samo takrat, ko držim pritisnjeno tipko- logično 1, npr na PORTD, pin PD4? Se pravi s katerim ukazom "potipam" željeni vhod in potem dovolim izvajanje programčka?


Misliš raje logično 0 ? Tipke so ponavadi vezane na maso, tako da ko jih stisneš, potegnejo pin na maso.

Lahko uporabiš naprimer IF stavek, v katerega bo program vstopil dokler bo tipka pritisnjena:

Koda:
while(1)
   {
     if (PIND.4 == 0)
         {
           // ta del programa med zavitima oklepajema so bo izvajal, če bo izpolnjen pogoj zgoraj
           // z masko postavi PA1 na 1
           PORTA |= 0x02;

           // počakaj pol sekunde
            delay_ms(1000);

             // z masko postavi PA1 na 0
             PORTA &= ~0x02;

            // počakaj pol sekunde
            delay_ms(500);
            }
   }



Citiram:
Je res, da sem že gledal Help od Codevisiona, ampak rezultati tega so bolj kilavi.


Vem, sem imel enak problem. CV pač predpostavi da uporabnik že pozna programski jezik C. V Helpu pa so dodani le ukazi in stvari, specifični za mikrokontrolerje.

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Pet Maj 23, 2008 4:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
@sebaveh: A sem jaz napisal tok nerazumljivo, da treba ponavljat moj post?




nekaj stvari o c-ju je tukaj. Na FEju se učimo šarm, ampak c je isti. Funkcije v codevisionu imajo drugačna imena, zato beri samo snov okoli jezika. Tutorialov za c je poln gugl.

Avtor: sebavehKraj: Slovenska Bistrica PrispevekObjavljeno: Pet Maj 23, 2008 9:23 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ne, vsekakor nisem pisal zato ker bi bilo nerazumljivo. Ampak zato, ker smo očitno vsi pisli ob istem času. Jaz sem začel pisati, ko še ni dobil nobenega odgovora. Wink

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sob Maj 24, 2008 12:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala za odgovore, pa prosim brez prepirov Smile Pomagal mi je vsak po svoje in če je ena in ista stvar napisana na 5 načinov, jo je mogoče lažje zastopiti.

Je pa res, da C-ja ne poznam in glede na večje število verzij se tudi sintaksa razlikuje. Problem je v tem, da še nikjer nisem zasledil nekega seznama ukazov in kratkega opisa s točno sintakso, kaj ta ukaz dela (se še kdo spomni priročnika od Commodoreja). Vseeno pa nisem toliko trapast, da stvari nebi zastopil. Če sem se sam naučil in potem tudi dobro znal uporabljati Comodorjev in Spectrumov Basic, asembler za 6510 in 8502, dokaj dobro tudi Pascal, mislim, da mi bo podobno uspelo tudi pri C-ju.

Največji problem je nepoznavanje sintakse, ki jo uporablja Codevision. Vse ostalo se že doseže s poizkušanjem, če vidiš kak primer. Res pa je, da je včasih lažje koga vprašat. Včasih te možnosti nisem imel.

PS tisti alt+W: Na moji tastaturi je bila narisana črta prekinjeno Rolling Eyes

PPS najbolj je v IF stavku pomagal sebaveh (saj pravim, sintaksa). je pa vseeno res, da bom to lahko preizkusil šele v ponedeljek. Tisto povezavo o Cju- dragoon- bom pa takoj pregledal.


Branko

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Sob Maj 24, 2008 3:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:

Je pa res, da C-ja ne poznam in glede na večje število verzij se tudi sintaksa razlikuje. Problem je v tem, da še nikjer nisem zasledil nekega seznama ukazov in kratkega opisa s točno sintakso, kaj ta ukaz dela (se še kdo spomni priročnika od Commodoreja). ........

Največji problem je nepoznavanje sintakse, ki jo uporablja Codevision. Vse ostalo se že doseže s poizkušanjem, če vidiš kak primer. Res pa je, da je včasih lažje koga vprašat. Včasih te možnosti nisem imel.

PS tisti alt+W: Na moji tastaturi je bila narisana črta prekinjeno Rolling Eyes




Vse verzije C so bolj kot ne iste. Codevision verjetno uporablja ANSI C, torej je kompitabilen z vsakim tutorialom. Če že znaš toliko programskih jezikov, potem verjetno ni problem razumevanje ukazov (if, while, for....), obliko ukazov pa najlažje najdeš z guglom: npr niz " C if statement syntax" .
C ki ga uporablja CV, je drugačen samo pri stvareh, ki so specifične za AVRje, torej imena registrov (PORTA, PINA, PINA.5,...), kar pa najlažje vidiš, če na začetku uporabljaš code wizard.
Prej sem malo brskal, na WIKIPEDIi je zbran opis ukazov. išči pod "WIKI C".

Res pa je najlažje začet z gledanjem primerov, po možnosti dobro komentiranim, zato kar sprašuj Wink

tista črta je na vseh tipkovnicah narisana tako, ne vem s kakšnim namenom Smile

PS: ne gre za kreganje, samo zanima me če pišem tako da me noben ne razume Confused , pa pisala sva 3 ure narazen.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Maj 27, 2008 11:54 am    Naslov sporočila:  
----------------------------------------------------------------------------
Uporabljam Attiny2313. Napisal (prepisal) sem tole kodo:
Koda:
while (1)
      {
      // Place your code here
      unsigned char test;
      test = PIND.0;
 #if (test == 1);
 {
 lcd_clear();
 lcd_putsf("prva vrsta");
 delay_ms(1000);
 }
 #else;
 {
 lcd_gotoxy(2,1);
 lcd_putsf("druga vrsta");
 delay_ms(1000);
  }   
 #endif
};


Kot se vidi, bi rad, da mi takrat ko imam pritisnjeno tipko na portd.0, dela polovica kode, ko tipke ni pritisnjene, dela druga polovica kode.

Pri prevajanju mi Codevision zacvili o napačni vrsti spremenljivke v vrstici IF (undefined symbol test) in pravi, da vrednost predpostavlja kot 0. Se pravi, vedno izvaja drugo polovico kode, ne glede na tipko.

Če napišem if stavek brez #, pa mi v vsakem primeru izvede obe polovici kode. Pa takrat sta napačna ukaza else in endif. Ju noče prepoznati.

Kako pravilno definiram spremenljivko in napišem ukaz IF?

Pa še to: Kako lahko vrednost spremenljivke "test" izpišem na ekran? Po možnosti obe varianti- samo en pin ali pa celoten port. v kateremkoli zapisu (dec, hex, bin)- samo da vidim, kaj uC vidi na vhodu. Po internetu sem našel, da se uporablja sprintf, ki pa ga CV ne spozna?


LP Branko

Avtor: sebavehKraj: Slovenska Bistrica PrispevekObjavljeno: Tor Maj 27, 2008 1:09 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
Uporabljam Attiny2313. Napisal (prepisal) sem tole kodo:
while (1)
{
// Place your code here
unsigned char test;
test = PIND.0;
#if (test == 1);
{
lcd_clear();
lcd_putsf("prva vrsta");
delay_ms(1000);
}
#else;
{
lcd_gotoxy(2,1);
lcd_putsf("druga vrsta");
delay_ms(1000);
}
#endif
};




Spremenljivko test daj ven iz while zanke. Dovolj bo, če jo postaviš na začetek main funkcije, kjer imaš definirane lokalne spremenljivke.

Na koncu if in else stavkov izbriši podpičja. CodeVision ne potrebuje ukaza endif, vsaj kolikor sem jaz delal s preprostimi if stavki. Po potrebi izbriši še #.

CodeVision ima eno uporabno stvar, to so vzorci kode "code templates". Najdeš jih na levi strani zaslona, kjer je drugače drevesni pogled datotek, ki jih imaš v trenutnem projektu. Tam vidiš zavihke "navigator", "code templates", "clipboard". Izberi vzorce kode in jih potegni v programsko okno.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Maj 27, 2008 1:40 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala za nasvete, bom poskusil.

Sem pa medtem ugotovil, zakaj ne dela sprintf ukaz. Vključiti je potrebno knjižnico stdio.h. Ta pa zavzame 1. preveč pomnilnika v attiniyu, 2. nastane predolga koda za Codevision evaluation verzija (več kot 2k). samega programčka pa je cca 8 vrstic Shocked
Bom očitno moral prebasati na Winavr, ker se mi za moje hece ne splača dati 150$ za taresno verzijo.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Maj 28, 2008 11:54 am    Naslov sporočila:  
----------------------------------------------------------------------------
@sebaveh:

IF stavek sem preizkusil in mi sedaj deluje. Prav tako sem se malce igral z logičnimi operacijami na vhodnih in izhodnih pinih. In mi tudi kar nekako uspeva. Hvala lepa

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Sre Maj 28, 2008 12:23 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Od kje ti ideja da winavr dela manjšo kodo? Za sprintf poglej malo po nastavitvah, nekje se da nastavit s kako natančnostjo naj dela. Ti rabiš samo 8 bitov, brez floatoing pointa,... S sprintf njaprej shraniš string nekam v ram, potem pa ta string zapišeš z lcd_puts(); in ne z lcd_putsf();
nekako takole:

Koda:

char buffer[64];


sprintf(buffer, "PORTA=%c", PORTA);      // Rezultat vrne v buffer, na lcd izpiše porta= 'desetiška vrednost na portu',  zadnji PORTA je variabla, ki jo vzame %c.


lcd_puts(buffer);     //izpiše buffer kar je v bufferju

 



Ukazi, ki se začnjeo z # so direktive kompajlerju, in ne procesorju. Stavki (if, while,...) izvedejo, če so pogoji, naslednji blok ukazov v programu. Blok ukazov je zaprt med {} . če imaš samo en ukaz teh {} ne rabiš. ne rabiš pisat endif (pravtako direktiva kompajlerju), ker se if avtomatsko konča, ko je izveden blok ukazov.

tole si videl?

Avtor: strobosKraj: Brežice PrispevekObjavljeno: Sre Maj 28, 2008 1:36 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Da ne bom odpiral nove teme: je kdo že mogoče testiral za koliko % manjšo kodo naredi Codevision proti Bascom AVR za isti program?

Lp

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Maj 29, 2008 6:45 am    Naslov sporočila:  
----------------------------------------------------------------------------
@dragoon: Saj sem IF stavek na koncu naredil brez #. sem pa preizkušal seveda oba načina.
Tudi domnevam, da winavr ne naredi krajše kode kot Codevision.
Problem je namreč v tem, da imam evaluation verzijo Codevisiona, ta pa dovoli izdelavo samo 2kB kode. To pa presežem že s tem, da vključim knjižnico stdio.h, ki jo potrebuje sprintf. Brez da bi dodal še kaj svoje kode.
Tako da tega že itak ne morem stlačiti v tinyja, ki tudi premore 2kB flasha.

Tako da se sedaj privajam na avrstudio in winavr. In seveda preklinjam, ker spet nič več ne znam.

aja, pa manual imam Smile seveda za CV, ki mi nič ne koristi.

Avtor: gumby PrispevekObjavljeno: Čet Maj 29, 2008 7:26 am    Naslov sporočila:  
----------------------------------------------------------------------------
#if - #else - #endif se obdela samo enkrat, in to pri prevajanju programa!

Ne mešat tega z navadnim "if"

Avtor: VolkDKraj: Divača (Kačiče) PrispevekObjavljeno: Čet Maj 29, 2008 9:44 am    Naslov sporočila:  
----------------------------------------------------------------------------
strobos je napisal/a:
Da ne bom odpiral nove teme: je kdo že mogoče testiral za koliko % manjšo kodo naredi Codevision proti Bascom AVR za isti program?

Zelo odvisno od tega kakšen program prevajaš.
Večinoma se da z boljšim algoritmom mnogo efikasnije zmanjšat kodo, kot pa z menjavo prevajalnika.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Maj 30, 2008 11:29 am    Naslov sporočila:  
----------------------------------------------------------------------------
Zopet sem se zaplezal. Ugotovil sem, da winavr nima knjižnice za LCD. Confused

Zato sem po internetu poiskal tole: http://winavr.scienceprog.com/download/AVR-LCD4b.zip.
In seveda mi nič ne gre skupaj. Kot prvo, mislim da bi tejle knjižnici oziroma kompilerju nekako moral povedati, kje sploh je priključen LCD in kakšen je. Če ima kdo čas in voljo, ali lahko pogleda malce knjižnico v linku in pove, kako in kaj. Sam na tejle strani nisem zasledil nobenih konkretnih navodil.

Oziroma še bolje, če ima kdo uporabno knjižnico za LCD, namenjeno za winavr.
Po možnosti z nekim seznamom ukazov
Rolling Eyes

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Pet Maj 30, 2008 2:03 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sem probal v CV tol0e kodo. Skompajla se v 634 besed.
Koda:

char buffer[16], test;

 test=33;
 sprintf(buffer,"var test=%c",PORTB);
 lcd_puts(buffer);



V tisti knjižnjic za winavr pa spremeni številke pinov v LCD.h.
tukaj:
Koda:

#define LCD_RS   0    //define MCU pin connected to LCD RS
#define LCD_RW   1    //define MCU pin connected to LCD R/W
#define LCD_E   2   //define MCU pin connected to LCD E
#define LCD_D4   4   //define MCU pin connected to LCD D3
#define LCD_D5   5   //define MCU pin connected to LCD D4
#define LCD_D6   6   //define MCU pin connected to LCD D5
#define LCD_D7   7   //define MCU pin connected to LCD D6
#define LDP PORTD   //define MCU port connected to LCD data pins
#define LCP PORTD   //define MCU port connected to LCD control pins
#define LDDR DDRD   //define MCU direction register for port connected to LCD data pins
#define LCDR DDRD   //define MCU direction register for port connected to LCD control pins




najave funkcij imaš pod tem tekstom, so lepo pokomentirane.

primer pisanja stringa na lcd:
Koda:

//Copies string from flash memory to LCD at x y position
const uint8_t welcomeln1[] PROGMEM="AVR LCD DEMO\0";
CopyStringtoLCD(welcomeln1, 3, 1);   


Ampak če hočeš pisat vrednost variable na lcd, moraš spet uporabit sprintf. Oz katerokoli funkcijo ki naredi ascii kode iz vrednosti.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sob Maj 31, 2008 12:11 pm    Naslov sporočila:  
----------------------------------------------------------------------------
@dragoon: hvala, bom v ponedeljek spet malce potelovadil. Sicer sem že nekaj poizkušal s spreminjanjem tistega portd > portb, ampak se mi ni skompiliralo ok, oziroma mi je javljal napake. A tebi je delovalo?

Pa še nekaj, kaj pomeni zraven tisti file lcd.c?

PPS: kaj pa naredi tista koda, ki si jo dodal?

Pa še to ugotavljam, da se bom moral začeti igrati z mego, ker so skoraj vse zadeve, ki se tičejo LCDja prevelike za tinyja

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Ned Jun 01, 2008 8:27 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Jaz uporabljam CV, tega nisem probaval, vendar mora načeloma delovat, če spremeniš porte in številke bitov pri define-ih. Kake napake pa ti je javljalo?

.h - header file, tam nastaviš define, najave funkcij, načeloma stvari, ki jih uporabnik knjižnice spreminja.

.c - sama "knjižnica", tam so vse funkcije knjižnice, tam zaenkrat ničesar ne spreminjaj. Na začetku je vključen (include) .h file.

ti moraš v svoj projakt vključit lcdlib.c file. Namen headerja je red. da imaš ločene zadeve. Načeloma bi bilo lahko vse v eni datoteki.


tista koda izpiše vrednost spremenljivke na zaslon

Koda:
char buffer[16], test;              //narediš varialbe, buffer - polje dolgo 16bajtov, test dolg en bajt

 test=33;                                        // prirdiš vrednost
 sprintf(buffer,"var test=%c",test);   //v buffer zapiše tole:  var test=33
 lcd_puts(buffer);                            //izpišeš buffer


zgoraj je v spintf PORTB, kar samo zapiše vrednost ki je na portb, po čemer si prej spraševal.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Jun 02, 2008 8:33 am    Naslov sporočila:  
----------------------------------------------------------------------------
Sedajle sem ponovno poizkusil z uporabo LCDja.

Prevajalnik WINAVR mi javlja sledečo napako:

Koda:
c:/program files/atmel/winavr/lib/gcc/../../avr/include/util\lcd_lib.c: In function 'LCDcursorLeft':
c:/program files/atmel/winavr/lib/gcc/../../avr/include/util\lcd_lib.c:194: error: 'for' loop initial declaration used outside C99 mode



Če pogledam, kam to kaže- kaže v naslednjo for zanko, očitno je tu nekaj narobe:

Koda:
void LCDcursorLeft(uint8_t n)   //Moves cursor by n poisitions left
{
   for (uint8_t i=0;i<n;i++)
   {
      LCDsendCommand(0x10);
   }
}


Mi pa javlja 4 popolnoma enake napake in sicer v funkcijah LCDshiftLeft, LCDshiftRight, LCDcursorLeft, LCDcursorRight.

Kaj bi moral spremeniti, da bi kompiliranje steklo naprej?




EDIT: Tole sem po taktiki MUP (mnoštvo uzaludnih pokušaja) in s pomočjo interneta razrešil. V nastavitvah projekta je bilo potrebno dodati eno stikalo -std=gnu99. Šlo pa se je za napako glede vrst C jezika.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Jun 05, 2008 1:15 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Smile Seveda se mi je zalomilo že v naslednjem koraku. Sicer znam izpisati eno črko na neko pozicijo LCDja, ne znam pa izpisati besede. Uporabljam winavr.

V prejšnjih postih omenjeni knjižnici sicer obstaja funkcija za izpis stringa, ampak mi nekako stvar ne uspe oživeti.

Tukaj imam izsek kode, ki naj bi izpisala string (besedo) na ekran (nahaja se v lcd_lib.c - imam jo vključeno v headerju #include):


Koda:
void LCDstring(uint8_t* data, uint8_t nBytes)   //Outputs string to LCD
{
register uint8_t i;

   // check to make sure we have a good pointer
   if (!data) return;

   // print data
   for(i=0; i<nBytes; i++)
   {
      LCDsendChar(data[i]); // ta funkcija izpiše posamezni znak in deluje
   }
}


Omenjena je tudi v datoteki lcd_lib.h in sicer takole:


Koda:
void LCDstring(uint8_t*, uint8_t);   //Outputs string to LCD


Pri kompiliranju mi vedno javi napako pri klicu te funkcije. Domnevam da zato, ker pri klicu ne vstavim pravilnih podatkov. Sem že poizkušal z besedo v narekovajih ", v opuščajih ' , z raznimi medsebojnimi kombinacijami.....

Primer, kako jo v programu kličem:


Koda:
LCDstring('test',4);


Javlja mi pa opozorilo: passing argument 1 of 'LCDstring' makes pointer from integer without a cast

Kako lahko pravilno napišem besedo na LCD? Se pravi, kakšen bi bil pravilen klic funkcije in ali je potrebno katero od spremenljivk še posebej definirati pred klicem (kako?).


PS drugače pa ugotavljam, da Winavr včasih eno in isto stvar uspešno prevede, včasih pa z napakami.

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Čet Jun 05, 2008 3:42 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:

char niz[10];
strcpy(niz, "test");
LCDstring(&niz[0],4);

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Jun 06, 2008 7:20 am    Naslov sporočila:  
----------------------------------------------------------------------------
@int47:

Deluje Very Happy . Tega nebi sam nikoli ugotovil. Sem pa moral vključiti tudi funkcijo string.h

Bi pa še vprašal malce o pomenu podatkov v tvoji kodi, če ti ni pretežko odgovoriti:

1- Char niz[10] - ta definira besedni string z imenom niz in maksimalne dolžine 10 znakov? (ali je zaključna 0 na koncu stringa všteta)

2 - strcpy(niz, "test") - tega sem ugotovil- besednemu stringu niz da vrednost "test"

3- LCDstring(&niz[0],4) - tega pa najmanj zastopim. Zakaj je pred stringom znak in (&), zakaj je v oglatem oklepaju vrednost [0], in zakaj je za vejico 4?

Sicer sem pa zaradi tvoje kode prišel do zanimive strani z osnovami c-ja, ki jo prav priporočam takim začetnikom, kot sem jaz. Je sicer namenjena linuxu, ampak očitno uporabna tudi pri avrjih Smile

http://www.macdonald.egate.net/CompSci/index.html

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Sob Jun 07, 2008 12:00 am    Naslov sporočila:  
----------------------------------------------------------------------------
Citiram:
1- Char niz[10] - ta definira besedni string z imenom niz in maksimalne dolžine 10 znakov? (ali je zaključna 0 na koncu stringa všteta)

10 znakov je skupaj z zaključno 0.
1. znak se nahaja v niz[0], zadnji pa v niz[9]

Citiram:
3- LCDstring(&niz[0],4) - tega pa najmanj zastopim. Zakaj je pred stringom znak in (&), zakaj je v oglatem oklepaju vrednost [0], in zakaj je za vejico 4?



Če pogledaš funkcijo
Citiram:
void LCDstring(uint8_t* data, uint8_t nBytes) //Outputs string to LCD

1. parameter je kazalec na podatke tipa uint8_t
Kazalec je spremenljivka, katere vrednost kaže na lokacijo(naslov), ki vsebuje željen podatek.
& vrne naslov, na katerem se nahaja spremenljivka
&niz[0] je torej naslov 1. znaka v nizu.

Pri delu z nizi in kazalci je potrebno paziti, da se ne uporablja več znakov(lokacij), kot je rezerviranih.

2. parameter je tipa uint8_t
Če pogledaš funkcijo, vidiš, da ta parameter določa koliko znakov naj funkcija izpiše. Beseda test ima 4 črke.
Če ne želiš šteti znakov, lahko uporabiš funkcijo strlen, ki namesto tebe prešteje število znakov v nizu (brez zaključne 0).

P.S.
Enak učinek bi se dalo dobiti tudi z:

Koda:
char niz[10]={"test}; // niz je dolzine 10 znakov
LCDstring(niz,4);


Ali bolj univerzalno brez štetja znakov:
Koda:
char niz[]={"test}; // niz je dolzine 5 znakov (4+1)
LCDstring(niz,strlen(niz));

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Jun 09, 2008 1:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala lepa za razlago, sedaj mi je jasneje kako in kaj.

Trenutno pa telovadim z lastnimi funkcijami in njihovim klicanjem.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Jun 26, 2008 11:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
S kakšnim ukazom bi lahko 2 byta združil v en podatek (16-bitni). Po SPI-ju prejmem
MSB in LSB byte, potrebujem pa samo en 16 bitni podatek, npr. tipa long.

Hvala za odgovor!

Avtor: Sokrat PrispevekObjavljeno: Pet Jun 27, 2008 9:03 am    Naslov sporočila:  
----------------------------------------------------------------------------
podatek_long = (MSB << 8-) | LSB;

Avtor: upornikKraj: Celje PrispevekObjavljeno: Pet Jun 27, 2008 3:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Točno to sem rabil, hvala Smile

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Jul 08, 2008 7:15 am    Naslov sporočila:  
----------------------------------------------------------------------------
[quote="silvo_v"]
Domenius je napisal/a:

Koda:
#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned char delay;


/**********************      prekinitev timerja 0    **********************/

SIGNAL(SIG_OVERFLOW0)   // signal handler for tcnt0 overflow interrupt
 {
  TCNT0 = 61;      // 50 ms @ 4M
  ++delay;
 }


int main(void)
{
 DDRB = 0xff;
 
 TIMSK = 0x02;      // enable TCNT0 overflow
 TCNT0 = 61;      // 50 ms @ 4M
 TCCR0 = 0x05;      // count with cpu clock/1024
 
 sei();            // enable interrupts
 
 
  while (1)
   {
    if (delay==20)   // 1 sek   
    {
     delay=0;
     PORTB ^= 0xff;
    }

   }
 }


Lp


Tukajle sem ugotovil, da je v vrstici TCCR0 = 0x05 manjša napaka. Ki začetniku, kot sem jaz, z lahkoto požre nekaj ur, pa še rezultata na koncu ni.
Namesto TCCR0 je potrebno napisati TCCR0B. Vsaj pri meni je bilo tako. Ugotovil pa sem pri simulaciji v winavr, ko sem opazil imena registrov TCCR0A in TCCR0B. Zakaj pa sta dva registra, pa še nisem ugotovil.
Trenutno telovadim s Tinnyjem.[/b]

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Tor Jul 08, 2008 8:33 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ta koda je bila napisana za ATmega8515, ki ima samo en TCCR0 register. Novejši AVR mikrokrmilniki imajo po dva TCCR0 registra. Sicer pa na napačno ime registra opozori že prevajalnik pri prevajanju programa.

Pri prenašanju rutin in programov med različnimi mikrokrmilniki družine AVR je potrebno biti pozoren tudi na to, da so lahko med seboj pomešane tudi lokacije posameznih bitov v registrih.

Lp

Avtor: trotKraj: glej fogl PrispevekObjavljeno: Tor Jul 08, 2008 11:17 am    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
Zakaj pa sta dva registra, pa še nisem ugotovil.

Poglej v datasheet od tega mikrokontrolerja, pa boš videl koliko registrov ima in za kaj je kateri.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Jul 08, 2008 1:33 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Z vašo pomočjo, in s pomočjo primerov v tej temi,predvsem pa z idejo izpisovanja številk od silvo_v, sem izdelal prvi dokaj uporaben programček: URA Smile

S silvotovim algoritmom je dovolj majhen, da pride v tinnyja (ni potrebe po sprintf funkciji, ki je preobširna za tinyja).

Koda:
/* ŠTOPARICA - ura
   TIPKA - priklop na pinD1 - proti masi
   LED - priklop na pinA0 - proti masi ali +
   LCD - na portB - kot v nadaljevanju (spremeniš lahko v lcd_lib.h)
      LCD_RS   0    //define MCU pin connected to LCD RS
      LCD_RW   1    //define MCU pin connected to LCD R/W
      LCD_E   2   //define MCU pin connected to LCD E
      LCD_D4   4   //define MCU pin connected to LCD D3
      LCD_D5   5   //define MCU pin connected to LCD D4
      LCD_D6   6   //define MCU pin connected to LCD D5
      LCD_D7   7   //define MCU pin connected to LCD D6
      LDP PORTB   //define MCU port connected to LCD data pins
      LCP PORTB   //define MCU port connected to LCD control pins
      LDDR DDRB   //define MCU direction register for port connected to LCD data pins
      LCDR DDRB   //define MCU direction register for port connected to LCD control pins

PROGRAM KAŽE URO
*/

#include <avr\io.h>
#include <util\lcd_lib.c>
#include <avr/interrupt.h>

//DEKLARACIJA SPREMENLJIVK
volatile unsigned char ure;
volatile unsigned char minute; //short za >255, char za <255
volatile unsigned char sekunde;
volatile unsigned char takt;
volatile unsigned char izpis;
volatile unsigned char val, e, d;


int main (void)
{
// NASTAVITEV TIMERJA 0
TIMSK = 0x02;    //maska
TCNT0 = 13;      //začetno stanje števca (ko prekorači 255- prekinitev)
TCCR0B = 0x05;   // deljenje z 1024


//definicija vhodov in izhodov
 DDRA = 0x03; //pinA0 in A1 je izhod
 DDRD = 0x00;  //PortD so vhodi
 PORTD = 0x03; //pina d0 in D1 imata vklopljen pullup upor
 DDRB = 0xFF; //PortB je izhod (na njem je LCD- ali je potrebno?)

//inicializacija LCD
LCDinit ();
LCDclr ();
LCDcursorOFF();

sei();    // omogočanje prekinitev

while (1)
{
   
   if (takt == 4)   // če je pretekla ~1s,
      {         //potem:
      takt = 0;   //takt postavi nazaj na 0
      ++sekunde;   // povečaj števec sekund
      izpis = 1;   //omogoči izpis na ekran
      
      if (sekunde == 60)
         {
         sekunde = 0;
         ++minute;
         }
      if (minute == 60)
         {
         minute = 0;
         ++ure;
         }
      if (ure == 24)
         ure = 0;
      }
   if (izpis == 1)   // če je omogočen izpis
   {            //potem:
   cli();         //onemogoči prekinitve
   izpis = 0;      //zbriši zastavico za omogočanje izpisa
   LCDGotoXY(4,0);   //postavi se na pozicijo
   
   //IZRAČUN IN IZPIS UR
   val = ure;      //
   izracun ();
   LCDsendChar (d+48); //d- desetice : 48 predstavlja ASCII znak 0
   LCDsendChar (e+48);   //e- enice
   LCDstring (":", 1);   //dvopičje
   
   //IZRAČUN IN IZPIS MINUT
   val = minute;
   izracun ();
   LCDsendChar (d+48);
   LCDsendChar (e+48);
   LCDstring (":", 1);
   
   //IZRAČUN IN IZPIS SEKUND
   val = sekunde;
   izracun();
   LCDsendChar (d+48);
   LCDsendChar (e+48);
   sei();            //ponovno omogoči prekinitve
   }
}
}
//FUNKCIJA IZRAČUNAVANJA CIFER
void izracun()
   {
   e=val/10;   //enice
   e=e*10;
   e=val-e;

   val=val/10;   //desetice
   d=val/10;
   d=d*10;
   d=val-d;
   }



// FUNKCIJA OB PREKINITVI
SIGNAL(SIG_OVERFLOW0)

   {
   TCNT0 = 13;         //osnovno stanje števca
   ++takt;            //takt povečaj
   if (takt == 2 || takt == 4)   // če je 0.5s ali 1s naokoli-
      PORTA ^= 0x01;   // Hartbeat LED na PORTA.0 se obdela z XOR (ali pa negacijo)
   }


Za izpis na LCD uporabljam knjižnico, ki sem jo našel na netu (nekje v tej temi sem že povedal, kje se jo da dobiti)
Točnost ure sicer ni 100% - bistvo je bilo v postopku
program je tudi namenoma bolj obširen- tako da je lažje razumljiv. Zasede pa cca 1100bytov.

Naslednji korak je optimizacija- manjšanje programa

Uporabljen Attiny in Winavr. Tiny deluje z osnovno interno frekvenco

edit: šele sedaj vidim, da je programčič kar dolg Shocked

Avtor: upornikKraj: Celje PrispevekObjavljeno: Tor Jul 08, 2008 3:46 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Citiram:
Naslednji korak je optimizacija- manjšanje programa


Še korak dalje bi lahko bila funkcija, s katero nastaviš čas, ki je nepogrešljiva pri uri za vsakdanjo uporabo.

Veselo programiranje Very Happy

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Jul 09, 2008 6:55 am    Naslov sporočila:  
----------------------------------------------------------------------------
Very Happy tudi to bom poizkusil narediti.

Avtor: PC_MasterKraj: Domžale , Blizu Ljubljane , Poštna 1230 PrispevekObjavljeno: Sre Jul 09, 2008 9:12 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pomoje lahko pri compilerju nastaviš velikost optimizacije. Samo baje če preveč optimiziraš program naj nebi deloval pravilno. Mislim optimizirat preko komande , ne ročno Wink

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Jul 10, 2008 1:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------
PC_Master, to vem! Itak sem imel vključeno optimizacijo glede na velikost prevedene kode.
Mislil sem na optimizacijo programa- krajšanje. Tako sem zmanjšal program iz 1098bytov in 14 spremenljivk na 938 bytov in (mislim da) 5 spremenljivk. Ob popolnoma enaki končni funkciji programa.

Trenutno - ko imam čas - program nadgrajujem z nastavitvijo ure preko ene tipke. Ni tako lahko, kot sem mislil.

Avtor: majkelKraj: Maribor PrispevekObjavljeno: Ned Jul 13, 2008 3:32 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Imam problem z prevajalnikom codevison.In sicer mi vrže napako ker ne najde knjižnice interrupt.h.V programu jo imam definirano tako :
#include "interrupt.h" ali pa če dam tako #include <avr/interrupt.h> mi napiše da ne more odpret tega fajla ki ga imam vključenega .prosim eč mi da lahko kdo nasvet.

LP

Avtor: tadej.ko2Kraj: sveta trojica PrispevekObjavljeno: Pet Avg 22, 2008 10:07 pm    Naslov sporočila:  vklop lučke
----------------------------------------------------------------------------
moja zgodba pa je taka:
spisal sem program, ki bi vsakih 24 ali 48 ur vključil led (mogoče bo to 11kw motor).
program je že skoraj real-time aplikacija. hardware: attiny 26, 2tipki (tp in tm), 2x7seg led, led kot motor (M), quarc 4MHz, 2 tranzistorja za 2x7seg ledice
deluje tako: na ledicah je izpisano število ur do naslednjega vklopa M, številka pa utripa, dokler ne pritisneš katere tipke. če tp("tipka plus") držiš več kot 1s, se vključi/izkluči M;če samo pritisneš tp/tm("tipka minus"), se ura, izpisana na 7seg ledicah, poveča/pomanša za 1.
imam še meni: če držiš tm, začnejo ledice utirpati, izpiše se interval vklopa(24/48 ). nastaviš ga s pritiskanjem na tp. naslednji pritisk na tm izpiše dolžino vklopljenega izhoda M (v minutah, recimo 4.2 - prižge se še pikica); ta čas nastavimo s pritiskanjem na tp/tm. nato sledi še 1s pritisk na tm in pridemo iz "menija", izpiše se število ur do naslednjega vklopa M.

koda: //prestavil sem jo v datoteko, ker je dolga 3 kilometre

sedaj pa problem: spremenljivka mcasc, ki hrani dolžino prišganega izhoda (M) se mi sama spreminja. Confused ko grem v mani, da bi jo nastavil, je velikokrat kar 0.0, kar se ob prtisku katere koli tipke takoj spremeni na 0.1, ker imam pogoje: if(mcasc < 1) mcasc =1; in if(mcasc>99) mcasc =99;
bi lahko kdo našel, kaj zavraga mi spreminja to spremenljivko? so mogoče vrstice kode predolge za ta mali čipek? koda zasede: Program size: 878 words (85,7% of FLASH)

hvala vsem!
lp

Avtor: tejkoKraj: Pragersko PrispevekObjavljeno: Sob Avg 23, 2008 2:19 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mogoče ti stack povozi spremenljivke, glede na to, da imaš 86% zasedenost flasha.

Avtor: tadej.ko2Kraj: sveta trojica PrispevekObjavljeno: Sob Avg 23, 2008 4:14 pm    Naslov sporočila:  
----------------------------------------------------------------------------
mislim da je težave povzročal overflow spremenljivke mcasc. tip sem mu spremenil na short in zadeva deluje perfektno.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Ned Avg 24, 2008 12:56 pm    Naslov sporočila:  
----------------------------------------------------------------------------
A ma kdo mogoče napisano kakšno funkcijo, ki iz 16-bitnega podatka naredi dva 8-bitna(MSB,LSB)? Potreboval bi jo zato, ker lahko oddajnik naenkrat pošlje samo 1byte, podatki ki jih pošiljam so pa 2bytni.

Hvala za odgovor!

Avtor: VolkDKraj: Divača (Kačiče) PrispevekObjavljeno: Ned Avg 24, 2008 1:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
/ 256
%256

Avtor: upornikKraj: Celje PrispevekObjavljeno: Ned Avg 24, 2008 1:53 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Citiram:
/ 256
%256


Se pravi, takole? MSB=podatek/256;
LSB=podatek%256;

Hvala, sploh nisem pomislil da se tako naredi Very Happy

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Avg 29, 2008 11:29 am    Naslov sporočila:  
----------------------------------------------------------------------------
Very Happy Po dopoustu in obilici dela doma in v službi sem se zopet lotil mojega testnega programčka URA. Dodal sem možnost nastavljanja časa. Vse se dela z eno tipko.
Napisano v WINAVR za Tinyja 2313. Velikost 1356 bytov in 31bytov spremenljivk.
Veliko možnosti optimizacije kode, še posebno na področju uporabe spremenljivk.


Še eno stvar pa bi rad poizkusil. Najlaže kar v tem programu. Kako lahko eno od spremenljivk (kalibracija) shranim v EEPROM? Ob vklopu napravice bi jo potem prebral in uporabil v programu ter ob morebitni ponastavitvi zopet zapisal v EEPROM?

Ko bom še to poizkusil, bom pa v testno ploščo vtaknil Mego. Ker se bom lotil resnega izdelka, kjer bom potreboval AD pretvornike.

V prilogi txt verzija programa

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Sep 03, 2008 7:05 am    Naslov sporočila:  
----------------------------------------------------------------------------
1. S pomočjo ata googla sem prišel do spoznanja, da je potrebno v eeprom najprej spremenljivke zaprogramirati (recimo z avr studiem). Pri prevajanju programa kompiler naredi datoteko za vpis v eeprom. Ali je to dvoje res?

2. Potem, ko so spremenljivke prišle v eeprom in se izvaja koda v uC, ali je možno, da uC sam spreminja vrednosti (na zahtevo programa) teh spremenljivk ali je treba nove vrednosti zopet vnesti s programatorjem?

3. Če lahko uC sam piše / spreminja vrednosti spremenljivk v eepromu bi pa rad, če kdo tukaj prilima kakšen že izdelan konček programa, ki bi to počel. Tako da bi vsaj vedel, katere besede / ukaze moram poiskati z googlom.

PS, tisto, kar je o eepromu omenjeno v tej temi, mi ne pomaga prav veliko.

Imam pa winavr.

Avtor: alessioKraj: Ljubljana PrispevekObjavljeno: Sre Sep 03, 2008 7:31 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ni nujno, da podatke v eeprom najprej vpišeš z programatorjem, če jih hočeš uporabljati v programu. Je samo dodatna opcija.
Normalna uporaba je ta, da MCU sam bere in seveda tudi piše v ta del pomnilnika. Če bi rabil samo branje, bi za to uporabil Flash.
Prednost EEPROM-a pred Flash-om je v tem, da ti omogoča zelo granuliran vpis podatkov, pri Flash-u lahko vpišeš minimalno en cel page,
kar je min. 512B (odvisno od čipa). V EEPROM pa se da zelo enostavno vpisati samo po 1B.

Če delaš z winarm toolchain-om, potem imaš med drugim za handlanje z eeprom-om že vse pripravljeno v knjižnici avr-libc. Poglej si user manual sekcija 6.13.
http://www.nongnu.org/avr-libc/

Sicer pa že dolgo ne uporbljam AVR-jev, odkar sem na ARM core-ih, tak da ti žal ne morem postreči s kakim primerom.

Aleš

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Sre Sep 03, 2008 7:42 am    Naslov sporočila:  
----------------------------------------------------------------------------
1. če variabli nastaviš vrednost jo moraš zapisat z .eep filom ja. če pa variablo samo inicializiraš, in jo potem spreminja program med delovanjem pa ti ni treba zapisat .eep filea.

2. ja lahko spremija vrednosti, to je fora eeproma.

3. za winavr išči <eeprom.h>. za codevision ne rabiš nič. samo inicializiraš z besedico eeprom. uporabljaš isto kakor ostale variable. npr:
Koda:

  eeprom char a=3;         //variabli a nastaviš vrednost, compiler naredi eep file
  eeprom int b;                // var samo inicializiraš.
  ......
  a=b+2;
 




tukaj imaš primer izdelave ure. uporablja kvarc kristal 32khz in asinhroni timer2. attiny nima takega timerja, glej datashet mega8, mega16,....

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Sep 03, 2008 1:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Bom tole malce preštudiral in preizkusil. Malce jasneje mi je že.

Hvala obema za odgovor!

Branko


PS dragoon: Če prav razumem, tvoj primer v eepromu ustvari char a in mu da vrednost 3 (to začetno vrednost v uC vneseš s programatorjem). Nato v eepromu rezervira prostor za int b (ki ima ob začetku verjetno vrednost 0). Nazadnje pa vsoto b+2 uC sam vpiše v eeprom kot novo vrednost char a.

Ali sem razmišljal prav?

Avtor: dragoonKraj: Trojane PrispevekObjavljeno: Sre Sep 03, 2008 6:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
tako je, v codevisionu. Pri GCC ni tako enostavno.


dolgo sem pisal, pa me je allesio prehitel.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Sep 04, 2008 10:40 am    Naslov sporočila:  
----------------------------------------------------------------------------
Very Happy Zopet sem se z vašo pomočjo naučil malce več, tokrat o uporabi eeproma.

Rešitev problema (za tiste, ki bodo naleteli na to težavo)

Z winawrom je uporaba eeproma malce drugačna kot v Codevisionu.

1. Najprej je treba vključiti knjižnico <avr/eeprom.h>
2. Nato pri deklaraciji spremenljivk na začetku programa tisto, ki bo v eepromu deklariraš takole:

Koda:
EEMEM unsigned char eespremenljivka = 15;


Deklariraš lahko tudi druge tipe spremenljivk, ključna je beseda EEMEM, ki kompilerju pove, da jo mora shraniti v eeprom. Tej v tem primeru je že prirejena vrednost 15 (vrednosti pravzaprav ni nujno prirediti)

3. v programu jo potem prebereš takole:


Koda:
spremenljivka = eeprom_read_byte (&eespremenljivka);

Byte prebere en znak, word bi prebral dva znaka

4. V eeprom bi novo vrednost napisal takole:
Koda:
eeprom_write_byte (eespremenljivka);

No, tega še nisem preizkusil, ampak nekako tako bi moralo biti.

Pri kompiliranju programa se ustvari eep datoteka. to je potrebno zapisati v eeprom.

Je pa pomemben vrstni red zapisovanja: najprej program (hex) v flash, šele nato vrednosti spremenljivk (eep) v eeprom. Če zamenjaš vrstni red, pri zapisovanju programa očitno izbriše vrednost eeproma in postavi vse vrednosti na 0xFF.

V pomoč mi je bil tudi ta tutorial:

http://winavr.scienceprog.com/avr-gcc-tutorial/save-constants-to-avr-eeprom-using-winavr.html

Avtor: tadej.ko2Kraj: sveta trojica PrispevekObjavljeno: Pet Sep 05, 2008 12:37 pm    Naslov sporočila:  
----------------------------------------------------------------------------
tukaj je en možakar imel podobne želje, a jih je drugače izvedel:
http://userweb.upctelemach.net/~u052009/Elektronika/CodeVisionAVR/CVAVR_8515_LED_eeprom/CVAVR_8515_LED_eeprom.html

lp

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Sep 05, 2008 1:22 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala tadej, tvoj link prikazuje sicer izvedbo s Codevisionom. Tukaj pa je razlika sintakse v primeri z winavr in mi ne ustreza. Saj princip sem si nekako že razjasnil, samo še izvedba me Mad .

Trenutno me muči 4. točka iz mojega prejšnjega posta.

bolj pravilno (čeprav ne povsem) bi se glasila:
Koda:
eeprom_write_byte (eespremenljivka, spremenljivka)


Pravilno pa ni zato, ker sem po dnevu tuhtanja ugotovil, da novo vrednost v eeprom zapiše tja, kamor mu paše (enkrat tukaj, drugič tam...). Se pravi ne tja, kamor bi jaz želel.

Pa še eno kratko vprašanje: ali se da uC resetirati programsko? Se pravi, ko bi uC nekaj naredil, bi se programsko resetiral in začel program izvajati povsem od začetka?


EDIT:

Very Happy Pa še prejšnjo 4. točko sem ugotovil.

Popolnoma pravilno se glasi:
Koda:
eeprom_write_byte (adresa, vrednost)

adresa pomeni kam naj shrani, vrednost pa tisto, kar bo na podano adreso zapisal.
Torej je potrebna previdnost, da v eepromu ne povoziš napačnih podatkov - dobra organizacija spomina.


Nazadnje urejal/a lojzek Pet Sep 05, 2008 1:48 pm; skupaj popravljeno 1 krat

Avtor: bolha95Kraj: Križe / Tržič PrispevekObjavljeno: Pet Sep 05, 2008 1:48 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:


Pa še eno kratko vprašanje: ali se da uC resetirati programsko? Se pravi, ko bi uC nekaj naredil, bi se programsko resetiral in začel program izvajati povsem od začetka?


Enostavno - aktiviraj watchdog

LP
R

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Sep 11, 2008 9:25 am    Naslov sporočila:  
----------------------------------------------------------------------------
Imam novo vprašanje (do problemov še nisem prišel Very Happy ).

Sedaj sem namesto Tinyja v testno ploščo vtaknil Mego in se začenjam igrati z AD pretvornikom. Berem razne tutoriale in user manual od Mege, tako da mi je princip delovanja AD pretvornika teoretično razumljiv.

Prišel sem do tega izseka kode:

Koda:
ADCSRA |= (1<<ADSC)|(1<<ADIE);


Razumljivo mi je, da ta vrstica v register ADCSRA na mesti bitov ADSC in ADIE vpiše vrednost 1, ne razumem pa matematično, kako to naredi- ni mi popolnoma jasna logika C-ja.
Vprašanja:
1. prvi operand |= verjetno pomeni, da se bo sprememba izvedla samo na dveh bitih, omenjenih v nadaljevanju funkcije, brez spremembe stanja ostalih bitov?
2. kaj dejansko naredi operand <<? Prebral sem, da naj bi premaknil bite v levo.
3. naslednji operand | : ali je nujno potreben, oziroma ali bi to kodo lahko ločil v dve vrstici kode na tem mestu?
4. ali kompiler (winavr) že sam po sebi ve, da je ADSC 6. bit in ADIE 3. bit? Brez da bi ju predtem moral kako definirati?
5. kako potem, ko bom prebral rezultat, podan v dveh bytih, iz teh dveh bytov naredim eno besedo (kateri matematični operand se za to uporabi). Primer: iz bytov 0x1E in 0xFF bi rad dobil 0x1EFF?

LP Branko

Avtor: trotKraj: glej fogl PrispevekObjavljeno: Čet Sep 11, 2008 10:02 am    Naslov sporočila:  
----------------------------------------------------------------------------
1: ADCSRA |= (1<<ADSC)|(1<<ADIE); <==> ADCSRA = ADCSRA|(1<<ADSC)|(1<<ADIE);
2: to je shift operator
3: to je logični OR operator
4: ne ne ve, to ima zapisano v headerjih kot makro, npr
Koda:
#define ADSC 6
. To pomeni, da v fazi prevajanja na mesta kjer piše ADSC zapiše 6.
5: (0x1E<<8-)+0xFF

Malo preštudiraj osnove c-ja, npr tole

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Sep 11, 2008 10:26 am    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala za hiter odgovor, ampak se mi je še nekaj vprašanj porodilo.

2. če normalno shiftaš samo 1 bit, ga dejansko zbrišeš. Ali potem ta izraz 1<<ADSC "postavi 1 pred bit ADSC in potem zashifta tako, da pride 1 v ADSC"? Smile Malce pesniško sem opisal, ampak upam da je razumljivo.
3. to vem, ampak ali v tem primeru OR ločuje dve operaciji, ki se izvedeta ena za drugo? Torej bi lahko to kodo razdelil na dve vrstici?
4. Ali je torej potrebno #include kakšno knjižnico, ali je že dovolj da winavrju poveš, da delaš z Mego? Ker sem testno to vrstico prevedel in ni bilo napak...
5. To bom pa preizkusil v nadaljevanju

Avtor: trotKraj: glej fogl PrispevekObjavljeno: Čet Sep 11, 2008 10:43 am    Naslov sporočila:  
----------------------------------------------------------------------------
2: nisem razumel. Naredi pa tako, 1 v binarnem je 00000001. To potem 6x premakne v levo in z desne dodaja ničle. Tako potem dobiš v binarnem 01000000.
3: lahko bi napisal dve vrstici: ADCSRA = ADCSRA|(1<<ADSC); ADCSRA = ADCSRA|(1<<ADIE); Edini efekt tega je več pisanja.
4: mogoče že sam doda knjižnico, ko v makefile-u izbereš čip.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Čet Sep 11, 2008 11:23 am    Naslov sporočila:  
----------------------------------------------------------------------------
Lojzek, glede bitnega naslavljanja z maskami je tudi mene mučilo v tej temi, zato bom sem še enkrat prilepil odgovor Domeniusa, ki sem ga takrat dobil, meni je razjasnil maske.

Citiram:
Če hočeš spremeniti stanje celega porta pošlješ nanj nek bajt oz. 8 bitov. Tukaj ni nič problemov z maskami. MSB bit spremeni PORTX.7, LSB bit poslanega bajta pa PORTX.0. Če pa hočeš spremeniti stanje samo enega pina brez da bi vplival na ostale moraš uporabit maske.
PORTC |= 0x20; v bistvu pomeni PORTC = PORTC | 0x20;, samo da je krajše napisano. Ta operacija postavi nek bit (0x20 je peti bit, ker je 0x20 enako 32 - 2 na 5 potenco je tudi 32, od tod torej peti bit) na 1. Tista črta pomeni logično operacijo OR. In ker je 0 OR X = X in 1 OR X = 1 se postavi bit samo tam kjer je enica, ostali pini pa ostanejo v takšnem stanju kot so.
Enako je pri PORTC &= ~0x20; - to pomeni PORTC = PORTC & ~0x20;. Ta operacija postavi pin na 0. Znak & pomeni logično AND operacijo, znak ~ pa negacijo. Namesto ~0x20 bi lahko napisal tudi 0xDF, je čisto enako, samo takšen način z negacijo se meni zdi bolj pregleden. Ker je 0 AND X = 0 in 1 AND X = X se pin postavi na nič samo tam kjer je ničla v poslanem bajtu, kjer so pa enice se pa stanje ohrani (X). Za boljše razumevanje tega napiši par programčkov z maskami in brez in jih testiraj v simulatorju AVR Studia pa boš videl razliko.
Napačno krmiljenje porta: če boš na port poslal 00000010 brez maske se bo drugi pin postavil na 1, ostali pa na 0 - če boš pa na npr. četrtem pinu spremljal stanje pina (vhodni pin) in bo pred pošiljanjem bajta na port stanje vhodnega pina 1 se bo pojavila napaka - ne programska ampak pri odčitavanju vrednosti.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Sep 11, 2008 11:46 am    Naslov sporočila:  
----------------------------------------------------------------------------
@ upornik, vse to se že prebral in tudi nekako razumem Smile . Pravzaprav vsakič, ko imam težavo, preberem celo temo.

@ trot: Aha sedaj razumem 2. točko. Pravzaprav izvede bitni OR med obstoječo vsebino registra ADCSRA in 6× v levo zašiftano 1 (0b0100000). Nato pa še ponovi enako operacijo s 3× zašiftano 1.

Povsem enak efekt bi torej dobil tudi z maskami. Npr. ADCSRA |= 0b01000100

Avtor: trotKraj: glej fogl PrispevekObjavljeno: Čet Sep 11, 2008 12:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
Povsem enak efekt bi torej dobil tudi z maskami. Npr. ADCSRA |= 0b01000100

Točno tako, to premikanje enke je samo način generiranja maske, ki je enostavnejši, poleg tega pa je tudi koda bolj razumljiva, ker če bi direktno pisal masko čez en teden ne bi več vedel, kaj dela koda v tej vrstici.

Avtor: jstajnkoKraj: koracice PrispevekObjavljeno: Ned Sep 21, 2008 8:27 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mene pa zanima kako narediti števec, ko pritisnem na tipko se naj na lcd-ju izpiše 1, ko ponovno pritisnem se naj izpiše 2 itd.

koda ki sem jo napisal:

while (1)

if (PIND.4 == 1)
{
i+=1;
lcd_putchar(i);
}

Ampak ta koda ne deluje, samo čudni znaki se izpisujejo po celem lcd-ju.

Avtor: VolkDKraj: Divača (Kačiče) PrispevekObjavljeno: Ned Sep 21, 2008 9:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
jstajnko je napisal/a:
Ampak ta koda ne deluje, samo čudni znaki se izpisujejo po celem lcd-ju.

Ja saj potem dela prav. Mislim... točno tako kot si napisal.

Če boš tole:
Koda:
if (PIND.4 == 1)


spremenil v
Koda:
if (PIND.4 == 0)


bodo pa čudni znaki na lcd-ju leteli le če boš tipko pritisnil...

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Sep 22, 2008 6:37 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pa še nekaj.. Ali ne napiše putchar ASCII znak s tisto številko?
Se pravi, bi moral nekako šteti pritiske, potem bi moral šteti spuste tipk, potem pa to številko predelati v kombinacijo ASCII znakov in te izpisati na LCD. Pa vsakič, ko kličeš funkcijo putchar, ti bo napisalo na naslednje mesto in boš imel hitro poln ekran. Se pravi.. Vsakič, ko boš pisal, se postavi na isto pozicijo na LCDju.

PS še 1× ali pa tudi večkrat preberi tole celotno temo. Je notri marsikaj koristnega! Mogoče tudi rešitev tvojega problema.

Avtor: nakamichiKraj: Nova Gorica PrispevekObjavljeno: Pet Dec 19, 2008 10:11 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Danes sem prvič naletel na to napako

Koda:
rm -rf utripanje_ledice.o  utripanje_ledice.elf dep/* utripanje_ledice.hex utripanje_ledice.eep utripanje_ledice.lss utripanje_ledice.map
Build succeeded with 0 Warnings...
avr-gcc.exe  -mmcu=atmega168 -Wall -gdwarf-2 -std=gnu99   -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT utripanje_ledice.o -MF dep/utripanje_ledice.o.d  -c  ../utripanje_ledice.c
../utripanje_ledice.c: In function 'main':
../utripanje_ledice.c:5: error: 'DDRA' undeclared (first use in this function)
../utripanje_ledice.c:5: error: (Each undeclared identifier is reported only once
../utripanje_ledice.c:5: error: for each function it appears in.)
../utripanje_ledice.c:6: error: 'DATAA' undeclared (first use in this function)
make: *** [utripanje_ledice.o] Error 1



Kljub kar nekaj programiranja do sedaj te napake, da PORT-a nebi našel še nisem videl. Ima kdo izkušnje, rešitve? Mikrokrmilnik je definiran, pišem v AVR Studio.

Koda:
#include <avr\io.h>

int main(void)
{
DDRA = 0xff;
DATAA = 0x01;
}



L.P.,
Miha

Avtor: jvolkKraj: okolica Divače PrispevekObjavljeno: Pet Dec 19, 2008 10:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
@nakamichi:
Verjetno tvoj mikrokontroler (oz tistega, ki si si zbral v projektu) nima porta A.

Z DATAA si pa verjetno mislil PORTA.

Avtor: nakamichiKraj: Nova Gorica PrispevekObjavljeno: Sob Dec 20, 2008 12:02 am    Naslov sporočila:  
----------------------------------------------------------------------------
Res je, zatipkal sem se v sili pisanja testnega programa.

No prav si imel, očitno nisem prav pri sebi, saj sem samoumevno sklepal, da ga ima brez pogledat datasheet in tako izpadel precej....

Hvala za hiter odgovor.

L.P.,
Miha

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Feb 22, 2009 5:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Naj me prosim nekdo razsvetli ali pa ustreli. Wink

Kam za vraga moram shraniti eno *.h datoteko (konkretneje lcd_lib) ali kaj za boga moram narediti z njo, da jo bo WinAvr prepoznal in jo pravilno tudi vključil?! Sploh se ne znajdem več. Preglodal sem avrfrike, strani od Winavr in bolj ko berem, bolj sem glup...ali pa so GCC orodja...

Prosim za pomoč. Samo en k*** displej bi rad oživel v tem okolju... Rolling Eyes Rolling Eyes

Avtor: jjakobKraj: Rakičan (Murska Sobota) PrispevekObjavljeno: Ned Feb 22, 2009 5:40 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Potrebuješ .h in .c v mapi v kateri imaš main, vključiš pa ju z #include (...).h.

Avtor: Sokrat PrispevekObjavljeno: Ned Feb 22, 2009 6:09 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Normalno v C-ju je, da gre za headerje, ki so v < > pogledat v include direktorij oz. pregleda cel include path, za tiste, ki so v " " pa v isti direktorij, kjer se nahaja .c.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Feb 22, 2009 6:16 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Saj imam...

edino stvar ki jo uspem pridelati je cel kup rdečih pik v build listi Rolling Eyes
Nevem no...a je tako težko al sem tako tumpast? Kar se teh stvari tiče je Bascom res zakon! No, sam se moram navaditi. Vsaka pomoč bi mi prišla prav. A imaš mogoče ti kako delujočo knjižnico za 16x2 LCDje, kateri se da določiti na katerih pinih imaš obešen LCD (brez R/W) ter da se to da enotavno klicati?!

Hvala.

Avtor: Sokrat PrispevekObjavljeno: Ned Feb 22, 2009 6:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pripni relevantni del kode in izpisa build procesa, od ugibanja ne bo nobene koristi.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Feb 22, 2009 6:25 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ja. Evo, poizkusil sem samo inicializirati LCD...pa...

Koda:

#include "lcd_lib.h"

void main(void)
{
   while(1)
      {
         LCDinit();

       }
   
}


lcd_lib.h

Koda:

#ifndef LCD_LIB
#define LCD_LIB

#include <inttypes.h>


//Uncomment this if LCD 4 bit interface is used
//******************************************
#define LCD_4bit
//***********************************************

#define LCD_RS   1    //define MCU pin connected to LCD RS
#define LCD_RW   2    //define MCU pin connected to LCD R/W
#define LCD_E   0   //define MCU pin connected to LCD E
#define LCD_D0   0   //define MCU pin connected to LCD D0
#define LCD_D1   1   //define MCU pin connected to LCD D1
#define LCD_D2   2   //define MCU pin connected to LCD D1
#define LCD_D3   3   //define MCU pin connected to LCD D2
#define LCD_D4   7   //define MCU pin connected to LCD D3
#define LCD_D5   6   //define MCU pin connected to LCD D4
#define LCD_D6   5   //define MCU pin connected to LCD D5
#define LCD_D7   4   //define MCU pin connected to LCD D6
#define LDP PORTD   //define MCU port connected to LCD data pins
#define LCP PORTD   //define MCU port connected to LCD control pins
#define LDDR DDRD   //define MCU direction register for port connected to LCD data pins
#define LCDR DDRD   //define MCU direction register for port connected to LCD control pins

#define LCD_CLR             0   //DB0: clear display
#define LCD_HOME            1   //DB1: return to home position
#define LCD_ENTRY_MODE      2   //DB2: set entry mode
#define LCD_ENTRY_INC       1   //DB1: increment
#define LCD_ENTRY_SHIFT     0   //DB2: shift
#define LCD_ON_CTRL         3   //DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY      2   //DB2: turn display on
#define LCD_ON_CURSOR       1   //DB1: turn cursor on
#define LCD_ON_BLINK        0   //DB0: blinking cursor
#define LCD_MOVE            4   //DB4: move cursor/display
#define LCD_MOVE_DISP       3   //DB3: move display (0-> move cursor)
#define LCD_MOVE_RIGHT      2   //DB2: move right (0-> left)
#define LCD_FUNCTION        5   //DB5: function set
#define LCD_FUNCTION_8BIT   4   //DB4: set 8BIT mode (0->4BIT mode)
#define LCD_FUNCTION_2LINES 3   //DB3: two lines (0->one line)
#define LCD_FUNCTION_10DOTS 2   //DB2: 5x10 font (0->5x7 font)
#define LCD_CGRAM           6   //DB6: set CG RAM address
#define LCD_DDRAM           7   //DB7: set DD RAM address
// reading:
#define LCD_BUSY            7   //DB7: LCD is busy
#define LCD_LINES         2   //visible lines
#define LCD_LINE_LENGTH      16   //line length (in characters)
// cursor position to DDRAM mapping
#define LCD_LINE0_DDRAMADDR      0x00
#define LCD_LINE1_DDRAMADDR      0x40
#define LCD_LINE2_DDRAMADDR      0x14
#define LCD_LINE3_DDRAMADDR      0x54
// progress bar defines
#define PROGRESSPIXELS_PER_CHAR   6


void LCDsendChar(uint8_t);      //forms data ready to send to 74HC164
void LCDsendCommand(uint8_t);   //forms data ready to send to 74HC164
void LCDinit(void);         //Initializes LCD
void LCDclr(void);            //Clears LCD
void LCDhome(void);         //LCD cursor home
void LCDstring(uint8_t*, uint8_t);   //Outputs string to LCD
void LCDGotoXY(uint8_t, uint8_t);   //Cursor to X Y position
void CopyStringtoLCD(const uint8_t*, uint8_t, uint8_t);//copies flash string to LCD at x,y
void LCDdefinechar(const uint8_t *,uint8_t);//write char to LCD CGRAM
void LCDshiftRight(uint8_t);   //shift by n characters Right
void LCDshiftLeft(uint8_t);   //shift by n characters Left
void LCDcursorOn(void);      //Underline cursor ON
void LCDcursorOnBlink(void);   //Underline blinking cursor ON
void LCDcursorOFF(void);      //Cursor OFF
void LCDblank(void);         //LCD blank but not cleared
void LCDvisible(void);         //LCD visible
void LCDcursorLeft(uint8_t);   //Shift cursor left by n
void LCDcursorRight(uint8_t);   //shif cursor right by n
// displays a horizontal progress bar at the current cursor location
// <progress> is the value the bargraph should indicate
// <maxprogress> is the value at the end of the bargraph
// <length> is the number of LCD characters that the bargraph should cover
//adapted from AVRLIB - displays progress only for 8 bit variables
void LCDprogressBar(uint8_t progress, uint8_t maxprogress, uint8_t length);


#endif


Ter lcd_lib.c
Koda:

#include "lcd_lib.h"
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

const uint8_t LcdCustomChar[] PROGMEM=//define 8 custom LCD chars
{
   0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block
   0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block
   0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block
   0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block
   0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block
   0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block
   0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow
   0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00  // 7. fast-forward arrow
};


void LCDsendChar(uint8_t ch)      //Sends Char to LCD
{

#ifdef LCD_4bit
   //4 bit part
   LDP=(ch&0b11110000);
   LCP|=1<<LCD_RS;
   LCP|=1<<LCD_E;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);   
   LCP&=~(1<<LCD_RS);
   _delay_ms(1);
   LDP=((ch&0b00001111)<<4);
   LCP|=1<<LCD_RS;
   LCP|=1<<LCD_E;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);   
   LCP&=~(1<<LCD_RS);
   _delay_ms(1);
#else
   //8 bit part
   LDP=ch;
   LCP|=1<<LCD_RS;
   LCP|=1<<LCD_E;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);   
   LCP&=~(1<<LCD_RS);
   _delay_ms(1);
#endif
}
void LCDsendCommand(uint8_t cmd)   //Sends Command to LCD
{
#ifdef LCD_4bit   
   //4 bit part
   LDP=(cmd&0b11110000);
   LCP|=1<<LCD_E;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   LDP=((cmd&0b00001111)<<4);   
   LCP|=1<<LCD_E;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
#else
   //8 bit part
   LDP=cmd;
   LCP|=1<<LCD_E;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);   
#endif
}
void LCDinit(void)//Initializes LCD
{
#ifdef LCD_4bit   
   //4 bit part
   _delay_ms(15);
   LDP=0x00;
   LCP=0x00;
   LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4;
   LCDR|=1<<LCD_E|1<<LCD_RW|1<<LCD_RS;
   //---------one------
   LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   //-----------two-----------
   LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   //-------three-------------
   LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|0<<LCD_D4; //4 bit mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   //--------4 bit--dual line---------------
   LCDsendCommand(0b00101000);
   //-----increment address, invisible cursor shift------
   LCDsendCommand(0b00001100);
      //init 8 custom chars
   uint8_t ch=0, chn=0;
   while(ch<64)
   {
      LCDdefinechar((LcdCustomChar+ch),chn++);
      ch=ch+8;
   }


#else
   //8 bit part
   _delay_ms(15);
   LDP=0x00;
   LCP=0x00;
   LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4|1<<LCD_D3
         |1<<LCD_D2|1<<LCD_D1|1<<LCD_D0;
   LCDR|=1<<LCD_E|1<<LCD_RW|1<<LCD_RS;
   //---------one------
   LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|0<<LCD_D3
         |0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   //-----------two-----------
   LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|0<<LCD_D3
         |0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   //-------three-------------
   LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|0<<LCD_D3
         |0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   //--------8 bit dual line----------
   LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|1<<LCD_D3
         |0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(1);
   //-----increment address, invisible cursor shift------
   LDP=0<<LCD_D7|0<<LCD_D6|0<<LCD_D5|0<<LCD_D4|1<<LCD_D3
         |1<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
   LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;      
   _delay_ms(1);
   LCP&=~(1<<LCD_E);
   _delay_ms(5);
      //init custom chars
   uint8_t ch=0, chn=0;
   while(ch<64)
   {
      LCDdefinechar((LcdCustomChar+ch),chn++);
      ch=ch+8;
   }

#endif
}         
void LCDclr(void)            //Clears LCD
{
   LCDsendCommand(1<<LCD_CLR);
}
void LCDhome(void)         //LCD cursor home
{
   LCDsendCommand(1<<LCD_HOME);
}
void LCDstring(uint8_t* data, uint8_t nBytes)   //Outputs string to LCD
{
register uint8_t i;

   // check to make sure we have a good pointer
   if (!data) return;

   // print data
   for(i=0; i<nBytes; i++)
   {
      LCDsendChar(data[i]);
   }
}
void LCDGotoXY(uint8_t x, uint8_t y)   //Cursor to X Y position
{
   register uint8_t DDRAMAddr;
   // remap lines into proper order
   switch(y)
   {
   case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
   case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
   case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
   case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
   default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
   }
   // set data address
   LCDsendCommand(1<<LCD_DDRAM | DDRAMAddr);
   
}
//Copies string from flash memory to LCD at x y position
//const uint8_t welcomeln1[] PROGMEM="AVR LCD DEMO\0";
//CopyStringtoLCD(welcomeln1, 3, 1);   
void CopyStringtoLCD(const uint8_t *FlashLoc, uint8_t x, uint8_t y)
{
   uint8_t i;
   LCDGotoXY(x,y);
   for(i=0;(uint8_t)pgm_read_byte(&FlashLoc[i]);i++)
   {
      LCDsendChar((uint8_t)pgm_read_byte(&FlashLoc[i]));
   }
}
//defines char symbol in CGRAM
/*
const uint8_t backslash[] PROGMEM=
{
0b00000000,//back slash
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000000,
0b00000000
};
LCDdefinechar(backslash,0);
*/
void LCDdefinechar(const uint8_t *pc,uint8_t char_code){
   uint8_t a, pcc;
   uint16_t i;
   a=(char_code<<3)|0x40;
   for (i=0; i<8; i++){
      pcc=pgm_read_byte(&pc[i]);
      LCDsendCommand(a++);
      LCDsendChar(pcc);
      }
}

void LCDshiftLeft(uint8_t n)   //Scrol n of characters Right
{
   for (uint8_t i=0;i<n;i++)
   {
      LCDsendCommand(0x1E);
   }
}
void LCDshiftRight(uint8_t n)   //Scrol n of characters Left
{
   for (uint8_t i=0;i<n;i++)
   {
      LCDsendCommand(0x18);
   }
}
void LCDcursorOn(void) //displays LCD cursor
{
   LCDsendCommand(0x0E);
}
void LCDcursorOnBlink(void)   //displays LCD blinking cursor
{
   LCDsendCommand(0x0F);
}
void LCDcursorOFF(void)   //turns OFF cursor
{
   LCDsendCommand(0x0C);
}
void LCDblank(void)      //blanks LCD
{
   LCDsendCommand(0x08);
}
void LCDvisible(void)      //Shows LCD
{
   LCDsendCommand(0x0C);
}
void LCDcursorLeft(uint8_t n)   //Moves cursor by n poisitions left
{
   for (uint8_t i=0;i<n;i++)
   {
      LCDsendCommand(0x10);
   }
}
void LCDcursorRight(uint8_t n)   //Moves cursor by n poisitions left
{
   for (uint8_t i=0;i<n;i++)
   {
      LCDsendCommand(0x14);
   }
}
//adapted fro mAVRLIB
void LCDprogressBar(uint8_t progress, uint8_t maxprogress, uint8_t length)
{
   uint8_t i;
   uint16_t pixelprogress;
   uint8_t c;

   // draw a progress bar displaying (progress / maxprogress)
   // starting from the current cursor position
   // with a total length of "length" characters
   // ***note, LCD chars 0-5 must be programmed as the bar characters
   // char 0 = empty ... char 5 = full

   // total pixel length of bargraph equals length*PROGRESSPIXELS_PER_CHAR;
   // pixel length of bar itself is
   pixelprogress = ((progress*(length*PROGRESSPIXELS_PER_CHAR))/maxprogress);
   
   // print exactly "length" characters
   for(i=0; i<length; i++)
   {
      // check if this is a full block, or partial or empty
      // (u16) cast is needed to avoid sign comparison warning
      if( ((i*(uint16_t)PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
      {
         // this is a partial or empty block
         if( ((i*(uint16_t)PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
         {
            // this is an empty block
            // use space character?
            c = 0;
         }
         else
         {
            // this is a partial block
            c = pixelprogress % PROGRESSPIXELS_PER_CHAR;
         }
      }
      else
      {
         // this is a full block
         c = 5;
      }
      
      // write character to display
      LCDsendChar(c);
   }

}


Vse tri. Test_lcd.c (moj main program), lcd_lib.h ter lcd_lib.c se nahajajo v isti mapi.

Build proess javi tole:

rm -rf TestLCD.o TestLCD.elf dep/* TestLCD.hex TestLCD.eep TestLCD.lss TestLCD.map
Build succeeded with 0 Warnings...
avr-gcc -I"C:\Documents and Settings\Gorazd\My Documents\TestLCD\." -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=12000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT TestLCD.o -MF dep/TestLCD.o.d -c ../Te
stLCD.c

../TestLCD.c:3: warning: return type of 'main' is not 'int'
avr-gcc -mmcu=atmega8 -Wl,-Map=TestLCD.map TestLCD.o -l -o TestLCD.elf
avr-gcc: TestLCD.elf: No such file or directory
make: *** [TestLCD.elf] Error 1
Build failed with 1 errors and 1 warnings...


Hvala za pomoč.

Avtor: jjakobKraj: Rakičan (Murska Sobota) PrispevekObjavljeno: Ned Feb 22, 2009 6:53 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:
void main(void)

popravi v
Koda:
int main(void)


Za drugo napako pa pripni makefile, tam imaš nekaj narobe nastavljeno.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Feb 22, 2009 6:56 pm    Naslov sporočila:  
----------------------------------------------------------------------------
1. popravil

2.

Koda:

###############################################################################
# Makefile for the project TestLCD
###############################################################################

## General Flags
PROJECT = TestLCD
MCU = atmega8
TARGET = TestLCD.elf
CC = avr-gcc

## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)

## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -std=gnu99     -DF_CPU=12000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Wl,-Map=TestLCD.map


## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature

HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings


## Include Directories
INCLUDES = -I"C:\Documents and Settings\Gorazd\My Documents\TestLCD\."

## Libraries
LIBS = -l

## Objects that must be built in order to link
OBJECTS = TestLCD.o

## Objects explicitly added by the user
LINKONLYOBJECTS =

## Build
all: $(TARGET) TestLCD.hex TestLCD.eep TestLCD.lss size

## Compile
TestLCD.o: ../TestLCD.c
   $(CC) $(INCLUDES) $(CFLAGS) -c  $<

##Link
$(TARGET): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET)
   avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@

%.eep: $(TARGET)
   -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0

%.lss: $(TARGET)
   avr-objdump -h -S $< > $@

size: ${TARGET}
   @echo
   @avr-size -C --mcu=${MCU} ${TARGET}

## Clean target
.PHONY: clean
clean:
   -rm -rf $(OBJECTS) TestLCD.elf dep/* TestLCD.hex TestLCD.eep TestLCD.lss TestLCD.map


## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)

Avtor: jjakobKraj: Rakičan (Murska Sobota) PrispevekObjavljeno: Ned Feb 22, 2009 7:15 pm    Naslov sporočila:  
----------------------------------------------------------------------------
target = (datoteka, v kateri imaš main)

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Feb 22, 2009 7:28 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Kam pa moram to napisati?

Avtor: jjakobKraj: Rakičan (Murska Sobota) PrispevekObjavljeno: Ned Feb 22, 2009 7:38 pm    Naslov sporočila:  
----------------------------------------------------------------------------
V 8. vrstico makefilea Confused

Predlagam ti kak drug makefile, ker je ta zelo nefleksibilno napisan. Recimo da poskusiš s tem v priponki, frekvenco, mcu, programator ... spremeni po svoji želji.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Feb 22, 2009 7:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hmmm Jakob. Hvala za vso ponujeno pomoč, sam kam pa naj dam tale makefile? V Isto mapo kot imam lcdtest.c ? In potem tudi za v naprej ga kar kopiram ali kako? Ali lahko kje to v AvrStudiu povem kam naj gre to gledat? Sorry, s tem res nisem še nikoli delal (razen da sem blinkal lediko).

Avtor: jjakobKraj: Rakičan (Murska Sobota) PrispevekObjavljeno: Ned Feb 22, 2009 8:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Makefile je datoteka, ki pravzaprav compilerju pove, kaj naj sploh naredi. V njej imaš ponavadi konfiguracijo mikrokontrolerja (frekvenca, tip), compilerja (poti, optimizacija), ...
Za vsak projekt imaš svoj makefile, v projektni mapi poleg vseh programskih datotek. Nima smisla imeti en skupen makefile.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Feb 22, 2009 8:16 pm    Naslov sporočila:  
----------------------------------------------------------------------------
No, sem skopiral tvoj Makefile v mapo, kjer imam ta projekt, pa še vedno ne skompajlira...

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Feb 23, 2009 7:24 am    Naslov sporočila:  
----------------------------------------------------------------------------
RGorazd: Očitno imaš isto knjižnico kot jaz.

1. Inkludaš jo takole:


#include <avr/io.h>
#include <util/lcd_lib.c>
#include <util/delay.h>
#include <avr/interrupt.h>


2. mislim, da se ravno pri uporabi te knjižnice mora v Project/Configuration options/custom options v desno okence dodati tekst (stikalo) -std=gnu99. To ima nekaj veze z verzijami C jezika

3. makefile izvoziš v tisto mapo, kjer imaš projekt.

4. EDIT: ali imaš uporabljen pravi port za povezavo z LCDjem? V defaultu je v tej knjižnici uporabljen PORTB, mogoče pa tvoj AVR tega nima...

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Pon Feb 23, 2009 7:46 pm    Naslov sporočila:  
----------------------------------------------------------------------------
No, sedaj mi je ratalo zadevo skompajlirat. Sedaj pa grem lcd.h popravljat na moj moj harware. Upam, da mi ne bo spet žrlo živcev. Hvala vsem trem za pomoč!

LP G

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Pon Feb 23, 2009 10:09 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Evo mene! S cel kup novimi problemi...

A mi lahko kdo razloži kje ga biksam. Sedaj mi kodo pravilno prevede, vendar se na displeju ne dogaja kaj dosti (razen tega da je tiho tudi ničesar ne prikazuje).

Tu je lcd.h

Koda:

#define LCD_PORT         PORTD        /**< port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN    7            /**< pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    6            /**< pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    5            /**< pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    4            /**< pin for 4bit data bit 3  */
#define LCD_RS_PORT      LCD_PORT     /**< port for RS line         */
#define LCD_RS_PIN       1            /**< pin  for RS line         */
#define LCD_RW_PORT      LCD_PORT     /**< port for RW line         */
#define LCD_RW_PIN       2            /**< pin  for RW line         */
#define LCD_E_PORT       LCD_PORT     /**< port for Enable line     */
#define LCD_E_PIN        0            /**< pin  for Enable line     */



Jaz imam razpored za LCD takle (testna plata doma narejena in sem LCD priključil prek enega DIP Switcha na PORTD od ATmega8 (ostale periferije se na tem portu najmanj uporablja).

Signal E = Portd.0
Signal RS = Portd.1
Signal R/W = GND
Signal DB4 = Portd.7
Signal DB5 = Portd.6
Signal DB6 = Portd.5
Signal DB7 = Portd.4

LCD je priklopljen v 4 bitnem I/O načinu...

Koda vsebuje samo inicializacijo, brisanje LCDja ter izpis stringa...nič drugega zaenkrat...pa še to ne dela...

Aja, v lcd.h imam pravilno nastavljeno frekvenco kristala in ostale parametre...

Hvala za pomoč

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Feb 24, 2009 8:18 am    Naslov sporočila:  
----------------------------------------------------------------------------
Očitno imam malce drugačno knjižnico kot ti. V moji je malce lažje razumljiva nastavitev izhodov. Poglej v priponko.

dobil sem jo pa nekje tukaj

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Sre Feb 25, 2009 10:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
No, s pomočjo Lojszek-a (hvala) sem uspel priti do te stopnje, da mi ukazi kot so LCDclr();LCDhome(); in LCDcursorOnBlink(); delujejo. Ko pa hočem izpisati kak karakter ali string se pa ne zgodi nič. (s hardverom je vse OK, saj mi na hitro spisan program v Bascomu normalno izpisuje na LCD);

Drugo vprašanje pa je v zvezi s samim Build-om in sicer:

Ko tole kodo:

Koda:

#include <lcd_lib.c>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>

int main(void)
   {

DDRB=0xff;
PORTB = 0x02;
LCDinit();   
LCDclr();
_delay_ms(1000);
LCDhome();
LCDcursorOnBlink();
LCDstring("Adijo World",12);

_delay_ms(1000);   
   while (1)
      {
      PORTB = ~PORTB;
      _delay_ms(500);            
      
      }

   }


prevedem, mi kot warning javi tole:

../Lcd_lojzek.c:17: warning: pointer targets in passing argument 1 of 'LCDstring' differ in signedness


Če pa stistnem še enkrat Build, pa tega opozorila ni več. A je mogoče tudi to, da je to opozorilo vir mojih težav?

Pa še to, a je potrebno F_CPU definirati samo tam v tistem "Configuration options" ali je to potrebno po vseh knjižnicah spremeniti?

Muči me dejstvo, da ko hočem simulirati v AvrStudiu skompajlirano kodo, mi tam ob strani piše, da je moj clock 4Mhz....

Hvala za pomoč.

Avtor: Sokrat PrispevekObjavljeno: Sre Feb 25, 2009 11:46 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Tale tema je odlicen primer zakaj se za take reci napise svoje knjiznice ... v vsem tem casu, ki si ga zapravil doslej z iskanjem napak, ki jih je morda zagresil nekdo drug, bi imel izpis na LCD ze 10x narejen.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Sre Feb 25, 2009 11:52 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sokrat res maš, vendar ta knjižnica deluje, tako Lojzku kot še komu drugemu...Problem je v mojem nepoznavanju okolja. S tem še nisem delal, s Cjem se še nisem dajal...to je zame vse "novo"... Silvotov primer pisanja na LCD v assemblerju mi je bil precej jasen in mi je z malo njegove pomoči in malo mukami celo ratalo spraviti v življenje, zdaj me zanima pa, kako se to dela v Cju, ker je to moj naslednji korak.

Avtor: upornikKraj: Celje PrispevekObjavljeno: Sre Feb 25, 2009 11:54 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Se strinjam s tem. Pa še več se naučiš pri pisanju svoje knjižnice in večje zadovoljstvo imaš. Je pa dobro shranjevati na varno mesto, kajti sam sem jo že enkrat pomotoma izbrisal Laughing

Avtor: Sokrat PrispevekObjavljeno: Čet Feb 26, 2009 12:01 am    Naslov sporočila:  
----------------------------------------------------------------------------
RGorazd je napisal/a:
Silvotov primer pisanja na LCD v assemblerju mi je bil precej jasen in mi je z malo njegove pomoči in malo mukami celo ratalo spraviti v življenje, zdaj me zanima pa, kako se to dela v Cju, ker je to moj naslednji korak.


Saj ni nic druagce - tlacis vrednosti v registre in to je to. Lazje je toliko, ker iams elemente visjenivojskega jezika, s katerim je precej bolj pregleno pisanje zank, preverjanja pogojev, vejitev ...

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Feb 26, 2009 7:14 am    Naslov sporočila:  
----------------------------------------------------------------------------
Rgorazd, morebiti bi pred tem ukazom
Koda:
LCDstring("Adijo World",12);

dodal še tole:
Koda:
LCDGotoXY(0,0);


Mogoče piše nekam, kjer ti ne vidiš.

Je pa res, tista opozorila javlja tudi meni, pri ponovnem kompiliranju jih ni. Glavno mi je, da stvar deluje. Smile

Prav tako je pa res, da z malce podlage lahko sam narediš knjižnico. Včasih je to celo lažje kot že narejena (tak primer je pisanje v eeprom - vsaj zame)

Avtor: tadej.ko2Kraj: sveta trojica PrispevekObjavljeno: Sob Mar 07, 2009 3:09 am    Naslov sporočila:  ne čisto začetniški problem
----------------------------------------------------------------------------
po zgledu http://www.faro.si/primer1.htm sem začel pisati program za AtTiny26.
program bi bil že nared, če mi nebi ponagajala bugica, ki je ne znam najti.

program deluje tako: ob pritisku na t1 ali t2 se postavi zastavica vklop1 ali vklop2, preko katere se potem v intervalu dt (spremenljivka iz programa) prižigajo naslednje ledice. če pritisneš t1, grejo ledice z ene strani, če t2 pa z druge.
ob vsakem prižigu se postavi tudi bit na določenem mestu v spremenljivki bitstack (ta spremenljivka je verjetno vzrok težav), prav tako pa se tudi shrani čas vklopa določene luči v array vklop.
nato je spodaj še en if, ki po pretečenem času "clock - vklop[k] > interval" izklaplja ledice.
problem je pa z led0, ki se noče ugasniti.

stvari so priklopljene na čip tako, kot so navedene v definicijah, oscilator je interni 1M. l1 in l2 sem uporabil kot izhoda, da sem preveljal spremenljivko bitstack (vrstice na koncu programa), tipko t3 pa za preklop opazovane veličine. te 3 veličine ne igrajo vloge v jedru programa.

upam da bi mi kdo znal razložiti to misterijo. kot pravim, sam sumim spremenljivko bitstack, vendar Think

Avtor: tadej.ko2Kraj: sveta trojica PrispevekObjavljeno: Ned Mar 08, 2009 12:46 pm    Naslov sporočila:  
----------------------------------------------------------------------------
zgoraj opisani problem (mojo napako) sem rešil! misterije v računalništvu pač ne obstajajo Mr. Green
težavo mi je delalo moje nebriljantno poznavanje c-ja: 2^k sem pričakoval, da mi bo vrnilo k-to potenco števila 2 Whistle

dodal sem funkcijo ter na vseh mestih 2^k zamenjal z potenca(2,k). stran gredo tudi vsi obupani poskusi parsanja: i==0?(short)1:(short)2^i .

funckija:

unsigned long potenca(char osnova, char pot);
unsigned long potenca(char osnova, char pot)
{unsigned long rez = 1;if(pot > 31) return 0; while(pot-- > 0) rez *=osnova;return rez;}

lp

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Mar 09, 2009 7:16 am    Naslov sporočila:  
----------------------------------------------------------------------------
Tista ^ v Cju pomeni nekaj drugega. In sicer bitni XOR na tistih številkah, ki si jih napisal okoli znaka.

drugače pa: 2^n je samo shiftanje bitov v spremenljivki za n bitov v levo.

Avtor: domen_puncerKraj: Ljubljana, Mozirje PrispevekObjavljeno: Ned Mar 15, 2009 6:57 pm    Naslov sporočila:  
----------------------------------------------------------------------------
x<<n je shiftanje za n bitov v levo.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Ned Mar 15, 2009 8:51 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Smile Hotel sem omeniti, da 2 na nekaj (2^n) je dejansko shiftanje bitov v levo za n mest. Nisem pisal odgovora sintaktično, ampak pomensko.

Avtor: dkoneKraj: Krško PrispevekObjavljeno: Čet Mar 26, 2009 6:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni!

Imam naslednji program:

Koda:


#include <tiny2313.h>
#include <delay.h>
#define tipka PIND.1;

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Func2=In Func1=In Func0=In
// State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port D initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
zanka1:
stevec=0;
PORTB.1=0;
while (1)
      {
      delay_ms(100);
      if(tipka==0)
      {
        goto zanka2;
      }
   
      };
     
zanka2:
while(1)
        {
        goto zanka1;
        };
     
}


ki z tipko skakam iz ene zanke v drugo,res da ne dela nič pametnega ampak se mi ustavi pri if(tipka==0){....},saj mi compiler javla napako:

Error: F:\vaja c\vaja.c(180): missing ')'
Error: F:\vaja c\vaja.c(180): invalid expression

Torej kaj je narobe?

Če dam pa namesto direktive tipka,pind.1,pa mi skompajla brezproblema.

V Bascomu nisem imel težav.

tipka alias pind.1
set tipka
if tipka=0 then
.
.
.
end if

Avtor: domen_puncerKraj: Ljubljana, Mozirje PrispevekObjavljeno: Čet Mar 26, 2009 7:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Oh, my... grozna koda Razz

Problem je v
Koda:
#define tipka PIND.1;


Prav je brez podpicja,
Koda:
#define tipka PIND.1
, ker drugače ti zamenja v
Koda:
if (PIND.1;==0) {
.

Za kakšne bolj komplicirane preprocessor težave je uporabnen gcc -E, če seveda uporabljaš gcc.[/code]

Avtor: dkoneKraj: Krško PrispevekObjavljeno: Pet Mar 27, 2009 11:19 am    Naslov sporočila:  
----------------------------------------------------------------------------
domen_puncer je napisal/a:
Oh, my... grozna koda Razz

Problem je v
Koda:
#define tipka PIND.1;


Prav je brez podpicja,
Koda:
#define tipka PIND.1
, ker drugače ti zamenja v
Koda:
if (PIND.1;==0) {
.

Za kakšne bolj komplicirane preprocessor težave je uporabnen gcc -E, če seveda uporabljaš gcc.[/code]



Vem,da je grozna,nekako "prehajam" iz bascoma na CV,zato toliko pravopisni napak.Ampak,sedaj ko sem odstranil ;,pa mi prevede. Hvala ti. Sedaj grem pa naprej,v dopolnitev.

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Ned Apr 05, 2009 12:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
pozdravljeni!
eno začetniško vprašanje:

v codeVision sem poskušal sprogramirat ATTiny26, vendar mi javi neko napako (program seveda ne dela) kopiral sem to kodo.

lahko, da sem kakšno neumno napravil, ker je to prvič.

Avtor: domen_puncerKraj: Ljubljana, Mozirje PrispevekObjavljeno: Ned Apr 05, 2009 3:48 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Preden lahko sprogramiras uC, se ti mora sploh skompajlat.
Izgleda uporabljaš 'delay_ms', ki ga nisi definiral.

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Ned Apr 05, 2009 6:31 pm    Naslov sporočila:  
----------------------------------------------------------------------------
bi si lahko kdo prosim vzel čas, da mi napiše program(enostaven-LED), ki bi deloval na ATtiny26, samo da zadevo "sprobam"? Pray Jutri si grem sposodit revije SE, da preberem članke od VolkD-ja.

lp

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Tor Apr 07, 2009 6:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Enako mi napiše s programom, ki preverjeno deluje (flowcode AVR)! d'oh!
Mi lahko kdo razloži postopek, kako sprogramirati AVR v CVAVR? Pray



lp

Avtor: seariderKraj: Maribor PrispevekObjavljeno: Pet Maj 01, 2009 7:03 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni,

lotil sem se C-ja na atmega8 in naletel na mnogo težav. Namreč na netu je mnogo izvornih kod, ko pa jo hočeš skompalirat, pa napake kot po tekočem traku. Bi lahko kdo priporočal kakšen dober link, kjer bi bilo razloženo na kaj paziti, da se to ne dogaja. Ker eni uporabljajo ene knjižnice, drugi druge in prihaja do totalne zmede (vsaj začetniku se tako zdi). Uporabljal sem AVRStudio in WinAVR.


Lp

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Jul 17, 2009 1:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ponovno eno vprašanje predem naredim kaj trapastega:

Ali se v WinAvr asemblerska komanda v C programu vključi takole:
Koda:
asm ("sleep");


Očitno je, da gre za spravljanje procesorja v spanje. Seveda sem potrebne registre že prej obdelal - MCUCR.
Sprašujem zato da vem, če jo uC sploh izvede (pri prevajanju namreč ni bilo težav).

Avtor: spyKraj: Tržič PrispevekObjavljeno: Sob Jul 18, 2009 12:12 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pravilno.
In tudi v simulatorju (klik na asembler okno) boš videl, da se prevede v ukaz "sleep".

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Sep 01, 2009 6:58 am    Naslov sporočila:  
----------------------------------------------------------------------------
Spet jaz Angel

Na mikrokontroler bi rad priključil barcode reader. No, to sem že naredil in tudi berem podatke. Edinole podatki so malce nerazumljivi- niso takšni, kot bi jih pričakoval.
To pa zato, ker očitno nisem dobro dešifriral komunikacije. Zato bi se rad lotil dešifriranja celotnega komunikacijskega protokola.

Torej, rad bi "ujel" celotno besedo, ki jo scaner pošlje v mikrokontroler. Se pravi z vsemi enicami in ničlami. Kakšen način moram uporabiti, da bi ujete črke spravil v neko veliko spremenljivko v mikrokontrolerju? To bi potem mirno preko USARTa spravil na PC in dešifriral. Če to namreč počenjam sproti, se mi del prejetih podatkov izgublja in dobim ven garbage.
Kakšno vrsto spremenljivke bi moral uporabiti, mogoče podprto tudi s kakim primerom.
Pišem pa v WinAvr.

Avtor: Sokrat PrispevekObjavljeno: Tor Sep 01, 2009 8:29 am    Naslov sporočila:  
----------------------------------------------------------------------------
To se ne dela tako, razen ce si mazohist.

Napisi, kaj ze ves o komunikaciji (torej katere podatke ze imas), ker se odgovor od tukaj naprej razlikuje glede na to, vsega pa nimam volje nastevati.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Sep 01, 2009 9:32 am    Naslov sporočila:  
----------------------------------------------------------------------------
d'oh! Saj sem res nerazumljivo napisal.

Torej, imam PS/2 komunikacijski protokol. Barcode reader ob prebrani kodi pošlje vlak signalov, ki jih prejme mikrokontroler. In iz tega bi zelo rad dobil tak podatek, kot je zapisan ob črtni kodi (številka 49776).
Namesto tega pa sedaj dobim garbage. Ta 49976 zgleda recimo takole: %p%FpFFpF=p=6p6

Ko sem pospešil USART komunikacijo (sem medtem tudi ugotovil, da to ni bilo potrebno) in namesto skenerja priklopil navadno tastaturo, sem ugotovil, da je vsak znak - številka v odčitku predstavljena s tremi znaki. Recimo št. 4 je %p%.
Kar pa je že manj garbage. Edinole še dešifrirat jih potrebujem.

Pomagal sem si s tole stranjo, ampak očitno se ne pošilja samo 8 bitni podatek (domneval sem, da se pošilja ASCII) in torej vse na tej strani ne drži.
Te trimestne znake bi rad predstavil na razumljiv način kot številke in črke.
Bom še malce sam poizkušal, ko se zataknem, bom pa spet tu Very Happy

Avtor: Sokrat PrispevekObjavljeno: Tor Sep 01, 2009 10:08 am    Naslov sporočila:  
----------------------------------------------------------------------------
Aha, zdaj je vse jasno - saj ti cisto lepo deluje. Ker nisi prebral opisa protokola, si mi dolzan :lasko: !

-=-=-=-=-=-=-=-=-=-

Teorija:

Scanner emulira PS.2 tipkovnico.

Tipkovnica poslje dve kodi za (skoraj) vsako tipko: eno za pritisk, eno za od-pritisk.

Koda za od-pritisk tipke je enaka kodi za pritisk, le da ima spredaj se prefix 0xF0.

Vse stevilske tipke imajo za pritisk enomestno kodo.

-=-=-=-=-=-=-=-=-=-

Praksa:

Ti imas kodo %p%FpFFpF=p=6p6, ki se razdeli na

% p% (pritisk 4, od-pritisk 4)
F pF (9, od-9)
F pF (9, od-9)
= p= (7, od-7)
6 p6 (6, od-6)

Opazis kaksen vzorec ? Wink

Ves kje sem doma, tako da le urno s pivom Dancing

Pa ce bos operiral s stevilskimi kodami, bo vse precej manj zmedeno, ker ti vsakic sproti kodna tabela doloca v kaj se vrednost prevede (v kateri znak).

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Sep 01, 2009 10:32 am    Naslov sporočila:  
----------------------------------------------------------------------------
Aha, še veliko jasneje. Ker ko sem poizkušal s tastaturo in tipko držal, se je pojavljal samo en znak namesto treh, na koncu pa tisti dvojni. Sedaj moram torej samo še ugotoviti, kje sem ga pobiksal v rutini za branje. Sem jo namreč od prvotne (za katero sedaj celo mislim, da je delala), že precej spremenil.

Pivo bo pa takrat, ko se pripeljem mimo Smile

Avtor: Sokrat PrispevekObjavljeno: Tor Sep 01, 2009 10:41 am    Naslov sporočila:  
----------------------------------------------------------------------------
Naredi tako, da ti uposteva kodo samo, ce ji sledi koda za od-pritisk (scanner jih bo vedno posiljal tako, kot ce bi pritiskal po eno tipko naenkrat), saj bos tako izlocil morebitne napake v komunikaciji. Ko imas obe kodi, pretvoris v vrednost (tekst ali stevilko) in to odposljes naprej oz. obdelujes, kar je pac potrebno.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Nov 26, 2009 7:42 am    Naslov sporočila:  
----------------------------------------------------------------------------
Tole postaja počasi že moja tema Smile

Imam težave z deklaracijo in klicanjem funkcije.

v headerju imam funkcijo deklarirano takole:

void Funkcija (uint_16t);

Mislim da imam problem v tem, ker jo ne kličem s pravimi podatki.
Med testiranjem sem jo klical samo z int podatki (in ni bilo errorjev pri prevajanju), sedaj pa jo včasih pokličem s char podatkom.
Torej vprašanje: ali lahko v spremenljivko tipa int vpišeš char? Recimo takole
Koda:
int a;
char b;

a = b;

Avtor: gumby PrispevekObjavljeno: Čet Nov 26, 2009 8:06 am    Naslov sporočila:  
----------------------------------------------------------------------------
Lahko.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Nov 26, 2009 8:17 am    Naslov sporočila:  
----------------------------------------------------------------------------
Aha. Torej imam problem nekje drugje Think

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Dec 11, 2009 7:49 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ta tema je vedno bolj moja. Izgleda da imam samo jaz probleme Very Happy

Imam eno vprašanje oz. potrditev mojega mišljenja:

V tem postu sem omenil težave z "izostajanjem sekund".

Mislim, da sem rešitev našel, vseeno me pa zanima, če mislim prav:
Če imam v programu dve časovni prekinitvi (ena takt iz omrežja, druga lastni takt), kaj se zgodi, ko se med izvajanjem ene prekinitve zgodi tudi druga? Po moje uC začne izvajati drugo prekinitev in ko jo zaključi, nadaljuje zopet v glavnem programu. Na zaključitev prve prekinitve pa pozabi.

Ali imam prav? Think

Avtor: gumby PrispevekObjavljeno: Pet Dec 11, 2009 8:23 pm    Naslov sporočila:  
----------------------------------------------------------------------------
c/p iz datasheeta za mega8:
Citiram:
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed.


Tebi je takt iz omrežja zelo pomemben, saj ti ta določa točnost ure. Ta naj ima najvišjo prioriteto.

Splošno pa velja, da naj bodo prekinitvene rutine zelo hitre (npr. samo poveča nek števec, postavi nek flag, itd). Uporaba delay() in podobnih funkcij znotraj prekinitev je zelo slaba ideja.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Dec 11, 2009 10:46 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala lepa za info. Čeprav ni točen odgovor na vprašanje, vsaj vem, kje ga poiskat Wink

Avtor: gumby PrispevekObjavljeno: Pet Dec 11, 2009 10:57 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Nimaš prav, če si hotel direkten odgovor. Po končanju druge prekinitve se vrne v prvo in po končanju te v glavni program.

"nested interrupt" je tisto, kar te zanima (torej prekinitev med prekinitvijo)...

Za hec daj 100ms zakasnitev v prekinitveno rutino in opazuj, kako se bo program obesil, ker se nikoli ne bo vrnil iz nobene prekinitve (ta se zgodi na vsakih 10 ali 20 ms)

Avtor: osmicaKraj: savinjska PrispevekObjavljeno: Pon Dec 28, 2009 10:39 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Iz te teme sem iz programov, ki so napisani izdelal tale program za štetje stiskov na tipko ozioma vsakih 800 mS šteje za eno. Vse mi prevede OK vendar mi ne šteje več kot do 01. Prosim za pomoč, kje je napaka?
Koda:
#define F_CPU 1000000
#include <avr\io.h>
#include <util\lcd_lib.c>
#include <util\delay.h>


volatile unsigned char  e, d;
volatile unsigned char val;

int main (void)
{

DDRA=0xff;
DDRB=0x01;

LCDinit ();
LCDclr ();
LCDcursorOFF();
LCDGotoXY(2,0);   //postavi se na pozicijo
LCDstring ("dela ",5);

void izracun()
   {
     e=val/10;   //enice
     e=e*10;
     e=val-e;

     val=val/10;   //desetice
     d=val/10;
     d=d*10;
     d=val-d;
    }
;
val=0;
while (1)
{
 if (PINB &0X01)
 {
  ++val;
   
   izracun();
   LCDclr ();
   LCDGotoXY(2,0);
   LCDsendChar (d+48);
   LCDsendChar (e+48);
  _delay_ms(800);
  };
 }   
}


Za vsak ukaz LCDstring mi napiše opozorilo: warning: pointer tragets in passing argument 1 of 'LCDstring ' differ in signedness
vendar ko sem se igral z LCDju je delalo vse OK.
Hvala za pomoč

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Pon Dec 28, 2009 11:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Opozorilo ti javlja, ker je verjetno vhod v funkcijo definiran kot navaden - se pravi signed - char. V tem primeru nič hudega, će uporabljaš ti unsigned char.

A drugače ti pa za funkcijo znotraj funkcije ne javlja napake?


LP!

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Tor Dec 29, 2009 12:29 am    Naslov sporočila:  
----------------------------------------------------------------------------
Kadar ti kaj ne deluje, poskusi simulirati delovanje programa.
Koda:
val=val/10;   
1/10=0; 0++=1...

Zakaj je cela funkcija Izracun() v Main() ? Na ta način se ti Izracun() prvič izvrši, še preden program pride do while zanke.

Avtor: osmicaKraj: savinjska PrispevekObjavljeno: Tor Dec 29, 2009 11:19 am    Naslov sporočila:  
----------------------------------------------------------------------------
Napako zakaj šteje samo do 01 sem ze našel- problem je ker val se obdeluje v izračunu in na koncu izračuna je stanje val=0. Dodal sem novo spremenljivko katera se povečuje vsak pritisk na tipko oz 800mS, na začetku izračuna se stanje nove spremenljivke "prenese" v val. Sedaj dela.

Avtor: osmicaKraj: savinjska PrispevekObjavljeno: Tor Dec 29, 2009 11:33 am    Naslov sporočila:  
----------------------------------------------------------------------------
chaos je napisal/a:
Opozorilo ti javlja, ker je verjetno vhod v funkcijo definiran kot navaden - se pravi signed - char. V tem primeru nič hudega, će uporabljaš ti unsigned char.

A drugače ti pa za funkcijo znotraj funkcije ne javlja napake?


LP!


Javi mi samo opozorilo vedno, ko uporabim ukaz LCDstring, neglede kje je .

Avtor: IgorrKraj: Ljubljana PrispevekObjavljeno: Sob Jan 02, 2010 11:14 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Napisati moram program za Atmel Tiny 2313 (v AVR Studiu), ki ob aktivnem vhodu D1 glede na stanje vhoda D0 pošlje eno izmed naprej določenih kod na izhod B1.

Bi bilo to pravilno: ?

Koda:
#include <avr/io.h>
#include <avr/delay.h>

int main (void)
{
   DDRB = 0x00;       //B --> output
   DDRD = 0xff;       //D --> input
   
   char i;
   char x,y;
   char koda_a[] = {1,0,1,0};   //koda A, ki se poslje ob neaktivnem D0
   char koda_b[] = {1,0,0,1};  //koda B, ki se poslje ob aktivnem D0

   while(1)
   {
         x = PIND & 1;   // x = vrata D, pin 1
      
         if (x)
      {
         y = PIND & 0;   // y = vrata D, pin 0
         
         if(y)   //ce je D0 aktiven
         {
            for (i=0;i<4;i++)
            {
               PORTB = koda_a[i];      //izhod B_1 glede na kodo A (ostali niso pomembni in se lahko povozijo)
            }
         }
         else   // ce D0 ni aktiven
         {
            for (i=0;i<4;i++)
            {
               PORTB = koda_b[i];      //izhod B_1 glede na kodo B
            }
         }
      }
   }
   return 1;
}



Kako napisati kodo za sprejemnik, ki bi neprekinjeno poslušala izbrano nožico (recimo B_1) in bi ob pravi kodi aktivirala izhod (recimo D_1)? Pravilni podatki bi prišli na vhod zelo redko (cca. 1x na 10 sekund) in vmes bi lahko prišel kakšen naključen signal (motnja).

Hvala. Smile

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Jan 04, 2010 7:45 am    Naslov sporočila:  
----------------------------------------------------------------------------
Jaz v AVR Studio za preverjanje stanja bita na nekem portu (ali pa tudi v spremenljivki) uporabljam:
Koda:
if (bit_is_set (PORTB, 5));
if (bit_is_clear (PORTB, 5));

Namesto PORTB lahko daš tudi kako spremenljivko- zastavico, ali katerega od statusnih registrov.
Mi je tako lažje razumljivo kot z maskiranjem.

Glede tistega LCDString: uporabljaš verjetno isto LCD knjižnico kot jaz. To tudi meni vedno javi, ampak dela b.p. Če pa prevedeš dvakrat, ti v drugo ne javi več napake...

Zadnje vprašanje: Motenj se boš pa moral na nek način znebiti. Ker drugače ti bo tudi motnja sprožila tvoj del programa. Drugače pa lahko procesor na pravi signal brez problema čaka tudi 5 let. Tako da 10s ni težava.

Avtor: gregoralKraj: Ljubljana PrispevekObjavljeno: Pon Jan 04, 2010 2:34 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
Če pa prevedeš dvakrat, ti v drugo ne javi več napake...


Mislim da je tukaj potreben komentar.
Pri prevajanju programske kode se večinoma uporablja optimizacija. Tako prevajalnik prevaja samo tiste datoteke ki so se spremenile od zanjega prevajanja. (Upošteva se modified date time).

Torej če prevedeš dvakrat to še ne pomeni da je napaka čudežno izginila. To je samo znak da prevjalnik ni ponovno prevajal datoteke.

LP, Gregor

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Sre Jan 06, 2010 10:10 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni!
Uporabljam AVR Studio 4 in WinAVR. Imam probleme s timerji. V tej temi je na 2. strani podan primer kode "utripanja" PORTB-ja:

Koda:

#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned char delay;


/**********************      prekinitev timerja 0    **********************/

SIGNAL(SIG_OVERFLOW0)   // signal handler for tcnt0 overflow interrupt
 {
  TCNT0 = 61;      // 50 ms @ 4M
  ++delay;
 }


int main(void)
{
 DDRB = 0xff;
 
 TIMSK = 0x02;      // enable TCNT0 overflow
 TCNT0 = 61;      // 50 ms @ 4M
 TCCR0 = 0x05;      // count with cpu clock/1024
 
 sei();            // enable interrupts
 
 
  while (1)
   {
    if (delay==20)   // 1 sek   
    {
     delay=0;
     PORTB ^= 0xff;
    }

   }
 }



Kodo mi pravilno prevede, ko pa zapečem na Atmega16, LEDice na PORTB ne utripajo. Preizkusil sem že nekaj primerov kod z uporabo timerjev, pa je vedno ista pesem. Mi lahko kaj svetujete?

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Sre Jan 06, 2010 11:06 am    Naslov sporočila:  
----------------------------------------------------------------------------
Se mi je zdel nekam znan primer programa.

Ta primer sem prenesel iz Attiny2313, kjer je prikinitev Timerja0 omogočena z bitom 1, pri Atmega16 pa je z bitom 0, zato poskusi takole:

TIMSK = 0x01; // enable TCNT0 overflow

Pri AVR-jih so specialni biti v registrih med seboj pomešani glede na tip mikrokrmilnika, zato je potrebno biti na to pozoren.

Lp, Silvo

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Jan 06, 2010 11:47 am    Naslov sporočila:  
----------------------------------------------------------------------------
Če smem še dodati k Silvotovem odgovoru:

Čeprav so si Atmelovi krmilniki med seboj podobni, se lahko med njimi razlikujejo tudi imena registrov in imena ter lokacije zastavic v registrih.

Z izkušnjami sem ugotovil, da je mogoče lažji "prenos" programov iz enega v drug krmilnik z uporabo imen registrov in zastavic. Za tvoj primer bi to izgledalo nekako takole:
Koda:
TIMSK |= (1<< TOIE0);  // enable TCNT0 overflow


Tako hitreje in lažje veš, s katerim registrom/zastavico delaš, pa če program prevajaš za drug krmilnik, ki mogoče nima enakih imen, bo prevajalnik takoj zacvilil. Če pa ima zastavica enako ime samo drugo lokacijo (tvoj primer), bo prevajalnik to že sam uredil.
Enako bi lahko postavljal bite v registru TCCR0... in v vseh ostalih registrih.

PS: TOIE0 je ime dotične zastavice pri megi8...

EDIT: vsa imena zastavic so napisana v datasheetu ob razlagi posameznega registra...

Branko

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Sre Jan 06, 2010 2:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Najprej hvala obema za odgovor!

Ojej...ja to sem se pa res zmotil, oz. nisem pregledal, če je treba kaj spremeniti. Brick wall
Sem sedaj popravil TIMSK register, ampak še vedno ni nič na PORTB.
Je še kak drug možen "hakelc"?

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Sre Jan 06, 2010 10:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Branko,
zelo lepo si me dopolnil, tudi jaz ponavadi uporabljam način, kot si ga opisal, za primer pa se mi je zdelo bolj pregledno tako kot sem zapisal.

Samo,
primer programa preverjeno dela na Atmega8515, ATmega16 pa nimam pri roki, a sem ga preizkusil v simulatorju, kjer dela.

Ali imaš v Project Options izbran ATmega16?

Lp, Silvo

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Sre Jan 06, 2010 10:22 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Silvo prav si imel. Sem šel še enkrat preverit in sem imel res nastavljeno na Atmega128 namesto Atmega16. Najbrš sem ponesreči prestavil, ko sem z miško kaj "scrollal" in je bilo ponesreči to okno označeno. To se mi večkrat naredi Smile Važno, da sedaj deluje!
Hvala za pomoč!

Avtor: clownfishKraj: Povir / Ljubljana PrispevekObjavljeno: Pet Jan 08, 2010 1:27 am    Naslov sporočila:  
----------------------------------------------------------------------------
Imam težavo z prenosom kode iz WIN-AVR na ICC AVR.

koda na strani:
http://winavr.scienceprog.com/example-avr-projects/avr-lcd-menu-routine.html

se sicer prevede, težava nastopi v vrstici

FPtr=(FuncPtr)pgm_read_word(&FuncPtrTable[MFIndex(MN.menuNo, MN.subMenuNo)]);

natančneje je problem v: pgm_read_word

kot sem gledal(WIN-AVR) gre za makro, ki prebere iz naslova flash-a 1Word - naslov..
Kako to definiram v ICC-AVR C prevajalniku?

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Ned Feb 21, 2010 9:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
Evo, sem se še jaz malo lotil teh AVR-jev in napisal prvi program, ki "pomika" LED levo in desno na PORT. Potem sem stvar še malo zakompliciral in sem dodal dve tipki (dodal dva pogojna stavka-ostala koda je ostala ista).
V primeru, da je pritisnjena tipka na PORTB.1 naj LED potuje v levo, če je pritisnjena PORTB.2 naj LED potuje v desno, če ne, pa naj vse LED gorijo.
Koda:
int pb = PINB;

   while(1)
   {

   int pb = PINB;

      if (pb==0xFD)
      {
      for(int i = 1; i <= 128; i = i*2)

      {

      PORTD = i;
      _delay_loop_2(30000);

      }
      }

      else if (pb==0xFB)
   
      {
      for(int i = 128; i >1; i -= i/2)
      {

      PORTD = i;
      _delay_loop_2(30000);

      }

      }
      else
      {
      PORTD = 0xFF;
      }
   }

   return 1;




}


Problem je, ker ko je pritisnjena PORTB.2 se LED pomikajo v desno, vendar le do predzadnje. Zadnja se ne prižge. Prej se je prižgala (brez tipk).

Sem še začetnik, zato morda ne vidim očitne napake...
Vidi kdo, kaj je narobe?


lp, Jernej

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Ned Feb 21, 2010 6:01 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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!

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Ned Feb 21, 2010 8:54 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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!

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Ned Feb 21, 2010 9:14 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mogoče takole:

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


Lp

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Ned Feb 21, 2010 9:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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")?

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Pon Feb 22, 2010 4:51 am    Naslov sporočila:  
----------------------------------------------------------------------------
strcmp.

LP!

Avtor: gumby PrispevekObjavljeno: Pon Feb 22, 2010 8:03 am    Naslov sporočila:  
----------------------------------------------------------------------------
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[].

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Pon Feb 22, 2010 8:19 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Eto, sem naredil s strcmp(). Hvala!

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Sob Mar 13, 2010 7:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ž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?

Avtor: gumby PrispevekObjavljeno: Sob Mar 13, 2010 8:37 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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...

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Sob Mar 13, 2010 8:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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).

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Ned Mar 14, 2010 1:52 pm    Naslov sporočila:  
----------------------------------------------------------------------------
@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?

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Ned Mar 14, 2010 3:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Č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.

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Ned Mar 14, 2010 5:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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.

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Ned Mar 14, 2010 9:54 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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.

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Ned Mar 14, 2010 11:21 pm    Naslov sporočila:  
----------------------------------------------------------------------------
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

Avtor: gumby PrispevekObjavljeno: Ned Mar 14, 2010 11:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
V delovanje AVR se nisem še preveč poglabljal, ampak...

Na PIC se tak problem rešuje tako, da se timer registru enostavno prišteje neka vrednost. Na ta način se ne "izgubi" noben cikel in je perioda prekinitve vedno enako dolga (kdaj se zgodi prekinitev dejansko ni pomembno). Tukaj seveda odpade uporaba prescalerja, ker ga vsako pisanje v TMR register resetira.
Mislim, da bi tole moralo delovat tudi na AVR...

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Pet Mar 26, 2010 10:28 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pa ne vem no... Sem naredil s timerjem1 in ponovno omogočil prekinitve v ostalih prekinitvah, pa je še vedno prehitro za kakih 12 sekund, tako da ne vem kaj je zdaj to. Sem zgleda res slabo načrtoval program. No, ampak s timerjem1 in preescalerjem 256 pri kristalu 10.240 MHz bi lahko stvar kar v redu skalibriral, saj tako nanese 40000 pulzov na sekundo, in z enim pulzom gor ali dol bi nastavljal v ločljivisti 0.0025%.
Pa dobro, se grem sedaj s čim drugim bavit. Smile
LP

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Pet Mar 26, 2010 10:39 am    Naslov sporočila:  
----------------------------------------------------------------------------
Samo87 je napisal/a:

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

Lahko predlagaš kako konkretno rešitev?

Brick wall
No, za podobne tiče kot sem jaz, prilagam še en dober tutorial za timerje (kjer je opisan tudi CTC [sedaj vem, kaj je to Mr. Green ])

Vir: http://www.avrfreaks.net/

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Čet Apr 08, 2010 7:19 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni!

Mi lahko kdo pove in reazloži, kako bi na LCD (2x16) izpisoval številke?
Konkretno bi pisal direkt vrednosti z AD pretvornika...?
Tekst mi rata izpisati, številk (spremenljick) pa ne...


lp, Jernej

Avtor: gumby PrispevekObjavljeno: Čet Apr 08, 2010 7:32 pm    Naslov sporočila:  
----------------------------------------------------------------------------
sprintf() ?

Avtor: osmicaKraj: savinjska PrispevekObjavljeno: Čet Apr 08, 2010 7:49 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Okrog ispisa je bilo v tej temi kar nekaj napisanega poglej post od Silvo_v na 3 strani zanimiv primer ispisa.

Avtor: jvolkKraj: okolica Divače PrispevekObjavljeno: Čet Apr 08, 2010 7:55 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:

#include <avr\io.h>
#include <stdio.h>

...

char trimer;
char msg[16];

trimer = 77;
sprintf(msg,"%d",trimer);
LCDputs(msg);


Kos primera iz predavanja... če ti pride prav

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Pet Apr 09, 2010 10:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Oi!

@osmica

ja, res je!
Vendar sem jaz že zelen in samouk kar se C-ja tiče.
Rad bi, da mi kdo malo razloži kaj določena stvar naredi.

@jvolk
Sem dal to kodo v atmega8 (vključil sem tudi knjižnico, ki je v mapi od predavanj), vendar mi izpiše same štirice...?
Nimam pojma, kaj bi bilo narobe. če spremenim število elementov (saj to pomeni tisto v [] oklepajih?) spremenljivke msg v 4 mi pa izpiše same Omega
lahko malo razložiš, kako ta stvar deluje?


lp, Jernej

Avtor: Samo87Kraj: Kamnik PrispevekObjavljeno: Pon Apr 12, 2010 2:55 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:
char trimer;
char msg[16];

trimer = 77;
sprintf(msg,"%d",trimer);
LCDputs(msg);


msg je niz šestnajstih znakov.

%d je določilo, ki pove sprintf funkciji, da naj interpretira vrednost spremenljivke trimer kot celo število.

Funkcija sprintf v tem primeru priredi celoštevilsko vrednost iz spremenljivke trimer v msg znakovni niz in na koncu doda znak 0.

LCDputs(msg) pa izpisuje ta znakovni niz, znak po znak, dokler ne pride do 0.

Podroben opis funkcije: KLIK

Avtor: gumby PrispevekObjavljeno: Pon Apr 12, 2010 3:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Biblijo (priponka) v roke in naštudirat jezik... brez tega ne bo šlo. Exclamation

Kolk vem stvar obstaja tudi v slovenskem jeziku (v tiskani obliki). Prva verzija (brez ANSI C) pa 100%.

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Pon Apr 12, 2010 8:12 pm    Naslov sporočila:  
----------------------------------------------------------------------------
gumby je napisal/a:
Biblijo (priponka) v roke in naštudirat jezik... brez tega ne bo šlo. Exclamation

Kolk vem stvar obstaja tudi v slovenskem jeziku (v tiskani obliki). Prva verzija (brez ANSI C) pa 100%.


a veš mogoče kje se jo da dobiti in cena?

lp

Avtor: gumby PrispevekObjavljeno: Pon Apr 12, 2010 8:30 pm    Naslov sporočila:  
----------------------------------------------------------------------------
http://cobiss2.izum.si/scripts/cobiss?ukaz=DISP&id=2028273942136793&rec=2&sid=2

Avtor: majkelKraj: Maribor PrispevekObjavljeno: Tor Apr 13, 2010 1:32 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Zanima me ali mi lahjko kdo pomaga.In sicer pri naslednji stvari. Imam ATmega32 in zunanji qvartz 8 Mhz.Sedaj bi rad ta signal pripeljal na en drug prosti pin ker moram izmerit nekaj okol qvartza.
Druga stvar pa je da bi na drug prosti pin moral pripeljati ta isti signal iz zunanjega qvartza 8Mhz vendar bi ga moral zdeliti na okrog 100 Hz oz kolikor je pač mogoče.

Prosim za pomoč. V naprej se zahvaljujem.

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Pet Sep 10, 2010 9:17 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni!

Imam eno teoretično(zaenkrat) vprašanje!

Torej...
Rad bi naredil števec impulzov z uporabo števnika, vendar bi le-ta moral šteti vsaj do nekje 5000, potreboval pa bi dva. Tukaj se pojavi problem, saj ima večina AVR-jev do dva 8b števnika ter do dva 16b števnika, vhoda za štetje pa en za 8b in en za 16b (T0 in T1 če prav razumem datasheet) Confused
Možna bi bila izbira večjega mikrokrmilnika (npr. AtMega1281), vendar imajo ti visoko ceno (previsoko)-ca. 25€ pri farnell-u , kar nekako ne pride v upoštev Sad
Dalo bi se ga dobit tudi za kaj manj na Ebay-u

Zanima me, kako bi naredil povečevanje spremenljiv kenekako sinhrono s števcem?
Torej, če se števec poveča za 1 se mora tudi spremenljivka, s tem da se števec ponastavi, ko pride do 255, spremenljivka pa se ne sme.

Nekako si mislim, da bi števcu odšteval prejšnje stanje in tako dobil spremembo+if stavek oz. prekinitev, ko prešteje do konca oz. nekaj takega?

lp, Jernej

Avtor: MarkoMKraj: Lovrenc na P. PrispevekObjavljeno: Pet Sep 10, 2010 10:25 am    Naslov sporočila:  
----------------------------------------------------------------------------
sortaj je napisal/a:

Možna bi bila izbira večjega mikrokrmilnika (npr. AtMega1281), vendar imajo ti visoko ceno (previsoko)-ca. 25€ pri farnell-u , kar nekako ne pride v upoštev Sad

Uf, ni poceni. Za 10€ dobiš LPC1758, ki se ne more primerjati z eno mego...

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Sep 10, 2010 11:36 am    Naslov sporočila:  
----------------------------------------------------------------------------
Kot en vhod uporabiš recimo 16 bitni števec. Ta ti deluje skoraj neodvisno od programa.
Kot drugi vhod uporabiš npr prekinitveno rutino, ki ti jo proži prispeli pulz na enem od external interrupt pinov in v njej recimo povečuješ eno "int" spremenljivko. Rutina naj bo kratka, da ne vpliva preveč na program.

EDIT: na tak način je sposoben delati že kak Tiny (za nekje 2-3€), recimo 2313, ki ima kasneje še dovolj pinov za izpis na LCD ali kaj drugega.

Avtor: sortajKraj: Med Vipavo in Štanjelom PrispevekObjavljeno: Pet Sep 10, 2010 11:59 am    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala!
Se ne bi domislil! Mr. Green

Frekvenca bo verjetno pod 1kHz.

Namen sem imel uporabiti malo večji uC, ker bom gor verjetno dal še LCD, pa senzorje, potenciometre, itd.
Imel sem željo uporabit AtMega32U4, ki ima že USB bootloader, pa zaradi Atmelovih težav trenutno ni mogoča dobava Sad


lp, Jernej

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Pon Sep 13, 2010 9:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Huh...nabil sem na trdno dno Smile

WinAvr ter prenos podatka tipa float ali double preko RS232 s pomočjo funkcije printf().

Koda:

float Beri_tlak(void)
{
   float ADC_vrednost;
   float Vout;
   float tlak;
   
   ADC_vrednost = ADC_Read();
   Vout = (5*ADC_vrednost) / 1024;

   tlak = ((0.76+Vout) / 0.05295);
   tlak = (tlak*10)+31;
   printf("Tlak v glavni zanki je %f",tlak);
   
   return (tlak);
}


To je samo del kode (funkcija), ki naj bi pretvorila vrednost ADCja, ki bi lahko bil tipa int v float vrednost. Compiler mi javi: ../SSI_Encoder.c:188: warning: format '%f' expects type 'double', but argument 2 has type 'float'

poizkusil sem tudi s spremenljivkami double.

napravil sem tudi tole

vendar vse kar dobim kot vrednost je "?".

Imel že kdo podobno težavo?

LP G

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Pon Sep 13, 2010 10:24 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Si bom sam odgovoril.

V linker je potrebno vpisati tole: -Wl,-u,vfprintf -lprintf_flt -lm

Sedaj dela.

LP G

Avtor: logistKraj: dom(o)vina PrispevekObjavljeno: Pon Sep 27, 2010 10:03 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mene pa zanima, če je taka uporaba Watchdog-a smiselna, ker delam prvič z njim in me zanima, a sem prav razumel, kaj sem prebral.

Koda:
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
//Vpis logične vrednosti 1 v WDTOE in WDE
WDTCR = (1<<WDTOE) | (1<<WDE);
//Izklop WDTRC
WDTCR = 0x00;
}

void main(){
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
//WDTCR=0x0F;

#asm("wdr");

while(1){
WDTCR = (0<<WDTOE) | (0<<WDE);
WDTCR=0x0F;
}


}

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Pon Dec 27, 2010 8:02 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Danes sem priden in delam z mega16. Timerje sem osvojil (sedaj upam tako trditi) Smile
Pa vseeno me muči ena koda.
Koda:
#include <avr/io.h>

int main (void)
{
   unsigned char i=0;
   
   DDRB |= ((1 << 0)|(1 << 7)); // Set LED as output

//   TCCR1B |= (1 << CS10);                  // Set up timer at Fcpu
   TCCR1B |= (1 << CS11);                // Set up timer at Fcpu/8
//   TCCR1B |= ((1 << CS10) | (1 << CS11));    // Set up timer at Fcpu/64
//   TCCR1B |= (1 << CS12);                // Set up timer at Fcpu/256
//   TCCR1B |= ((1 << CS10) | (1 << CS12));    // Set up timer at Fcpu/1024


   
   for (;;)
   {
      // Check timer value in if statement, true when count matches 1 second
      if (TCNT1 >= 500)
      {
         PORTB ^= (1 << 0); // Toggle the LED

         TCNT1 = 0; // Reset timer value

       i++;
      
       if(i>=1000)
       {
         PORTB ^= (1 << 7); // Toggle the LED

       i=0;

       }
      }
   }
}


S Timerjem delam 0.001ms delay in si "izpisujem" na LED na PORTu B.

Problem:
Pri AVRStudio simulaciji deluje, v realnosti na plošči ne. Zakaj?
Če delam 10ms delay mi deluje ok, tudi pri 1s. (spreminjam TCNT1 in delilnik).

Avtor: logistKraj: dom(o)vina PrispevekObjavljeno: Pon Dec 27, 2010 8:16 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Uporabi prekinitev (primer napisan za Atmega32):

Koda:


unsigned int i_timer1;

ISR(TIMER1_COMPA_vect){
 i_timer1++;
 if(!i_timer1%4){ // vsako sekundo (približno) 0,256 * 4 = 1,024 s
    // koda ki se izvede ob prekinitvi;

 }
}


int main(void){
   //Nastavitev registrov casovnika 1 (Timer/Counter0),
   TCNT1 = 0x00;      // postavitev registra stetja casovnika 1 na 0
   //deljenje sistemske ure s 1024, ter nastavitve izbrisa registra ob ujemanju vrednosti (CTC),
   TCCR1B = (1<<CS12)|(0<<CS11)|(1<<CS10)|(1<<WGM12);
   //omogocitev prekinitve poteka stevnika (Timer Overflow),
   TIMSK = (1<<OCIE1A);
   //registra ujemanja vrednosti (OCR1)
   OCR1A = 2000;      //1A - ujemanje vrednosti vsake 0,256 s

       while(1){}

      return 0;
}



Če pa želiš imeti točno na sekundo pa ti priporočam da uporabiš DS1307 (kateremu lahko določiš datum in uro in s katero frekvenco se ti bo izvajala prekinitev). Dela pa na i2c vodilu in lahko mu vežeš baterijo, da ob izpadu elektrike ti ura in datum tečeta še naprej.

Avtor: piromanKraj: Ljubljana PrispevekObjavljeno: Pon Dec 27, 2010 8:29 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Če je frekvenca oscilatorja 8 MHz (tega ne vemo) in imaš vklopljen delilnik 1/8 (to pa vemo), se ti timer premakne za eno vrednost vsako us; ravno toliko, kot hočeš delaya...

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Pon Dec 27, 2010 8:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Frekvenca je 4MHz, delim z 8. Tako bi moral imeti 500 taktov, da bi bila zakasnitev 1ms.
Ampak mi je ne izpisuje na PORTB.7

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Pon Dec 27, 2010 9:08 pm    Naslov sporočila:  
----------------------------------------------------------------------------
sem se že ujel. Problem je bil pri:
Koda:
   unsigned char i=0;

potem pa:
Koda:
if(i>=1000)

premajhna spremenljivka.

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Čet Dec 30, 2010 8:42 pm    Naslov sporočila:  
----------------------------------------------------------------------------
@lojzek
Vprašanje zate.
Torej, rad bi izpisal vrednost neke spremenljivke na LCD.
LCD mi deluje normalno, pišem lahko s funkcijo LCDstring("nekaj", 5),...

Mi pa ne deluje LCDsendChar();
v tvojem primeru vidim, da delaš na tak način:

Koda:
   volatile unsigned char i = 18;

      LCDGotoXY(0,0);
    LCDsendChar(i+48);


meni pa žal to ne deluje. Izpiše mi nek B...?

Avtor: RUrosKraj: Moravče PrispevekObjavljeno: Čet Dec 30, 2010 11:40 pm    Naslov sporočila:  
----------------------------------------------------------------------------
B ti izpiše zato, ker če vpišeš cifro v oklepajih, bo izpisal po ascii kodi znak ki je na številki i+48=66, ki pa je ravno B (veliki b). Lahko pogledaš ascii pa boš videl, da je desetiško po ascii kodi B ravno 66.
kaj želiš izpisati ?

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Pet Dec 31, 2010 12:34 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Aham, se mi je zdelo, da je nekaj v tem primeru. Ampak lojzeku pa izpisuje v redu.

sedaj sem rešil z drugim prijemom.
Koda:
sprintf(msg, "i=%d", i);
LCDstring(msg, 5);


tako pa mi pravilno izpisuje spremenljivke.

Hvala vseeno.

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Pet Dec 31, 2010 1:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Zabavam se z FLIPom on pa z mano. Ko naložim program v AT90USB1287 ta deluje v redu. Ko prekinem napajanja ali resetiram pa pazabi na program. Kje ga lomim ?.

Hvala.

Avtor: logistKraj: dom(o)vina PrispevekObjavljeno: Pet Dec 31, 2010 1:55 pm    Naslov sporočila:  
----------------------------------------------------------------------------
žrepko je napisal/a:
Aham, se mi je zdelo, da je nekaj v tem primeru. Ampak lojzeku pa izpisuje v redu.

sedaj sem rešil z drugim prijemom.
Koda:
sprintf(msg, "i=%d", i);
LCDstring(msg, 5);


tako pa mi pravilno izpisuje spremenljivke.

Hvala vseeno.


Lahko pa uporabiš tole kodo : http://extremeelectronics.co.in/avr-tutorials/using-lcd-module-with-avrs/ čist na koncu pod številko 148 pa uporabi še kodo, če imaš 4x(XY) LCD. Avtor popravka pa sem jaz.

Lp,

Mihael

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Dec 31, 2010 6:15 pm    Naslov sporočila:  
----------------------------------------------------------------------------
@žrepko: tisto sem uporabil za izpis cifer. številka 0 je po ASCII tabeli na 48. mestu, in če temu (48) prišteješ cifro med 0 in 9, ti bo izpisal željeno cifro. POSAMEZNO cifro, ne cele številke. Torej moreš desetice in enice izpisat posebej....

Ta način sem uporabljal ponavadi zato, ker sem pisal programe za male mikrokontrolerje in je knjižnica stdio.h (ki vsebuje printf) že sama po sebi prevelika za male mikrote.

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Pet Dec 31, 2010 9:37 pm    Naslov sporočila:  
----------------------------------------------------------------------------
rudiP je napisal/a:
Zabavam se z FLIPom on pa z mano. Ko naložim program v AT90USB1287 ta deluje v redu. Ko prekinem napajanja ali resetiram pa pazabi na program. Kje ga lomim ?.

Hvala.


Sem našel napako. Pin Pe.2/HWB (hardware bootloader activation) je bil stalno na logični nuli, tako da bootloader ni delal.

Vsem zdravo in srečno 2011.

Avtor: logistKraj: dom(o)vina PrispevekObjavljeno: Sre Jan 19, 2011 8:59 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni,

imam srce vezja je ATmega32 + Ds1307 in zraven tega pa bi še dodal ATtiny45 na i2c vodilo.

Zanima me če komunikaciji med ATmega32 in ATtiny45 je potrebno nastavit kateri mcu je master in kateri slave. In če lahko uporabim isto kodo iz komunikacije master => slave pri komunikaciji slave => master samo da pri slave nastavim potrebne vrednosti registrov?

hvala,

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Ned Jan 23, 2011 11:17 am    Naslov sporočila:  
----------------------------------------------------------------------------
Učim se debugiranja v Avr Studiu. Programček napisan v Codevision AVR sem aktiviral v AVR Studiu. VSE lepo dela, nerazumljivo pa mi je, da sem v CVavr definiral Clock frequency : 8,000000 MHz v AVR Studiu pa mi napiše: frequency 4,000000 MHz. Prosim za razlago, Hvala.

prilagam screen shot:

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Ned Jan 23, 2011 12:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Jaz bi si tole razlagal nekako takole. Ti samo compilerju poveš, s kako frekvenco deluje tvoj mlinček zato, da lahko compiler preračunava trajanja posameznih ciklov, ta podatek pa se nikamor ne zabeleži (v hex ali bin ali kateri drugi fajl, ki služi debagiranju itd...), tako da boš moral povedati tudi AVRstudiu, s kako frekvenco imaš opravka, to pa narediš v Project --> Configuration options in imaš tista tri okenca, v katerega vpišeš tip uCja, frekvenco ter vtičnike za optimizacijo kode.

LP G

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Ned Jan 23, 2011 12:26 pm    Naslov sporočila:  
----------------------------------------------------------------------------
RGorazd je napisal/a:
tako da boš moral povedati tudi AVRstudiu, s kako frekvenco imaš opravka, to pa narediš v Project --> Configuration options in imaš tista tri okenca, v katerega vpišeš tip uCja, frekvenco ter vtičnike za optimizacijo kode.

LP G


Te opcije ni, verjetno zato, ker sem za odprtje projekta uporabil *.cof fajl.

Avtor: vilkoKraj: Dragomer PrispevekObjavljeno: Pon Jan 24, 2011 9:03 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hej! Na hitro sem preletel vse napisano, marsikaj se vidi, a tisto, kar iščem, ne. Odpira pa se mi novo vprašanje:
Za WinAVR slišim tukaj prvič. Kakšna je razlika med WinAVR in AVRStudio?

Dalje imam vprašanje za AVRStudio, ki sem ga danes instaliral in se spotikam zdaj tu zdaj tam:
Pri Bascomu imam Simulator programa, ki silno prav pride pri iskanju napak v podprogramih, vidiš pomnilnike vidiš spremenljivke. No nekaj podobnega ima tudi AVRStudio.
Pogrešam pa okno, kje se pojavi vse, kar napišem na standardni izhod.
Prilagam sliko Bascomovega simulatorja, v oknu z modrim ozadjem se pojavi vse, kar pošlje moj program na uart0 ali na uart1 (odvisno on mikrokrmilnika in okna)

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Pon Jan 24, 2011 9:21 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ni potrebe uporabljati posebej Winavr. V Avrstudio odpreš nov projekt z AVR GCC. Glej raznorazne primere tudi v Svetu Elektronike. Za programerje, še posebej za začetnike v C-ju, je veliko bolj dojemljiv CodevisionAVR. Odličen čarovnik ti inicializira mikrokrmilnik tako kot je treba, ostane ti le pisanje kode. Lahko si snameš light verzijo do 2k kode. Licenca pa tudi ni draga (180 eur). Program debugiraš brez problema v AVR Studiu.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Pon Jan 24, 2011 11:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Vilko, AVRstudio je kot tak namenjen ASM programiranju AVRjev. WinAVR je pa GCC orodje, ki ti omogoča, da v AVRStudiu pišeš program v C-ju. Vsebuje vse, knjižice, linker, compiler itd...

V AVRstudiu nimaš direktno okna, kjer bi videl, kaj ti pošilja UART.

LP G

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Tor Jan 25, 2011 6:53 am    Naslov sporočila:  
----------------------------------------------------------------------------
RGorazd je napisal/a:


V AVRstudiu nimaš direktno okna, kjer bi videl, kaj ti pošilja UART.



Zato pa vidiš kaj se dogaja v registrih, iram, stekih itd . Ni težko.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Jan 25, 2011 7:20 am    Naslov sporočila:  
----------------------------------------------------------------------------
rudiP je napisal/a:


Te opcije ni, verjetno zato, ker sem za odprtje projekta uporabil *.cof fajl.


To opcijo dobiš, ko zaženeš simulacijo,, prej se ne vidi. Potem se ti v meniju "Debug" čisto spodaj pojavi "AVR Simulator optioms", kjer POSEBEJ za simulacijo izbereš tip mikrota in delovno frekvenco. Če tega ne narediš, potem simulacija včasih ne dela dobro...

Tudi jaz sem dolgo potreboval, da sem do tega prišel. Liar

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Tor Jan 25, 2011 7:25 am    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala za namig, dela.

Avtor: vilkoKraj: Dragomer PrispevekObjavljeno: Čet Jan 27, 2011 2:38 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ajaja, nič ni tako kompicirano kot izgleda, ampak bolj.

AVRstudio in C, začetniški problem.
prekopiral sem prvi program, in ko hočem dobiti .hex datoteko, mi javi napako:
make: *** No rule to make target `../vaja2.c', needed by `vaja2.o'. Stop.

Prilagam sliko.
Kaj ne vem?

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Čet Jan 27, 2011 3:59 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Izgleda, da nisi pravilno kreiral projekt, ter nimaš vseh parametrov. Kljub temu, da delaš z Avrstudiem, moraš imeti instaliran tudi WinAvr.


Tudi osnovni okvir ni v redu. Predlagam, da si narediš osnovo tako:

Koda:
#include <avr/io.h>   //Vkljucitev IO knjiznice (vhodi/izhodi)
// globalne spremenljivke
int main(void)   //Glavna funkcija
{
     // Lokalne spremenljivke

   //Zanka for, ki se izvaja neskoncno
   for (;;)
   {
      

   };

};   //Konec programa.

Avtor: vilkoKraj: Dragomer PrispevekObjavljeno: Čet Jan 27, 2011 6:12 pm    Naslov sporočila:  
----------------------------------------------------------------------------
rudiP je napisal/a:
Izgleda, da nisi pravilno kreiral projekt, ter nimaš vseh parametrov.


Izgleda čisto druga filozofija kot tista, ki sem je bil vajen.
Vajen sem bil
- izvorna koda
- prevedeni program, ki se polni z programatorjem v mikro ( .hex file ali .bin file)
- error file, v kolikor so napake
- report file, ki daje osnovne karakteristike programa, kateri mikrokrmilnik, timestamp prevoda, mapa spremenljivk, kje so, koliko spomina je zasedeno oziroma fraj,
-------------------
Tukaj pa imam Projekt . Sliši se zelo akademsko, ampak kaj pravzaprav je projekt?
Potem ime poleg prevoda (compile) še build in makefile, pojma nimam, kaj je to.

???

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Čet Jan 27, 2011 6:22 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Iz enake filozofije prihajam tu sam. Prehajam na C in ni to tako težko. POglej ta tutorial za začetek.


http://imakeprojects.com/Projects/avr-tutorial/

Avtor: vilkoKraj: Dragomer PrispevekObjavljeno: Čet Jan 27, 2011 10:30 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ta tutorial sem 'dal skoz'
A ne razlaga o tem, kako priti do hex datoteke in kaj pomenijo operacije Build, Makefile, compile ( no to slednjo razumem, a mi ne naredi hex datoteke, kot bi pričakoval)
Zadeva se je začela komplicirati, ko sem hotel upravljati, kje naj bodo moje datoteke, ko sem za hex datoteko lokacijo spremenil iz /default (za katero pojma nimam, kje je, ne maram pa je imeti nekje v windows sistemu) na mojo lokacijo,
Se držim koncepta, da so vse 'moje' kreacije v mapi z mojim imenom, ki ima podmape, in potem je enostavno narediti mesečno kopijo mojih kreacij.

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Čet Jan 27, 2011 11:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
VIlko, vse kaže, da make ne vidi poti do tvoje source kode. Poizkusi spremeniti Vaja v main.c, ali preveri naslednje, če imaš v nastavitvah. Prav tako se tudi vidi,kje označiš, da želiš imeti generiran hex za vpis v mlinček.

LP G

Avtor: vilkoKraj: Dragomer PrispevekObjavljeno: Pet Jan 28, 2011 12:34 am    Naslov sporočila:  
----------------------------------------------------------------------------
Končno uspel dobiti hex file:
Naredil sem popolnoma nov Project, in dal križec v 'create new folder'

Koliko različnih datotek je naredil!! Samo za .c in .hex imam občutek, da vem, zakaj so.

Avtor: VolkDKraj: Divača (Kačiče) PrispevekObjavljeno: Pet Jan 28, 2011 1:23 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ko vas takole sledim, moram nehote ugotoviti, da je baskom na nek način spremenil vaše razmišljanje in imate zaradi tega zdaj enormne težave.
No ampak v C je treba ugriznit, ker drugače ne gre prešaltat na arme.


Nazadnje urejal/a VolkD Čet Apr 07, 2011 11:12 pm; skupaj popravljeno 1 krat

Avtor: marsKraj: Obala PrispevekObjavljeno: Pet Jan 28, 2011 9:37 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Vilko, za AvrStudio obstaja Hapsim simulator. http://www.helmix.at/hapsim/

lp

Avtor: logistKraj: dom(o)vina PrispevekObjavljeno: Pet Feb 04, 2011 12:39 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mene pa zanima, kako je najboljše da programsko izvedem generiranje impulza širine 10us z ATmega32. A z _delay_ms() ali pa z časovnikom.

Lp,

Avtor: silvo_vKraj: Domžale PrispevekObjavljeno: Pet Feb 04, 2011 12:59 pm    Naslov sporočila:  
----------------------------------------------------------------------------
S časovnikom, seveda.

Lp

Avtor: logistKraj: dom(o)vina PrispevekObjavljeno: Sob Feb 12, 2011 7:21 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Trenutno imam kodo (prikazani so samo segmenti kode)
Koda:
#define TENTER   6

unsigned char GetKeyStatus(unsigned char key){
return(!(PINA) & (1<<key));
}

GetKeyStatus(TENTER);


A obstaja kakršna varjanta, da bi pri define napisal tako in imenovano funkcijo da bi bila univerzalna za vse porte - seveda da so porti predhodno nastavljeni kot vhodi.

Lp,

Avtor: TomazpKraj: Ljubljana PrispevekObjavljeno: Tor Feb 15, 2011 9:40 am    Naslov sporočila:  
----------------------------------------------------------------------------
Zelo dobro izhodišče za učenje C za AVR na osnovi winavr se najde na:

http://www.smileymicros.com/download/
http://www.smileymicros.com/

Lekcije so na primeru Butterfly testne plošče (Atmega169). Obsegajo pa delo od začetnega nastavljanja winavr do bolj kompleksnih konkretnih primerov programiranja. Obstaja tudi knjiga, ki je skoraj identična. Je pa s knjigo morda malce lažje slediti.

lp

Avtor: eddieKraj: Severna primorska PrispevekObjavljeno: Sre Apr 06, 2011 8:38 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Tudi sam sem pred tem da zagrizem v C. Že dolgo je želja, sedaj izgleda pa bo tudi malo vzpodbude...
Cja kot takega se bo treba naučiti to ni debate, kaj pa vzeti v roke kot orodje pa je moje vprašanje. Šlo bo za AVR procesorje.
Glede na to da je Avrstudio 5 že opremljen tudi s prevajalnikom za C ali bi bila to prava izbira?
Tisti, ki ste bolj doma v teh vodah - ga je že kdo bolj resno preizkusil?
Ali bi bilo morda izbrati katero drugo orodje?
Če da, potem katero?

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Sre Apr 06, 2011 9:36 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Za AVR je Avrstudio 4 odlično orodje, primerov in literature je ogromno na internetu. Zelo dobro čtivo za začetek je Lemur knjiga, priporočam.

Avtor: JanckKraj: Ljubljana PrispevekObjavljeno: Čet Apr 07, 2011 6:31 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Imam Atmelovega Tiny'a in mi ga ne zazna preko USB-ja. Kakšna ideja?

Avtor: rudiPKraj: KOPER PrispevekObjavljeno: Čet Apr 07, 2011 6:52 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Janck je napisal/a:
Imam Atmelovega Tiny'a in mi ga ne zazna preko USB-ja. Kakšna ideja?


Moraš malo več povedati. Kaj imaš USB programator ?

Avtor: davideKraj: Savinjska PrispevekObjavljeno: Čet Apr 21, 2011 7:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Nimam še večjih izkušenj s programom codevision avr zato me zanima, kako implementirati detekcijo tipke na portu na negativno fronto?
Sem pobrskal po internetu in mi nekako ne dela nobeden od primerov...
Prej sem takšne enostavne zadeve delal z orodjem microc for avr, je bila funkcija button v kateri si kar določil na katero fronto se naj odzove pritisk tipke, verjetno tudi s tem orodjem se da kako enostavno to napisati

Hvala za pomoč!

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sre Apr 27, 2011 8:09 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ravnokar presedlal iz bascoma na C. LEDica že utripa, pojavi pa se problem, ko hočem v program vključiti for zanko. Ob gradnji (build) mi javi, da je program velik 3726 bytov, veliko preveč za attiny13. Kaj delam narobe?

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

int main(void)
{
   DDRB = 0b00001000;
   int i;

      for(i=0;i<255;i++)
      {
       _delay_ms(i);
      PORTB = 0b00001000;
      _delay_ms(i);
      PORTB = 0b00000000;
      }

return 0;
}

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Sre Apr 27, 2011 8:33 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Spremeni iz
Koda:
 int i
na
Koda:
char i;

Mogoče bo pomagalo.

EDIT:

Šele sedaj sem videl, da uporabljaš delay funkcijo.
Raje uporabljaj timerje. Primeri so na www.avrfreaks.com zelo lepo prikazani.
Program se ti najbrž ne bo izvajal po želji, ker vedno znova povečuješ zakasnitev.

Avtor: teeyKraj: Maribor PrispevekObjavljeno: Čet Apr 28, 2011 12:08 am    Naslov sporočila:  
----------------------------------------------------------------------------
TECHNIC je napisal/a:
Ob gradnji (build) mi javi, da je program velik 3726 bytov, veliko preveč za attiny13. Kaj delam narobe?


Nič, čist dober si. Tisti int bi res lahko bil unsigned char, ampak to nima tolikšne veze z tvojo napihnjenostjo. Absolutno pa vklopi "Release Build" oziroma optimizacije (gcc -O2). Sploh _delay_xx funkcije iz avr-libc so vezane na njih, saj če pogledaš so postavljene celo z floating-pointi (double), ampak jih optimizacija potem demolira v samo par ukazov brez plavajoče vejice, kar pa Debug Build ne naredi.

Jaz sem v takih primerih, če je res bil potreben Debug Build, zadevo rešil z funkcijo, ki je glede na konfiguracijo (Release ali Debug) uporabila _delay_xx funkcijo ali pa kar navadno zanko z nop(). S tem sem se rešil tudi omejitve največje zakasnitve funkcije.

Na hitro,

Koda:

void delay(unsigned int ms)
{
#if(defined(_DEBUG) || defined(DEBUG))

   unsigned int ms_ticks = (1000 / F_CPU);
   
   while(ms-- > 0)
   {
      for(unsigned int t = 0; t < ms_ticks; t++)
      {
         asm volatile("nop"::);
      }
   }

#else

   _delay_ms(ms);

#endif
}


Lahko da mrgoli kakšna napakica noter, nisem sprobal, moralo bi pa delati.

Avtor: davideKraj: Savinjska PrispevekObjavljeno: Čet Apr 28, 2011 4:32 pm    Naslov sporočila:  
----------------------------------------------------------------------------
kaj res nihče še ni delal s tipko v codevision-u?
res bi prosil za to pomoč, nekako mi ne dela tako kot j treba...hm

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Apr 29, 2011 6:10 am    Naslov sporočila:  
----------------------------------------------------------------------------
@technic: Pred prevajanjem moraš v nastavitvah AVR studia vklopiti optimizacijo glede na velikost programa. Wink

Project - Configuration options, potem pa pri "optimization" izberi možnost "-Os"

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sob Apr 30, 2011 8:24 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala vsem za odgovore!

Sem že uspel nagruntati timerje, tokrat ledica utripa s točno 1Hz Smile
Na forumu našel še par uporabnih zadev, kot so |=, ^=, &= ... pa tudi 1<<x. Tako da hvala za povezavo!

Imam pa vprašanje, ali vedno uporabljate timerje? Tudi za kakšne preproste zakasnitve (recimo nekaj us zaradi prevajanja med FETi v H-mostu)?

Avtor: logistKraj: dom(o)vina PrispevekObjavljeno: Pet Maj 06, 2011 10:31 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mene pa zanima zakaj mi program noče globalne spremenljivki dodelit vrednost 0?

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Pet Maj 06, 2011 11:13 pm    Naslov sporočila:  
----------------------------------------------------------------------------
TECHNIC je napisal/a:
Hvala vsem za odgovore!

Sem že uspel nagruntati timerje, tokrat ledica utripa s točno 1Hz Smile
Na forumu našel še par uporabnih zadev, kot so |=, ^=, &= ... pa tudi 1<<x. Tako da hvala za povezavo!

Imam pa vprašanje, ali vedno uporabljate timerje? Tudi za kakšne preproste zakasnitve (recimo nekaj us zaradi prevajanja med FETi v H-mostu)?


Najenostavneje je za kratko pavzo napisati tako:

unsigned int pavza = 255;
While(pavza--){}

ali pa
for(pavza=0; pavza ==255;pavza++);

to sta samo dva primera, kako napraviti krajši delay.

Lahko uporabiš tudi nop ukaz ali pa nop();

LP G

Avtor: alen666Kraj: okolica Podčetrka PrispevekObjavljeno: Sob Maj 28, 2011 6:39 pm    Naslov sporočila:  atmega8
----------------------------------------------------------------------------
Pozdravljeni!
Da ne odpiram nove teme, imam atmego8 in lpt programator-samo 5 žic.
Včeraj mi je zadevo uspelo usposobit, da sem programiral v bascomu na stk200 programator in zadeva je delovala.
Danes čip spozna, le sprogramirat ga noče- verifikacija ne uspe.
Kaj bi lahko bilo narobe?
hvala

Avtor: RUrosKraj: Moravče PrispevekObjavljeno: Sob Maj 28, 2011 7:32 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Preveri še enkrat povezave s programatorjem, če so še vse v redu. Hkrati pa poglej kako je kaj s frekvenco oz. kristalom pri atmegi, da nisi kaj zaprogramiral in se zato s programatorjem ne moreta zmenit.

Drugače pa imam tudi sam en banalen problem, ki nevem kako naj ga čim bolj enostavno rešim.
Iz GPS modula dobivam string iz katerega izluščim uro po UTC času, se pravi moram čas prestaviti za 2 uri naprej da bo po naše. Kako naj to na najbolj enostaven način naredim da bo delovalo za vseh 24ur dneva ? Kako ste to rešili tisti, ki ste naleteli na takšen problem ?

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sob Jun 11, 2011 4:00 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdrav!

Tale koda:
Koda:
k=1000;
while(k--){}

Mi v programu proti pričakovanju ne naredi povsem nič. Zdi se mi, da je prevajalnik od AvrStudia preveč pameten in pri vklopljeni optimizaciji Os enostavno zbriše to zanko. (zakaj?) Če pa optimizacijo izklopim(O0), mi iz 222b programa nastane 624b.
Za zakasnitev lahko še vedno uporabim notranji timer, vendar gre ta le do 255 (in ga hkrati v neki drugi funkciji potrebujem, da teče hitro, zato ne morem uporabit prescalerja). Pravzaprav me samo zanima, zakaj (in če se da spremenit) mi izbriše/ignorira while zanko (ki po njegovem mnenju ne naredi ničesar)?

Avtor: David2204Kraj: Ljubljana - Nova Gorica PrispevekObjavljeno: Sob Jun 11, 2011 6:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Poskusi napisati:

int k = 1000;
while(k>0) k--;

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Ned Jun 12, 2011 10:15 am    Naslov sporočila:  
----------------------------------------------------------------------------
TECHNIC je napisal/a:
Pravzaprav me samo zanima, zakaj (in če se da spremenit) mi izbriše/ignorira while zanko (ki po njegovem mnenju ne naredi ničesar)?


Od prevajalnika si zahteval optimizacije, zakaj se čudiš, da je optimiziral tvojo kodo? Smile

Prevajalnik nima nobenega koncepta časa oz. trajanja. Poenostavljeno povedano, če vidi prirejanje vrednosti neki spremenljivki, ki se nikjer ne uporablja, ta del kode odstrani, skupaj s klici funkcij ipd.

Najbolj preprosto se da ta problem rešit tako, da spremenljivko deklariraš kot volatile (volatile int i). V tem primeru prevajalnik ne bo odstranil te kode.

volatile namreč prevajalniku pove, da a) spremenljivka lahko vpliva na stvari zunaj tega programa, in b) stvari zunaj tega programa lahko vplivajo na to spremenljivko. Kar v tem primeru sploh ni pomembno, važno je, da prevajalnik ne predpostavlja več, da je vrednost spremenljivke nepomembna, čeprav se njena vrednost v programu nikjer ne upošteva.

Mimogrede, v knjižnici (util/delay.h) imaš že napisane rutine za zakasnitve, zakaj jih ne uporabljaš?


LP!

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Ned Jun 12, 2011 11:16 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ker so mi zgoraj svetovali uporabo timerjev, ampak za take "navadne" zakasnitve (kjer program res nič ne rabi delati) je verjetno najbolje klicati delay. Hvala!

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sre Jun 22, 2011 2:42 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Tokrat se mi je zataknilo pri zbujanju iz spanja. Želim, da mi uC zbudi sprememba stanja na PORTB.2, zato najprej naredim tole:

Koda:
SREG |= (1<<7); //global interrupt enable
PCMSK |= (1<<PCINT2); //pin change PORTB.2
GIMSK |= (1<<PCIE); // pin change interrupt enable
MCUCR |= (1<<SM1); //sleep mode power-down


Potem pa v program dodam tole, kjer hočem, da gre uC v power-down.
Koda:
MCUCR |= (1<<SE); //sleep enable
sleep_cpu();
MCUCR &= ~(1<<SE); //sleep disable


V program imam seveda dodano knjižnico "avr/sleep.h"
Problem pa je, ker se program obnaša zelo čudno, uC nikoli ne izklopi motorja (PORTB.1), čeprav je ta ukaz malo nižje. Ali se pri vsaki spremembi PORTB.2 (trigger), program nekam usmeri in nikoli ne pride preko tega?

Tule je pa cel program:
Koda:
int main(void)
{
DDRB = 0b00000011;
PORTB |= 0b00001100;
TCCR0B |= ((1<<CS00) | (1<<CS02));

SREG |= (1<<7);
PCMSK |= (1<<PCINT2);
GIMSK |= (1<<PCIE);
MCUCR |= (1<<SM1);

int i;

while(1)
   {
   TCNT0 = 0;
   i = 0;

   while((PINB & (1<<Trigger))==0x04) //dokler je stikalo izklopljeno
      {
      if(TCNT0>250) {i++; TCNT0=0;}
      if(i>3)
         {
         PORTB &= ~(1<<Stop); //izklopi zavoro motorja
         MCUCR |= (1<<SE);
         sleep_cpu();
         MCUCR &= ~(1<<SE);
         }
      }
   PORTB &= ~(1<<Stop); //izklopi zavoro motorja

   _delay_ms(1);

   PWM_start(); //funkcija ki vklopi motor
   PORTB |= (1<<Start); //vklopi motor
   while((PINB & (1<<Trigger))==0){} //dokler je stikalo vklopljeno
   PORTB &= ~(1<<Start); //izklopi motor

   _delay_ms(1);

   PWM_brake(); //funkcija ki zavre motor
   PORTB |= (1<<Stop); //zavri motor

   _delay_ms(5);
   }
return 0;
}

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sob Jun 25, 2011 6:54 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Začel s preprostejšim primerom, vendar zadeva še kar ne deluje. uC gre v spanje, vendar pa se ne zbudi vedno/se čudno obnaša. Ko tipko pritisnem, včasih LED gori, tako kot bi morala, včasih pa samo žmigne, ko tipko spustim. Kaj pozabljam?

Koda:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define Trigger PORTB2
#define Start PORTB1

int main(void)
{
DDRB = 0b00000011;
PORTB |= 0b00001100;

PCMSK |= (1<<PCINT2);
GIMSK |= (1<<PCIE);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();

while(1)
   {
   sei();
   sleep_mode();
   cli();

   while((PINB & (1<<Trigger))==0x00) //ko je pritisnjena tipka, LED gori
      {
      PORTB |= (1<<Start);
      }
   PORTB &= ~(1<<Start);
   }
return 0;
}

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sre Jul 20, 2011 1:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Še vedno nisem rešil problema ... Čudno je to, da povsem enak program skompajlan iz Bascoma deluje brez problema, medtem ko program iz AVRstudio4 ne deluje. Mikrokontroler se zbudi samo včasih.

AVRStudio:
Koda:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define Trigger PORTB2
#define Start PORTB1

int main(void)
{
DDRB = 0b00000010;
PORTB = 0b00000100;

PCMSK |= (1<<PCINT2);
GIMSK |= (1<<PCIE);
MCUCR |= (1<<SM1);
MCUCR &= ~(1<<SM0);
sei();
while(1)
   {
   sleep_enable();
  sleep_cpu();
  sleep_disable();

   if((PINB & (1<<Trigger))==0) PORTB ^= (1<<Start);
   while((PINB & (1<<Trigger))==0){}
   }
return 0;
}


Bascom:
Koda:
$regfile = "attiny13.dat"
$crystal = 4800000

Config Portb.1 = Output
Config Portb.2 = Input

Enable Interrupts
Set Pcmsk.pcint2
Set Gimsk.pcie
Set Mcucr.sm1
Reset Mcucr.sm0

Trigger Alias Pinb.2
Startmotor Alias Portb.1
Portb.2 = 1

Do
Set Mcucr.se
Sleep
Reset Mcucr.se

If Trigger = 0 Then
   Toggle Startmotor
End If

Bitwait Trigger , Set

Loop

End

Avtor: HighlagKraj: Črnuče PrispevekObjavljeno: Sre Jul 20, 2011 2:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Smiselno bi bilo preverit asm kodo, ki jo zgenerirata oba programa. Nekje je razlika.

Avtor: BorisPKraj: Celje PrispevekObjavljeno: Sre Jul 20, 2011 3:38 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Poizkusi takole definirati tipke in postavljati ledice

Koda:

//T1 = active high - se proži proti 1
//T2 = active low  - se proži proti 0
#define T1  (PINB & 0x01)
#define T2 !(PINB & 0x02)

#define ClrLED1 (PORTB &= ~(1 << PB0))
#define SetLED1 (PORTB |= (1 << PB0))
....

if (T1) SetLED1;
if (T2) ClrLED1;

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sre Jul 20, 2011 4:35 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Take stvari sem že poskusil, dejstvo je, da program brez sleep rutine deluje kot je treba.

V priponki obe asm kodi, če bo še kdo kaj našel. Rutina okrog sleep ukaza je enaka, več pa nisem gledal.

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Pet Jul 22, 2011 5:21 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Tako na hitro ima program vsaj dve napaki. Omogočiš prekinitve in:
-Nimaš spisane prekinitvene rutine.
-Nisi inicializiral stack pointerja.

Nekateri AVR-ji so po Sleep instrukciji potrebovali dva NOP-a.
Če pišeš in takoj nato bereš iz porta je dobro dati en NOP med instrukciji.

Avtor: TECHNICKraj: Senovo PrispevekObjavljeno: Sre Jul 27, 2011 12:10 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sem rešil, hvala!

Avtor: trobidaKraj: Savinjska dolina-okolica Gornjega Grada PrispevekObjavljeno: Pet Sep 09, 2011 2:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ponovno eno vprašanje za vse boljše poznavalce C-ja. Nekako opuščam Bascom in presedam na program C (uporabljam AVR studio in WinAvr, ter Atmega8). Osnove so mi dokaj poznane. Nekaj postov nazaj je uporabnik Lojzek spraševal kako v določeni knjižnici za LCD lahko nastaviš pine, na katerih je priklopljen LCD. Mimogrede, uporabljem isto knjižnico kot Lojzek, ki se nahaja tukaj. Knjižnico sem že preuredil mojim zahtevam. Zanima pa me sledeče; ko sem v bascomu nastavljal pine LCD-ja sem pin R/W dal na nulo (fizično maso). Tako je zadeva delovala normalno. V tem C-jevskem primeru pa vidim, da je pin R/W priključen na določen pin procesorja. Prav tako je vključen v knjižnico. Spodaj pripenjam kodo:

Koda:

#define LCD_RS   0    //define MCU pin connected to LCD RS
#define LCD_RW   1    //define MCU pin connected to LCD R/W
#define LCD_E   2   //define MCU pin connected to LCD E
#define LCD_D4   4   //define MCU pin connected to LCD D3
#define LCD_D5   5   //define MCU pin connected to LCD D4
#define LCD_D6   6   //define MCU pin connected to LCD D5
#define LCD_D7   7   //define MCU pin connected to LCD D6
#define LDP PORTD   //define MCU port connected to LCD data pins
#define LCP PORTD   //define MCU port connected to LCD control pins
#define LDDR DDRD   //define MCU direction register for port connected to LCD data pins
#define LCDR DDRD   //define MCU direction register for port connected to LCD control pins


Zanima me, ali je ta pin (R/W) obvezno potrebno priključiti na procesor ali je lahko na masi, kot v primeru v bascomu ?

Hvala za vsako pomoč in nasvet Wink .

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Pet Sep 09, 2011 6:01 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Odvisno, kako je knjižnica spisana.
Če iz LCD-ja nikoli nič ne bere (namesto preverjanja statusa uporablja zakasnitve), je RW lahko na maso.

Avtor: trobidaKraj: Savinjska dolina-okolica Gornjega Grada PrispevekObjavljeno: Sob Sep 10, 2011 8:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------
@Int47, hvala za odgovor. Omenjeni pin sem v knjižnici pustil na miru, le na nek še prosti pin sem ga naslovil. Fizično pa sem ga dal na maso. Zadeva zaenkrat deluje po pričakovanjih.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Sep 12, 2011 6:09 am    Naslov sporočila:  
----------------------------------------------------------------------------
Kolikor imam v spominu, v "moji" knjižnici ni RW pin sploh nikoli uporabljen, razen da je na začetku definiran.
Jaz sem knjižnico predelal v tej meri, da ima krmilne in podatkovne pine na različnih portih, ter da res uporablja in definira samo tiste pine porta, ki jih uporablja. V osnovi je namreč "porabila" kar celoten port in s tem po svoje preuredila I/O funkcije porta.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Sep 13, 2011 12:59 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sedajle pa zopet jaz z vprašanjem..

Do sedaj še nisem uporabljal printf() funkcije. Ker je potrebna stdio.h knjižnica že sama zasedla preveč prostora za male mikrote (ki imajo do 2kB spomina).

Sedaj pa bom uporabil Mego8 in spomin ni tak problem.

Zanima me pa, če je moje razmišljanje pravilno in sem stvari razložene na netu pravilno razumel:

1. Printf() izpiše tisto, kar imaš podano v njenih argumentih na RS232 izhod? (pri računalniku to zapiše neposredno na ekran)

2. sprintf() pa tisto, kar imaš podano v njenih argumentih, zapiše v spomin mikrota v obliki nekega char arraya (stringa), ti pa potem moraš ta rezultat iz spomina (char arraya) spraviti tja kamor želiš, npr. na LCD ekranček?

Avtor: gumby PrispevekObjavljeno: Tor Sep 13, 2011 1:29 pm    Naslov sporočila:  
----------------------------------------------------------------------------
1. printf() pošilja na stdout. Če misliš pošiljat na UART ali LCD, boš moral stdout preusmerit na neko funkcijo, ki pošlje znak kam pač mora. Tule vse lepo piše...
2. da, ampak pazi, da bo array dovolj dolg za rezultat.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Sep 15, 2011 1:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Zopet jaz Angel

Imam ta manjši testni programček- pisan v DEV C++. To pa zato, ker je na kompu funkcije lažje testirat kot v mikrotu.
Koda:
#include <stdio.h>
#include <string.h>

char tekst [16];
volatile unsigned int stevilo1, stevilo2;
unsigned char a,b,c;


int main ()

{
printf ("Merjenje velicin\n\n");
stevilo1 = 3510;     //napetost
stevilo2 = 220;      //tok

printf ("stevilo1=%d   stevilo2=%d\n", stevilo1, stevilo2); //TU JE VSE OK

sprintf (tekst, "U=%.2d.%.2dV I=%.1d.%.2dA\n",
         stevilo1/100, stevilo1%100, stevilo2/100, stevilo2%100);
                              //pretvorba stevilke v string:
                                //tekst = rezultat;
                                //"%.2d" = desetiška številka, z dvema ciframa
                                //stevilo1 = stevilo, ki ga želiš pretvoriti

//TU PA SE stevilo1 ŽE SPREMENI

printf ("mesto: 1234567890123456\n");
printf ("IZPIS: %s\n" ,&tekst[0]);

printf ("stevilo1=%d   stevilo2=%d\n", stevilo1, stevilo2);

scanf("%s", &a);    //počakaj pritisk neke tipke


}


Programček dve int cifri predela v string in izpiše. Lepo in pravilno. Problem pa je, da ne zastopim, zakaj mi sprintf() spremeni vrednost spremenljivke stevilo1. Dobi vrednost 10. Če pa stevilo1 na začetku nastavim na drugo vrednost, pa ima po sprintf() vrednost 2625. Opisano se vidi tudi na izseku ekrana... S poizkušanjem sem definitivno ugotovil težavo v sprintf() funkciji - premikal sem izpis cifer na razna mesta v programu. In zakaj spremeni samo stevilo1, medtem ko stevilo2 ostane kot na začetku?

Torej, kje sem ga kiksnil v tisti sprintf() vrstici Think ?

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Čet Sep 15, 2011 1:27 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Za zacetek povecaj array tekst za en vnos (char tekst[17]), in potem ponovno poskusi.

Kaj bi lahko bilo drugega pa na prvi pogled ni ocitno.

LP!

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Sep 15, 2011 1:39 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ja, točno to je bilo. Null terminator stringa mi je "povozil" polovico int cifre 35-10 in jo predelal v (najverjetneje) 0-10.

Ampak, ali ni pri velikosti arraya [16] le ta dolg pravzaprav 17 polj? Saj se šteje od 0, 1, 2, ...16. In v tistem zadnjem 17.tem (z oznako 16) sem računal skrajni doseg za null terminator..

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Čet Sep 15, 2011 1:54 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:

Ampak, ali ni pri velikosti arraya [16] le ta dolg pravzaprav 17 polj? Saj se šteje od 0, 1, 2, ...16. In v tistem zadnjem 17.tem (z oznako 16) sem računal skrajni doseg za null terminator..


Ne, pri deklaraciji polja podas njegovo tocno velikost, torej int a[16]; je deklaracija polja z 16-imi elementi, prvi je a[0], zadnji a[15].

LP!

Avtor: trobidaKraj: Savinjska dolina-okolica Gornjega Grada PrispevekObjavljeno: Sre Sep 21, 2011 1:02 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni !

Ponovno se oglašam z nekim začetniškim problemom Wink . Neko kodo iz Bascoma še verzije 8051 prevajam v C. Programiram za AVR studio in WinAvr-jem. Spodaj prilagam kodo, katera je napisana v Bascom8051:

Koda:

V_nap_sp:
         Cls
         Lcd "St.Vrt. ->:" ; V_naprej
         Lowerline
         Lcd "(OK)/(-)/(+)"

        [b] Do[/b]
          A1 = P3.3                                         ' (-)              239
          A2 = P3.5                                         ' (+)              223
          A3 = P3.4                                         ' (OK)             247
          Ar = P3.2                                         ' Avtomatsko/Ročno 251
          If A2 = 0 Then
                 If A1 = 0 Then
                   V_naprej = -1
                   Gosub V_nap_1
                 Else
                   Gosub V_nap_1
                 End If
                 Set Sprememba
          Elseif A1 = 0 Then
                 Gosub V_nap_2
                 Set Sprememba
          Elseif A3 = 0 Then
                 [b]Exit Do[/b]
          End If
          Waitms 250
        [b] Loop[/b]

Return



Napisan je le delček kode oziroma funkcija ki čaka pritiske tipk. Sedaj sem se lotil kodo prepisati v C vendar imam manjši problem. V Bascom kodi so uporabljeni ukazi ki so napisani krepko. Ti so: Do, Loop in exit do.

Mi lahko kdo prosim pove ali poda kakšen primer kako naj se te kode lotim v C-ju oziroma kaj naj uporabim namesto bascom ukazov Do, Loop in Exit do ? Spodaj sem kodo po večini prevedel, vendar se mi je zaradi zgornjih ukazov zataknilo Sad .
Prilagam še prevedeno kodo:

Koda:

void V_nap_sp()
{      
      char lcdstr1[16];
        char lcdstr2[16];

      LCDclr();
      sprintf(lcdstr1, "Vrtljaji: %i", Vrtljaji);
      LCDGotoXY(0, 1);                     //Kurzor postavi na drugo vrstico
      LCDstring("(OK)/(-)/(+)", 12);

   ?????   Do
      if (PLUS_is_pressed())
               
          {      
                  
                  if (MINUS_is_pressed())
               
                     {
                     V_naprej = -1;
                     V_nap_1();

                     else
                     {
                     V_nap_1();
                     }
                     }

            Sprememba = 1
            else if (MINUS_is_pressed())
            {
            V_nap_2;
            Sprememba = 1;
            }
            else if (OK_is_pressed())
            {
         ?????   exit do;
            }
           }

      delay_ms(LOCK_INPUT_TIME1);
   ?????   Loop;

}



Hvala vsem za nasvete.

Avtor: žrepkoKraj: Ptuj-Maribor PrispevekObjavljeno: Sre Sep 21, 2011 1:39 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Potrebuješ funkcijo do while.
lahko tudi samo while(pogoj) { ... }

izvaja tisto kar je v while funkciji tako dolgo dokler pogoj ni izpolnjen.

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Sre Sep 21, 2011 5:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:
do ... loop -> for(;;) { ... }, ali while() { ... }

exit do -> break;

next -> continue;

Avtor: trobidaKraj: Savinjska dolina-okolica Gornjega Grada PrispevekObjavljeno: Sre Sep 21, 2011 7:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala za info, bom poizkušal zgornjo kodo "prebekslati" tako, kot sta svetovala. Poročam Wink ...

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Sep 22, 2011 6:11 am    Naslov sporočila:  
----------------------------------------------------------------------------
Če je tista do - loop zanka pravzaprav glavni program in se mora stalno izvajati, ga označiš takole:
Koda:
while(1)
{

//tvoj programček

} //zaključek while zanke - in s tem tudi programa


V glavnem while (1) in oklepaja označujeta program. Z oklepaji tudi označiš dele programa - ukaze, ki po funkciji spadajo skupaj in se morajo tudi skupaj izvesti.

Seveda, če je to glavni program, iz njega ne moreš "izskočiti". Kaj bo pač mikro potem počel? Če pa je to samo ena funkcija (podprogram), pa iz nje izskočiš na več načinov: 1. ko se enkrat izvrši, 2. z ukazom return (ko je npr izpolnjen pogoj).
V primeru, da je to funkcija, pa bi tudi zanko funkcije mogoče naredil z 1. while(pogoj), ali pa 2. do --funkcija--- while (pogoj).

Malce branja , drugače pa se podobnega na netu kar najde..

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Sep 28, 2011 1:03 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Zopet eno vprašanje, nekdo ki zna, bo hitreje odgovoril, kot pa se bom jaz prebil skozi morje branja na netu.

V eni podfunkciji programa imam lokalno (v njej) definirani recimo dve int spremenljivki. Mikro pri izvajanju funkcije ti spremenljivki spreminja.
Kaj se s tema spremenljivkama zgodi po izhodu iz funkcije. Ali se njuna vrednost "izniči", ali še vedno ta vrednost ostane nekje v spominu mikroja?

Pravzaprav to niti ni bistvo željene informacije. Najbolj me zanima, kaj se s tema spremenljivkama zgodi ob ponovnem klicu podfunkcije. Ali je njihova vrednost še vedno taka, kot je bila ob prejšnjem obisku funkcije? Oz. kolikšna je verjetnost, da se njuna vrednost ni spremenila?

Izsek problema za lažje razumevanje:

Koda:
void podfunkcija ()
{
unsigned int a, b;
if (en pogoj == true)
   ++a;
else 
   ++b;
}


Sem poizkušal sicer z AVR studiovim simulatorjem sam ugotoviti, ampak mi nekaj v tem delu simulacije ne dela po željah (seveda ne, ko ga pa nekje biksam), tako da točnega odgovora sam nisem ugotovil.

Avtor: gumby PrispevekObjavljeno: Sre Sep 28, 2011 1:14 pm    Naslov sporočila:  
----------------------------------------------------------------------------
a in b ne obstajata zunaj funkcije. Načeloma vrednost sicer ostane nekje v RAM-u, vendar je kakršnokoli zanašanje na to vrednost recept za kasnejši glavobol.
Biblijo v roke in naštudiraj "doseg" spremenljivk.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Sep 28, 2011 1:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Se mi je kar zdelo, da tako na easy ne bo šlo. Ali bom moral uporabiti globalne spremenljivke, ali pa povsem drug princip....

Avtor: matjazkariz PrispevekObjavljeno: Sre Sep 28, 2011 2:11 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Eni compilerji podpirajo deklaracijo globalnih spremenljivk v funkciji in sicer ponavadi jo definiraš s static...

Koda:
static unsigned char blabla;

Avtor: gumby PrispevekObjavljeno: Sre Sep 28, 2011 2:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Static ne pomaga. Spremenljivka znotraj funkcije navzven ne bo vidna.

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Sre Sep 28, 2011 3:19 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Rabiš za rekurzijo?
V tem primeru bi šlo s static.

Avtor: alyKraj: Kranj - struževo PrispevekObjavljeno: Sre Sep 28, 2011 9:02 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Globalno spremeljivko narediš. Ali imaš premalo RAM-a ali v čem je težava?

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Sep 28, 2011 10:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Se je kar debata razvila. Moja želja je, da bi pravzaprav štel, kolikokrat je program poklical podfunkcijo in je bil hkrati nek pogoj izpolnjen (tuhtam o neki moji vrsti debounce-ja tipke,. Zakaj? Ker ne vem, kako to profiji naredijo) Ob X-kratni ponovitvi klica podfunkcije in hkratno izpolnjenem pogoju- pritisnjeni tipki bi pa postavil zastavico v neki globalni - za cel program veljavni spremenljivki.

Drugače pa, o "static" deklaraciji bom še malo prebral- ni pa frke, če kdo od vas tudi kaj o tem omeni. Ni pa to problem rešiti z nekaj več globalnimi spremenljivkami.
Rad bi pač ugotovil neko "drugo" pot , če je seveda kolikor-toliko enostavno rešljiva.

Aja.... Rekurzija je pa kaj? Neutral

..... Naslednjič se oglasim (najverjetneje) šele v ponedeljek. Grem familijo v hribe terat...

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Okt 13, 2011 7:36 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ponovno sem tukaj.

Zahtevno vprašanje:

Zakaj popolnoma enaka ukazna vrstica s popolnoma enakimi vrednostmi spremenljivk U in I naredi drugačen izpis, če se izvede v programu DEV C++ in AVR studiu?

Edina (mislim da matematično nepomembna) razlika je pri spremenljivki U, ki je pri DEV tipa unsigned int, pri AVR Studio pa unsigned long.

Instrukcija:
Koda:
sprintf (tekst, "U=%.2d.%.2dV I=%.1d.%.2dA",
         U/100, U%100, I/100, I%100);
                              //pretvorba stevilke v string:
                                //tekst = rezultat;
                                //"%.2d" = desetiška številka, z dvema ciframa
                                //U ,I = stevilo, ki ga želiš pretvoriti


Pri uporabi - točni določitvi - vrednosti spremenljivke U = 1155 in I = 495

V simulaciji na računalniku v programu DEV C++ izpiše - array tekst postavi na vrednost:
Koda:
U=11.55V I=4.95A


V programu AVR Studio pa
Koda:
U=11.00V I=55.00


Skratka, pri U ne izračuna decimalke, I pa izračuna in izpiše popolnoma napačno

Tudi pri sami simulaciji v AVR studio je rezultat tak, kot na LCD zaslonu Brick wall

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Okt 14, 2011 10:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
Na nekaj pa lahko odgovorim sam sebi. Mogoče pa tudi komu drugemu, ki bo naletel na enak problem.

S simulacijami in ročnim vnašanjem vrednosti, ki sem jih želel izpisat, sem ugotovil, da mi oba argumenta U in I nekako "združi in povozi".

Vzrok vsega je, da sprintf v AVR studiu ne želi številke, ki ima v spominu rezerviranih več mest kot pa int. Shame on you

Tako da mojega tipa številke "long", dolgega 4 mesta, sprintf ne prebavi pravilno.

Rešitev je konvert long -> int in izpis se izvede pravilno.

Druga možnost (nepreverjena) je morebiti uporaba sprintf_P (če zastopim komentar v stdio.h, naj bi ta prebavila "infinite size" argumentov)

Avtor: RGorazdKraj: Ig PrispevekObjavljeno: Pet Okt 14, 2011 4:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Lojzek, mislim, da tiči zajec v linkerju. Enkra se spomnim sem imel težave z izpisom spremenljivke tipa float. Nekaj guglanja me je privedlo do tega:

http://www.elektronik.si/phpBB2/viewtopic.php?t=10229&postdays=0&postorder=asc&highlight=float&start=225

LP G

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sob Okt 15, 2011 8:05 am    Naslov sporočila:  
----------------------------------------------------------------------------
No glavno, da sva ugotovila. Meni kar ustreza uporaba pretvorbe long -> int. Tisti long potrebujem pred izpisom, ker je zaradi računanja cifra večja od 65535. Pri samem izpisu pa je največ 4000.

Je pa prvič, da se srečujem z sprintf funkcijo. Ta namreč zasede že sama cca 2kb spomina, tako da je pri tinnyjih itak ne moreš uporabit.

Avtor: alyKraj: Kranj - struževo PrispevekObjavljeno: Ned Okt 16, 2011 12:24 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Saj se jo da tudi "na roke" zaobiti.
Za izpis številke greš po vrsti, cifro po cifro, znak po znak:
(n/1000) + 0x30 = tisočica v ascii
(n/100) + 0x30 = stotica v ascii
itd..
Pridobljene znake namečeš na izhodni port (npr usart, lcd).
Decimalno piko postaviš po želji nekam vmes.

Avtor: zdovcjKraj: Kovor PrispevekObjavljeno: Ned Okt 16, 2011 6:57 pm    Naslov sporočila:  
----------------------------------------------------------------------------
aly je napisal/a:

(n/1000) + 0x30 = tisočica v ascii
(n/100) + 0x30 = stotica v ascii


Ko dobiš tisočice, jih moraš odšteti, drugače ti ta algoritem za stotice vrže ven neko dvomestno število (v primeru, da je število večje od tisoč). Če prišteješ še ascii kodo za ničlo, boš dobil nek čuden znak.

Pravilno bi šlo nekako takole:


(n/1000) + 0x30 = tisočica v ascii
((n - (n/1000)*1000)/100) + 0x30 = stotica v ascii
...

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Okt 17, 2011 6:18 am    Naslov sporočila:  
----------------------------------------------------------------------------
@aly: Takle princip, kot ga ti predlagaš, običajno uporabljam. Ga je v točno tej temi omenil (mislim da) silvo_v. Zaradi "poenostavitve" programa, in da mi ena rutina lahko piše vse potrebne podatke na ekran, sem uporabil to funkcijo. Podatki so namreč različnih dolžin in različnih tipov.

Seveda je ta "poenostavitev" poskrbela za to, da je program sedaj (ko je šele 20% razhroščen), že dolg okoli 4500kb, od tega polovico zaseda stdio.h. Brez te sprintf funkcije bi ga prav gotovo stlačil v tinyja26, tako pa tiči v overkill megi8.

Avtor: RUrosKraj: Moravče PrispevekObjavljeno: Pon Jan 02, 2012 12:57 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sprva se mi je zdelo da bo enostavno uporabiti kodo od atmega324 za attinya pa mi ne gre in ne gre. Zanima me zakaj mi omenjega koda ne dela na attiny13. Namenjena za branje tipk.

Koda:

//funkcija
void tipke()
{

static char newPIND=0;
static char oldPIND=0xff;

newPIND=PIND;

PRITISKI_TIPK |= (((oldPIND ^ newPIND) & oldPIND) >> 2) & 0x03;
SPUSTI_TIPK |= (((oldPIND ^ newPIND) & newPIND) >> 2) & 0x03;

oldPIND=newPIND;

 }

//uporaba funkcije v while(1)

tipke();
if(PRITISKI_TIPK)
      {
      
         if(PRITISKI_TIPK & 0x01)
            {
               PRITISKI_TIPK=PRITISKI_TIPK & (~0x01);
               //naredi nekaj
               
            }   
      
          if(PRITISKI_TIPK & 0x02)
            {
               PRITISKI_TIPK=PRITISKI_TIPK & (~0x02);
               //naredi nekaj
            }
                
   
      }         


Koda lepo deluje z atmega324, nevem pa zakaj noče delati z drugim uC. Uporaba funkcije je pravilna, problem je v stavku kjer se nahaja xor in & operacije. Tu ne razumem najbolje kaj bi moral prilagoditi svojemu uC-ju.

EDIT:
Problem rešen:
Koda:
void tipke()
{

static char newPINB=0;
static char oldPINB=0xff;

newPINB=PINB&0x03;

PRITISKI_TIPK=(oldPINB^newPINB)&newPINB;
SPUSTI_TIPK=(oldPINB^newPINB)&oldPINB;

oldPINB=newPINB;

}

Avtor: majkelKraj: Maribor PrispevekObjavljeno: Pon Feb 06, 2012 9:20 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ali mi lahko kdo pomaga oz vsaj razloži kako s pomočjo termistorja izmeriti temperaturo. Imam Termistor NTCLE100E3103JB0 10K@25°C. Pull up je 4.64K. Imam atmega16a.Vseskupaj programiram v codevision-u.Prebral vse mogoče pdf-e pa ne zaštekam zadeve.
Proim za pomoč

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Feb 06, 2012 12:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
1. Dejstvo: NTC pomeni, da upornost s temperaturo pada
2. določi si temperaturni obseg meritev MIN in MAX.
3. iz karakteristike NTC-ja (ali pa s poskusom) določi vrednosti upornosti NTCja pri temperaturah iz tč.2
4. Dejstvo: atmega zna izmeriti NAPETOST na svojih ADC vhodih. in sicer v obsegu od 0V do recimo 5V (odvisno, kako si mego skonfiguriral in s čim jo napajaš)
5. Problem: kako upornost NTC spremeniti v napetost? rešitev: Ohmov zakon. Preko predupora skozi NTC pošiljaš določen tok in na njem se pojavi napetost, ki jo lahko z mego izmeriš. Ta napetost se s temperaturo NTC spreminja.
6. Velikost predupora določiš tako, da bo napetost na NTCju pri upornostih iz tč. 3 v merilnem območju Mege (tč.4). Koristno je, če je napetost na NTCju v čimvečjem merilnem obsegu Mege. S tem pridobiš točnost meritev.

Kako pa potem iz dobljenega rezultata pretvorbe ADC vhoda izračunat nazaj temperaturo... Pri tem pa pomagajo malce logike, znanja osnovnošolske matematike, svinčnik, papir in kalkulator. Ter seveda že narisana (ali izmerjena) karakteristika NTCja

Avtor: ZajcKraj: Postojna PrispevekObjavljeno: Sob Mar 17, 2012 5:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Mene pa zanima zakaj mi PORTB=0x00 uposteva kot HIGH 0xFF pa LOW. AVR studio+winavr na atmega16.

Avtor: eddieKraj: Severna primorska PrispevekObjavljeno: Sob Mar 17, 2012 7:57 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Malo bolj točno opiši kaj sprašuješ. Kako je pa nastavljen DDRB?

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Sob Sep 07, 2013 11:47 am    Naslov sporočila:  
----------------------------------------------------------------------------
Imam problem z makroji v C-ju.

Imam deklarirane makroje:

Koda:


#define SET_BIT(port,pin)      port|=1<<pin
#define CLR_BIT(port,pin)      port&=~(1<<pin)
#define CHECK_BIT(port,pin)   (port&(1<<pin))
#define DDR(x)      DDR ## x
#define PORT(x)   PORT ## x
#define PIN(x)      PIN ## x

#define LCD_RS_PORT    B
#define LCD_RS_PIN      PINB7



In znotraj main funkcije bi rad uporabil nekaj v tem smislu (S tem bi nastavil PINB7 na output):

Koda:


SET_BIT(DDR(LCD_RS_PORT), LCD_RS_PIN);



In pri tem fašem error, da makro "DDRLCD_RS_PORT" ne obstaja.

Kako bi lahko naredil, da bi makro "DDR" zaznal "DDRB" namesto "DDRLCD_RS_PORT"?


Nazadnje urejal/a tilz0R Sob Sep 07, 2013 11:48 am; skupaj popravljeno 1 krat

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Sob Sep 07, 2013 11:48 am    Naslov sporočila:  
----------------------------------------------------------------------------
Imam problem z makroji v C-ju.

Imam deklarirane makroje:

Koda:


#define SET_BIT(port,pin)      port|=1<<pin
#define CLR_BIT(port,pin)      port&=~(1<<pin)
#define CHECK_BIT(port,pin)   (port&(1<<pin))
#define DDR(x)      DDR ## x
#define PORT(x)   PORT ## x
#define PIN(x)      PIN ## x

#define LCD_RS_PORT    B
#define LCD_RS_PIN      PINB7



In znotraj main funkcije bi rad uporabil nekaj v tem smislu:

Koda:


SET_BIT(DDR(LCD_RS_PORT), LCD_RS_PIN);



In pri tem fašem error, da makro "DDRLCD_RS_PORT" ne obstaja.

Kako bi lahko naredil, da bi makro "DDR" zaznal "DDRB" namesto "DDRLCD_RS_PORT"?

Avtor: int47Kraj: Ljubljana PrispevekObjavljeno: Ned Sep 08, 2013 2:53 pm    Naslov sporočila:  
----------------------------------------------------------------------------
DDRLCD_RS_PORT definiraj pred DDR(x)

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Ned Sep 08, 2013 2:56 pm    Naslov sporočila:  
----------------------------------------------------------------------------
To mi pol ne pomaga nič.

Hvala vseeno Wink

Avtor: gregoralKraj: Ljubljana PrispevekObjavljeno: Pon Sep 09, 2013 10:15 am    Naslov sporočila:  
----------------------------------------------------------------------------
Zakaj pa ne poskusiš v tej smeri?

Koda:

#define LCD_RS_PORT    B
#define LCD_RS_PIN      PINB7

#include "MyMacros.h"


Vsebina MyMacros.h:
Koda:

#define SET_BIT(port,pin)      port|=1<<pin
#define CLR_BIT(port,pin)      port&=~(1<<pin)
#define CHECK_BIT(port,pin)   (port&(1<<pin))
#define DDR(x)      DDR ## x
#define PORT(x)   PORT ## x
#define PIN(x)      PIN ## x



LP, Gregor

Avtor: gumby PrispevekObjavljeno: Pon Sep 09, 2013 1:23 pm    Naslov sporočila:  
----------------------------------------------------------------------------
gregoral je napisal/a:
Koda:
#define SET_BIT(port,pin)      port|=1<<pin


V izogib kasnejšim glavobolom se navadite na tako obliko:
Koda:
#define SET_BIT(port,pin)      (port)|=1<<(pin)

Avtor: gregoralKraj: Ljubljana PrispevekObjavljeno: Pon Sep 09, 2013 3:23 pm    Naslov sporočila:  
----------------------------------------------------------------------------
gumby: V izogib kasnejšim glavobolom se navadite na tako obliko:
Koda:
#define SET_BIT(port,pin)      (port)|=1<<(pin)


Pritrjujem napisanemu,
parametre makrojev je zelo priporočljivo vgnezditi med oklepaje.

Razlog:
Koda:

#define OPERACIJA_A(x)      x*2
#define OPERACIJA_B(x)      (x)*2
...
int a = OPERACIJA_A(1+1);
int b = OPERACIJA_B(1+1);
...
// to je isto kot
int a = 1+1*2;
int b = (1+1)*2;


Razlika upam da je vsem razumljiva!
Vrstni red operacij se spremeni, s tem pa tudi rezultat!

Moj post je bil za ilustracijo ideje, s katero je možno vrstni red definicij zelo enostavno zamenjati.

Osnova je da splošne makroje premakneš v header file.
To je priporočljivo v vsakem primeru.
S tem pridobiš tudi možnost uporabe iste datoteke v več projektih.
Prednost je, da izboljšave te datoteke lahko uporabiš pri vseh projektih ki datoteko uporabljajo.

Header datoteko potem vključuješ po potrebi.
Pred vključevanjem pa lahko definiraš tudi druga "imena".

Kodo sem vzel od predhodnikov in je nisem podrobno analiziral.

Lp, Gregor

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Tor Sep 10, 2013 3:01 am    Naslov sporočila:  
----------------------------------------------------------------------------
gregoral je napisal/a:
Zakaj pa ne poskusiš v tej smeri?

Koda:

#define LCD_RS_PORT    B
#define LCD_RS_PIN      PINB7

#include "MyMacros.h"


Vsebina MyMacros.h:
Koda:

#define SET_BIT(port,pin)      port|=1<<pin
#define CLR_BIT(port,pin)      port&=~(1<<pin)
#define CHECK_BIT(port,pin)   (port&(1<<pin))
#define DDR(x)      DDR ## x
#define PORT(x)   PORT ## x
#define PIN(x)      PIN ## x



LP, Gregor


Žal, ampak to je neuporabno za moj problem.

Avtor: program_erKraj: Maribor (Pohorje) PrispevekObjavljeno: Tor Sep 10, 2013 8:50 am    Naslov sporočila:  
----------------------------------------------------------------------------
Koda:
#define SET_BIT(port,pin)   (port) |= 1<<(pin)
#define CLR_BIT(port,pin)   (port) &=~(1<<(pin))
#define CHECK_BIT(port,pin)   ((port)&(1<<(pin)))

#define DDRx(x)      (DDR ## x)
#define PORTx(x)   (PORT ## x)
#define PINx(x)      (PIN ## x)

#define DDR(x)   DDRx(x)
#define PORT(x)   PORTx(x)
#define PIN(x)   PINx(x)

#define LCD_RS_PORT    B
#define LCD_RS_PIN     PINB7


Tvoj makro ne sme imeti "stika" z ##, ker se v tem primeru ne razširi. Zato sem dodal še eno plast makroja, kar povzroči, da se prvotni makro pravilno razširi in stvar deluje.

Preberi si odlomek: Scanning the replacement list for macros to expand.

Avtor: gregoralKraj: Ljubljana PrispevekObjavljeno: Tor Sep 10, 2013 8:51 am    Naslov sporočila:  
----------------------------------------------------------------------------
tilz0R je napisal/a:
Žal, ampak to je neuporabno za moj problem.

Nisi probal, ne deluje, ti ni všeč, kaj je narobe??
Napiši da bodo tudi drugi vedeli in se morda česa naučili.

Poskusiš lahko še z inline funkcijami namesto makrojev.
Poleg tega dobiš zraven type-checking gratis.

Koda:

//typedef uint8_t address_t;
//typedef uint8_t index_t;
typedef int address_t;
typedef int index_t;

static inline void SET_BIT(volatile address_t *target, index_t bit){ *target |= (1<<bit); };
static inline void CLR_BIT(volatile address_t *target, index_t bit){ *target &= ~(1<<bit); };
static inline void TOGGLE_BIT(volatile address_t *target, index_t bit){ *target ^= (1<<bit); };
static inline bool CHECK_BIT(volatile address_t *target, index_t bit){ return *target & (1<<bit); };



LP, G

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Tor Sep 10, 2013 10:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
gregoral je napisal/a:
tilz0R je napisal/a:
Žal, ampak to je neuporabno za moj problem.

Nisi probal, ne deluje, ti ni všeč, kaj je narobe??
Napiši da bodo tudi drugi vedeli in se morda česa naučili.

LP, G


Ni delalo, še vedno DDRLCD_RS_PORT da ne obstaja.

Sem pa našel na netu "adc" knjižnico, v kateri je bila koda za "CONCAT" pa sem jo dodal k sebi.

Koda:

#ifndef CONCAT1
   #define CONCAT1(a, b) CONCAT2(a, b)
#endif

#ifndef CONCAT2
   #define CONCAT2(a, b) a ## b
#endif

#define SET_BIT(port,pin)         (port)|=1<<(pin)
#define CLR_BIT(port,pin)         (port)&=~(1<<(pin))
#define CHECK_BIT(port,pin)         ((port)&(1<<(pin)))
#define PINSTATE(port,pin,state)   (state==0)?(CLR_BIT((port),(pin))):(SET_BIT((port),(pin)))
#define DDR(x)                  CONCAT1(DDR, x)
#define PORT(x)                  CONCAT1(PORT, x)
#define PIN(x)                  CONCAT1(PIN, x)
#define CONCAT(a, b)            CONCAT1(a, b)


In uporaba čudežno dela:

Koda:

DDR(LCD_RS_PORT);


Zdej zakaj je to, da tokrat dela ne vem, če pa kdo ve pa lahko napiše.

Avtor: chaosKraj: Zagorje ob Savi PrispevekObjavljeno: Sre Sep 11, 2013 2:16 pm    Naslov sporočila:  
----------------------------------------------------------------------------
tilz0R je napisal/a:

Zdej zakaj je to, da tokrat dela ne vem, če pa kdo ve pa lahko napiše.


Saj ti je progam_er napisal, zakaj je tako, tudi pravo resitev ti je podal.

LP!

Avtor: klemen88Kraj: Slovenj Gradec PrispevekObjavljeno: Pon Jun 30, 2014 6:40 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Lep pozdrav,

tudi jaz sem prišel do problema oz. sam ne najdem rešitve. Sem začetnik v Cju.

Uporabljam ATMega328 ter programiram v C-ju (GCC).

V eni aplikaciji želim uporabiti UART komunikacijo in sem vzel že napisano knjižico od Peter Fleury-a. Zadeva deluje tako kot more vendar težava nastane, ko želim sprejeti več bytov informacij (string). Kako bi lahko na boljši način sprejel string v obdelavo (predhodno se shrani v procesorju in potem kličemo byte po byte vsak cikel) kot sem to storil jaz. Težavo imam, ker nikoli nevem, če sem že sprejel celoten string.



Koda:

   // SPREJEM ZNAKOV //
            
 c = uart_getc();
        if ( c & UART_NO_DATA )
        {
    /* ni podatkov
      
        }
        else
        {
                 zastavica=1;
            sprejem[i]=c;
            i++;
         
          /*
             * nov podatek
         
                       */
         
      }

      // KONEC SPREJEMA //


Sam sem razmišljal v tej smeri, da bi uporabil samo "c = uart_getc();" in z neko while funkcijo shranjeval podatke v string, od 0 (0 vrne, če ni kakšnega sprejetega podatka) pa do druge 0, ki sledi in potem postavil zastavico, da je sprejet string.
Sam sem poskušal vendar zaradi predhodnega (ne)znanja nisem prišel do prave rešitve. Upam, da me razumeta kaj sem želel napisati.

Hvala za odgovore!

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Pon Jun 30, 2014 6:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ena ideja je, da čakaš znak, ki ti pomeni konec stringa, recimo "\n".

Avtor: klemen88Kraj: Slovenj Gradec PrispevekObjavljeno: Sre Jul 02, 2014 6:19 pm    Naslov sporočila:  
----------------------------------------------------------------------------
To sem že poskusil vendar mi nekako ni delalo. Zdaj, ko si mi napisal sem spet poskusil in dodal 100us pavzo pri pobiranju znakov iz spomina mi je stvar začela delovati. Včasih že pomaga, če samo napišeš na forum Wink

Če se mi še kje zalomi pa se priporočam,

Hvala!

Avtor: red_mambaKraj: Edinburgh PrispevekObjavljeno: Sre Jul 02, 2014 11:01 pm    Naslov sporočila:  
----------------------------------------------------------------------------
ponavadi imas nek flag, ki ga lahko preveris ali je kak podatek v internem UART bufferju.

ali pa naredis na prekinitve ki ti polnijo neko string speremenljivnko.
v glavni zanki pa se sprehodis cez sprejete znake

Avtor: klemen88Kraj: Slovenj Gradec PrispevekObjavljeno: Pon Avg 04, 2014 6:48 am    Naslov sporočila:  
----------------------------------------------------------------------------
Lep pozdrav,

zadeva mi sedaj deluje, problem mi je nastal kako bi iz string ločil podatke in jih stranil v svojo spremenljivko, med seboj se ločijo z vejico.

Naredil sem s to kodo vendar mi ne deluje vedno kot bi morala.

Koda:

char *tmp_rx_data = rx_data; // Zacasni kazalec


// Poisci vsebino

// Isci do naslednjega ','


while( *tmp_rx_data++ != ',' );

// Izracunaj dolzino

int length = tmp_rx_data - rx_data ;

// Rezerviraj prostor za vsebino

vsebina = (char*)malloc( length  );

// Zascitis, da ne vgre cez dovoljene meje

vsebina[length-1] = 0;

// Prekopiraj vsebino

memcpy(vsebina, tmp_rx_data, length-1 );



Hvala!

Avtor: program_erKraj: Maribor (Pohorje) PrispevekObjavljeno: Tor Avg 05, 2014 7:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
klemen88 je napisal/a:
Naredil sem s to kodo vendar mi ne deluje vedno kot bi morala.


Kdaj pa ne deluje in kaj se takrat dogaja?

Prvi očiten problem bi bil v primeru stringa, ki ima že na prvem mestu vejico. V tem primeru je spremenljivka length = 0, zato ti malloc vrne NULL pointer, nato pa hočeš ti na ta null_pointer[-1] zapisati 0 (torej dvojna napaka).

EDIT: Spregledal post inkrement pri *tmp_rx_data++. Zgoraj napisano torej ni možno.

EDIT2: Ti kopiraš bajte iz tmp_rx_data na vsebina. Vendar pazi, tmp_rx_data kaže na konec substringa, na začetek kaže rx_data.

Ekvivalentna (a delujoča) koda memcpy v tvojem primeru bi bila:
Koda:
// Rezerviraj prostor za vsebino

vsebina = (char*)malloc( tmp_rx_data - rx_data );

// Prekopiraj vsebino

char *tmp_substr = rx_data;

while( tmp_substr != tmp_rx_data ) *(vsebina++) = *(tmp_substr++);

*vsebina = 0; // Dodaj null-char na koncu

ali
Koda:
// Rezerviraj prostor za vsebino

vsebina = (char*)malloc( length );

// Zascitis, da ne vgre cez dovoljene meje

vsebina[--length] = 0; // length je >= 1

// Prekopiraj vsebino

while(length--) vsebina[length] = tmp_rx_data[length];

ali
Koda:
// Rezerviraj prostor za vsebino

vsebina = (char*)malloc( length  );

// Zascitis, da ne vgre cez dovoljene meje

vsebina[--length] = 0; // length je >= 1

// Prekopiraj vsebino

memcpy(vsebina, rx_data, length);

Avtor: arksiKraj: Dolenjska PrispevekObjavljeno: Tor Dec 23, 2014 8:07 am    Naslov sporočila:  
----------------------------------------------------------------------------
>>nekaj mesecev kasneje<<

Zanima me, ali ostaja v jeziku C kakšna funkcija, ki bi decimalni rezultat zaokrožila na določeno število decimalk. Programiram atmega328P.

Npr.: vrednost 2.12345 bi rad zaokrožil na eno decimalno mesto 2.1.

LP

Avtor: MitjaNKraj: Ljubljana PrispevekObjavljeno: Tor Dec 23, 2014 8:44 am    Naslov sporočila:  
----------------------------------------------------------------------------
ans = ((float)((long)(2.12345 * 10 + 0.5)))/10;

Avtor: arksiKraj: Dolenjska PrispevekObjavljeno: Pet Feb 13, 2015 10:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Mar 07, 2016 9:28 am    Naslov sporočila:  
----------------------------------------------------------------------------
Mene pa zanima, če je že kdo zasledil enostavnejšo softversko rešitev, ki bi bila podobna hardverski "pin change interrupt" oz. hardverski prekinitvi na rising / falling edge?
Sedaj to softversko delam z if stavki in postavljanjem / brisanjem vsaj dveh zastavic / spremenljivk, ki jih potem zopet preverjam. Skratka kar nekaj IF-ov in vsaj ena spremenljivka.

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Pon Mar 07, 2016 9:33 am    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
Mene pa zanima, če je že kdo zasledil enostavnejšo softversko rešitev, ki bi bila podobna hardverski "pin change interrupt" oz. hardverski prekinitvi na rising / falling edge?
Sedaj to softversko delam z if stavki in postavljanjem / brisanjem vsaj dveh zastavic / spremenljivk, ki jih potem zopet preverjam. Skratka kar nekaj IF-ov in vsaj ena spremenljivka.


Če si shraniš trenutno stanje PIN registra v eno spremenljivko, lahko preveriš v while zanki, ali se je vrednost spremenila glede na shranjeno.

Če se je, narediš XOR z staro vrednostjo in dobiš rezultat, ki ima bite na 1 tam, kjer se je stanje zamenjalo.

Potem pa pač preveriš stanje PIN registra glede na to, kateri bit imaš postavljen na 1 v rezultatu XOR operacije.

Tukaj, poglej "Primeri" pri vaji za tipke (vaja 4)

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Mar 07, 2016 12:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
THX, to je malce lažje in bolj razumljivo od tistega, kar sem do sedaj počel. Bom pa še malce preštudiral.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Maj 06, 2016 11:21 am    Naslov sporočila:  
----------------------------------------------------------------------------
Ponovno imam eno vprašanje:

Programiram mego8 in imam recimo 4 spremenljivke tipa uint8_t, se pravi unsigned char. Ta normalno sprejme vrednost 0-255. Ker gre v mojem primeru za časovne spremenljivke, se njihova vrednost giblje 0-23 za ure in 0-59 za minute.

Potem pa v if stavku, kot je prikazano v primeru:
Koda:

if (((hour*100+min)    <  (ALhourOFF2*100 + ALminOFF2))


vrednost ur pomnožim s 100 in prištejem minute. Npr ura 10:00 bi tako postala vrednost 1000.

Ali pa je to resnično, ali pa primerjalna vrednost (ZANIMA ME SAMO V IF STAVKU) zaradi uporabe Uchar-a naredi večkratni rollover in tako v danem primeru dobi stanje 232:

Koda:

1000 = 0b11111101000
 232 = 0b   11101000


S sprintf sem sicer vrednost prikazal na LCD in dobim lepo 1000, ampak sprintf mogoče naredi kaj "po svoje" in nisem nikakor 100%, kateri rezultat je za mego tisti pravi... Think 1000 ali 232 Think

Avtor: dgrudeKraj: Velike Lašče PrispevekObjavljeno: Pet Maj 06, 2016 11:53 am    Naslov sporočila:  
----------------------------------------------------------------------------
Vrednost 232 dobiš zato, ker mega računa z 8 bitno spremenljivko(kot vidiš je spodnjih 8 bitov pravilnih). V if stavku spremenljivko castaj v 16 bit-no pa bo zadeva delovala po pričakovanjih.

Takole bi moralo delovati:

if ((((uint16_t)hour*100+min) < (ALhourOFF2*100 + ALminOFF2))

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Maj 06, 2016 12:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Aha hvala. Bom poskusil po predlogu. Sicer mi že brez tega preverjanje časovnikov deluje (tako preko palca) ampak dejansko pa ne vem, kaj pravzaprav v resnici primerja. sedaj vem, da napačne vrednosti, ki so pravzaprav po naključju vse enako napačne in zato ustrezne Smile

Think

Sem še malo potestiral. V primeru rolloverja bi potem morala biti ura 2:57 (željena vrednost 257) popolnoma enaka kot rollover na čas 00:02 (vrednost 257-255 = 2). Ampak vseeno zgleda da se rollover ne zgodi Think
Skratka, program se obmaša kar enako če castam z uint16_t ali pa ne... Mogoče pa že kompiler naredi tisto, kar bi moral jaz "na roke" Think

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Avg 10, 2016 1:38 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ponovno imam eno vprašanjce....

Želim narediti menu, ki ima recimo 6 elementov, izbor vsakega nekaj naredi. To deluje.

Rad pa bi naredil neke vrste menijski prikaz, kjer menije izbiraš z enkoderjem.
Torej, podmenijev je recimo 6, na LCD imam 4 vrstice za prikaz. Ali obstaja nek način, da besedila (naslove) menijev spravim v spomin, potem pa glede na vrtenje enkoderja (od 1-6) prikažem na LCD ekranu tisti naslov menija z določeno številko?

Nekaj podobnega kot na risbi v prilogi

Malce sem gledal po netu, pa mi stvari niso jasne:
- Zasledil pa sem nekaj s "struct" ukazom.
- ali se da kaj narediti s kazalci (do sedaj jih še nisem uporabljal Whistle Angel )

Če mi kdo lahko nakaže smer rešitve bi bil hvaležen.


Nazadnje urejal/a lojzek Sre Avg 10, 2016 1:41 pm; skupaj popravljeno 1 krat

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Sre Avg 10, 2016 1:40 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Imaš array pointerjev na stringe, ki jih prikažeš.
Imaš potem enkoder, ki z njim kontroliraš spremenljivko.

Ta spremenljivka gre v tvojem primeru od 0 do 2 in predstavlja, kater string se začne na vrhu LCD-ja.

Če je x = 0, potem prikažeš prve 4,
če je x = 1, potem prikažeš drugo, tretjo, četrto, peto
če je x = 2, potem prikažeš zadnje 4.

Je jasno?

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Avg 10, 2016 1:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
To je bilo pa neverjetno hitro Very Happy

tilz0R je napisal/a:
Imaš array pointerjev na stringe, ki jih prikažeš.



Kako pa te stringe spravim v spomin (da vem kateri je 1., ... in kateri zadnji)?

Kako ustvarim array pointerjev?

Kako potem pokličem pravi pointer?

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Sre Avg 10, 2016 1:51 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Tako nekako.

Koda:

//Seznam stringov
char * stringi[] = {
    "string1",
    "string2",
    "string3",
    "string4",
    "string5",
    "string6",
};

//Print vrstic, pac neka funkcija, prvi parameter je vrstica na LCD, drugi kaj naj sprinta
int i = 0;
print_vrstica(1, stringi[i]);
print_vrstica(2, stringi[i + 1]);
print_vrstica(3, stringi[i + 2]);
print_vrstica(4, stringi[i + 3]);


Poskrberi moraš, da je i med 0 in 2, manj ne, več pa tudi ne.

lpTM

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Čet Avg 11, 2016 10:56 am    Naslov sporočila:  
----------------------------------------------------------------------------
Very Happy Princip deluje! Prvič sem uporabil arraye in pointerje in vse kaže, da jih bom počasi zastopil.

Tilzor, thx Smile

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Avg 26, 2016 1:02 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hja.... še vedno problemi z menujem. Po nebroj poizkusih sem najverjetneje ugotovil težavo, ne pa rešitve...

V eni funkciji: void (Menu) imam deklaracijo spremenljivk za meni (gornji posti) definirano takole:

Koda:


char *Naslov[] =
   {
   //01234567890123456789
   "            ",
   "1-Izhod     ",
   "2-Obrat. ure",
   "3-Temperat. ",
   "4-Ura       ",
   "5-Casovniki ",
   "6-Kalibrac. ",
   "7-Auto Send ",
   };


Delovanje programa menija sicer v nadaljevanju funkcije deluje.

Sedaj pa problem:

V naslednji funkciji: void (obratovanje) pa imam zopet definirano spremenljivko za drugačen meni na popolnoma enak način.

Koda:

char *Naslov[] =
   {
   //01234567890123456789
   "          ",
   "1-Izhod   ",
   "2-Izklop  ",
   "3-Rocno   ",
   "4-Tedensko",
   "5-Datum   ",
   };


in tudi program funkcije funkcionira tako, kot je treba.

Ampak.... če v celotnem programu prevedem obe funkciji, mi to zmeša vrednosti vseh ostalih spremenljivk v vseh delih programa in program kot celota napačno deluje. Ne glede na to, da ne pokličem v izvajanje nobene od teh dveh menijskih funkcij.

Če prevedem samo eno (katerokoli) od teh menijskih funkcij, program kot celota deluje v redu.

Zato po mukotrpnem preizkušanju in poizkušanju slklepam, da "besedilnih" spremenljivk ne definiram prav...

Torej, kako je prav? Sem že poizkusil z različnimi imeni (Naslov1 in Naslov2), pa ni haska..

Avtor: rafaellsiKraj: Radovljica PrispevekObjavljeno: Pet Avg 26, 2016 2:26 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Da ti mogoče ne primankuje spomina?

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pet Avg 26, 2016 9:06 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pomislil sem tudi na to.... Mego 168 imam (po avr studiu) zapolnjeno do 14kB spomina (od 16kB) in max 950B (od 1kB) spremenljivk... Po AVR studiu pri prevodu oboje manj kot 100% Think

Imam še enega 328... Bom v ponedeljek poskusil še s tem, če bo kaj bolje.

Res pa je, da še nikdar taaako obsežnega programa in toliko spremenljivk še nisem skupaj sklamfal....

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Ned Avg 28, 2016 10:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
...in max 950B (od 1kB) spremenljivk...

V RAM se ne shranjujejo samo spremenljivke, pozabil si na stack.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Avg 29, 2016 8:15 am    Naslov sporočila:  
----------------------------------------------------------------------------
Če bi uporabil 328, bi moral program predelat.... Samo s prevodom programa zanjo ne deluje.

Bom moral ostati pri 168...

@Domenius: Ali lahko laično razložiš tvoj post...? Think Ali se poleg tega, kar AVR Studio napiše, v RAM naloži še nekaj?


Nazadnje urejal/a lojzek Pon Avg 29, 2016 8:20 am; skupaj popravljeno 1 krat

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Pon Avg 29, 2016 8:17 am    Naslov sporočila:  
----------------------------------------------------------------------------
RAM je uporabljen za globalne in lokalne spremenljivke.

Globalne spremenljivke so tiste, ki so deklarirane izven funkcij, medtem, ko so lokalne tiste, ki so znotraj njih deklarirane.

Te spremenljivke (lokalne) se shranjujejo na "Stack" (slovensko "Sklad"), ki je del RAM-a, kar ti AVR studio ni štel v izračunu ker za to potrebuje izračunat celoten call stack upoštevajoč interrupt rutine v vsakem momentu.

Lahko se je zgodilo, da si šel s stackom izven memory-ja RAM-a in je vse začelo delovati po svoje.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Avg 29, 2016 12:22 pm    Naslov sporočila:  
----------------------------------------------------------------------------
tilz0R je napisal/a:

Te spremenljivke (lokalne) se shranjujejo na "Stack" (slovensko "Sklad"), ki je del RAM-a, kar ti AVR studio ni štel v izračunu ker za to potrebuje izračunat celoten call stack upoštevajoč interrupt rutine v vsakem momentu.


To zna biti tisto....

Prevajalnik mi izvrže naslednje....
Koda:

Device: atmega168p

Program:   13596 bytes (83.0% Full)
(.text + .data + .bootloader)

Data:        964 bytes (94.1% Full)
(.data + .bss + .noinit)


Build succeeded with 106 Warnings...


Tisti Warningi so predvsem pri izpisu tekstov... malce zbrke med unsigned in signed spremenljivkami - dosedaj še niso motili izvajanja programa.

Če torej nekaj spremenljivk (te v zgornjih postih omenjene tekstualne in zato velike okoli 50 Bytov) zaradi izvajanja programa mora še nekam shranjevat, pa torej lahko del že prej shranjenih spremenljivk "povozi" Think ?

Torej je bolje, da te največje (besedila) reorganiziram in definiram globalno?

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Pon Avg 29, 2016 12:28 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Gre nekako tako.

Imaš na voljo 1k rama in tvoje spremenljivke globalne kurijo 950B RAM-a.
Torej imaš za stack na voljo še recipiši 74Bytov.

Vsak klic funkcije znotraj druge funkcije dodatno obremenjuje stack. Če ga zasedeš, torej celih 74Bytov pushneš na stack (na stack gredo lokalne spremenljivke, delovni registri, pa še kaj).

Ko pushneš na stack zadeve se povečuje zasedenost. Če stack prekoračiš, si v območju kjer ni RAM-a (v ARM Cortex bi te čakal HardFault error) in ko nazaj pop-neš dol imaš neznane vrednosti na stacku, ki je izven RAM-a.

Po domače bi lahko rekli, da se povozi RAM.


Nazadnje urejal/a tilz0R Pon Avg 29, 2016 1:18 pm; skupaj popravljeno 1 krat

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Avg 29, 2016 1:16 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Hvala za lepo domačo razlago.

Torej bom program primoran optimirati predvsem v smislu spremenljivk in njih uporabe. Na žalost sem program že skoraj v celoti spisal, tako da bo dela malo več. Bom vedel za naslednjič.

Avtor: integrercKraj: Novo mesto PrispevekObjavljeno: Čet Nov 24, 2016 7:59 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni!
Prešel na AVR studio 6, WinAVR.
Težava, ki jo nikakor ne morem rešiti je sledeča.....
Ko hočem uporabiti v svojem projektu npr. lcd knjižnico (ki jo dodam v projekt), mi ob prevajanju javi napak.... lcd_lib.h: no such file or directory
Knjižnica seveda obstaja v failu in bi morala delovati, je tudi zdefinirana v samem programu (#define <lcd_lib.h>).
Prosim za pomoč, kaj delam narobe?
LP!

Avtor: matjazkariz PrispevekObjavljeno: Čet Nov 24, 2016 9:50 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Namesto define napiši include in namesto<> daj "", če je header v isti mapi kot ostale datoteke projekta.

Avtor: integrercKraj: Novo mesto PrispevekObjavljeno: Čet Nov 24, 2016 9:54 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ja, ja saj sem dal #include in z narekovaji sem poizkusil, pa je isto...

Avtor: JanKraj: Dolenjska PrispevekObjavljeno: Čet Nov 24, 2016 10:01 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Imaš mogoče kakšne presledke v imenu poti projekta?
Če jih imaš, prestavi projektno mapo direktno na C:\ in poskusi, če bo isto.

Jan

Avtor: integrercKraj: Novo mesto PrispevekObjavljeno: Čet Nov 24, 2016 11:48 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ne nimam presledke v imenu poti , poskusil sem dat projekt direktno na C: in je ista "figa"....očitno delam nekaj narobe...v solution explorerju dodam z ADD knjižnjico, .c in .h, potem pa izberem "build" in mi pokaže zgoraj omenjen error.

Error 1 lcd_lib.h: No such file or directory C:\Users\Andrej\Documents\Atmel Studio\vajeatmelstudio\vajadelamojstra\vajadelamojstra\lcd.lib.c

Avtor: DomeniusKraj: Trbovlje, LJ PrispevekObjavljeno: Pet Nov 25, 2016 9:23 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pot (path) imaš kar dolgo, mogoče bi jo bilo dobro skrajšati - sem že imel probleme. Tudi šumnike in presledke odsvetujem - vem da jih nimaš, govorim na splošno. Pa napisal si lcd_lib.c, tam kjer imaš pot pa imaš napisano lcd.lib.c. Se pravi da bi bilo pravilno #include "lcd.lib.h".

Avtor: integrercKraj: Novo mesto PrispevekObjavljeno: Pet Nov 25, 2016 10:51 am    Naslov sporočila:  
----------------------------------------------------------------------------
Hm, ne vem kako, ampak res je, ime knjižnjice je bil lcd.lib v sami knjižnjici pa je imenovana lcd_lib. Spremenil sem ime knjižnice na lcd_lib in očitno bo v redu, error-a ni več.
Bom pa proti večeru preizkusil, če dela tudi funkcionalno.
Hvala, lp!

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sob Nov 26, 2016 9:12 am    Naslov sporočila:  
----------------------------------------------------------------------------
To je copy/paste iz mojega programa:
Koda:
#include <avr\io.h>
#include <avr\interrupt.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdio.h>
#include "lcd_lib.c"
#include "twi.c"
#include "definicije.h"
//#include "nrf24l01.c"
//#include "spi.c"


Tisti z <> so datoteke nekje v Atmelovem oz. WinAvr jevih direktorijih, tisti z " " pa so v mapi, kjer imam trenutni projekt.
Pa poskusi pisat datoteke brez dvojnih pik : lcd.lib.c ampak malo drugače, npr lcd_lib.c (ali pa s končnico .h)

Avtor: integrercKraj: Novo mesto PrispevekObjavljeno: Sob Nov 26, 2016 11:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
Bom upošteval napisano lojzek.
Vprašal bi še, kakšen programator naj uporabim?
Do sedaj sem uporabljal Proggy od Svet elektronike, vendar pa mi v AVR studio 6 ne deluje.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Feb 25, 2020 9:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni,

Sedaj se mučim z eno težavico, ki jo sicer znam rešiti z nekaj if () stavki, ampak mislim da se da to lepše rešiti z XOR, vendar mi rešitev noče v glavo.

Torej, v enem bajtu imam dva bita, za katera me zanima, če sta enaka (oba 0 ali oba 1 - vrne recimo 1) ali različna - vrne recimo 0.

primeri- vsaka vrstica me zanima primerjava z "x" označenih bitov:
Koda:


   xx 
00011000 == 1
00000000 == 1
00010000 == 0
00001000 ==0


Gre se pa za priklop malega enkoderja, da bi ugotovil smer.

moj primer, ki me muči:
Koda:
SIGNAL (INT1_vect)
{   
//bitno preverjanje bitov enkoderja
   //Enaka == ena smer, različna == druga smer

if (PIND & (1 << PD3) ^ PIND & (1 << PD4))
   ++Gor;
   else ++Dol;
}

Avtor: SilvoKraj: Koroška-okolica Dravograda PrispevekObjavljeno: Tor Feb 25, 2020 9:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Citiram:
Gre se pa za priklop malega enkoderja, da bi ugotovil smer.


V C-ju ti ne znam pomagat. V assemblerju jaz naredim tako da "eno sled" enkoderja dam na pin zunanje prekinitve. Recimo, da se prekinitev sproži ob padajoči fronti. V prekinitveni rutini pa preverjam stanje drugega vhoda. Visoko stanje ena smer nizko stanje druga smer.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Feb 25, 2020 10:21 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ja, saj tako sem imel pri prejšnjem enkoderju.
Je bil očitno drugačen - ker je vgrajen in v uporabi, pa ne morem preverit. In njegov "program" je lepo deloval.

Ta pa ima pri zasuku enkoderja za en zob levo najprej spremembo izhoda A na 1, ki ji sledi B na 1. Pri drugem zobu vrtenja v levo pa se A spremeni na 0 in ji sledi B na 0.
Tako jih moram preverjat pri "enkah" ki jim sledijo enke, in "nulah" ki jim sledijo nule. Drugače moraš za spremembo dveh številk zavrteti za 4 zobce.

Mislil sem na XOR, kajti obe enaki vrednosti bitov pomenita eno smer, različni pa drugo.

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Tor Feb 25, 2020 11:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Naredi nasko ki ima oba bita na 1 in potem rezultat registra primerjaj z masko.

If ((register & maska) == maska)

Nastavi masko na oba bita 1 in boš vedel kdaj sta oba na 1.

Avtor: SilvoKraj: Koroška-okolica Dravograda PrispevekObjavljeno: Tor Feb 25, 2020 11:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Vsi enkoderji - tudi industrijski (vsaj tiste, ki jih poznam) imajo sled A in B zamaknjeno za 90° industrijski imajo običajno še sled "Z" ter vse signale tudi negirane.
Za določetev smeri vrtenja pač vzameš eno sled in jo primerjaš z drugo v trenutku, ko se ta spremeni torej če je pri dvigajoči fronti stanje visoko pri padajoči pa nizko se je zavrtelo za en "zob" v eno stran, če je stanje pri dvigajoči enako padajoči se je ostalo na istem mestu enako gre za drugo stran.
Tukaj je lepa simulacija.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Feb 26, 2020 11:47 am    Naslov sporočila:  
----------------------------------------------------------------------------
@tilzor: to bom pa poskusil, ker tak primer mislim da je večkrat uporaben. Vse take uporabne stvari si po preizkusu zapišem in kasneje laže najdem. Take enostavne rešitve včasih človek niti ne opazi.

@Silvo, tisto simulacijo na Wikiju sem že videl. In moj tudi dela tako, če ga preizkusim z lučkami.

Nekako sem pa tudi slutil, da me malo debouncing heca. Sem ga hotel kasneje reševati.
Zato sem se pa lotil "kopanja" po načrtih naprave, kjer do sedaj uporabljam prvi in edini enkoder Ter videl, da imam hardverski debouncing (R+C). Ta ploščica, ki sem jo kupil ima pa samo pullup upore. Torej najprej hardver urediti, nato pa naprej. Mogoče bo že preizkušena rešitev delovala.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Feb 26, 2020 11:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
Evo, tule je delujoča koda in delujoča shema. Samo ne vem, katero verzijo sem (že) uporabil.... Think
Koda:
//prekinitev - vrtenje enkoderja
SIGNAL (INT1_vect)
{
if (PIND & (1 << PD4))
   ++Gor;
   else ++Dol;
Neaktiv = 0;
}

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Feb 26, 2020 2:33 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Rešitev... Najprej hardverski debounce, potem je koda prejšnjega posta začela delat. Sprememba števca na vsak drugi zobec (res imam prejšnji enkoder drugačen Think )
Zanjo je bila prekinitev INT1 nastavljena na padajoči rob signala...


Tole je pa nova delujoča koda:

Koda:
//prekinitev - vrtenje enkoderja
SIGNAL (INT1_vect)
{   
if (!(PIND & (1 << PD3)) && PIND & (1 << PD4) || PIND & (1 << PD3) && !(PIND & (1 << PD4)))
   ++Gor;
   else  ++Dol;
Neaktiv = 0;
}


Zanjo je treba pa nastaviti PinChange interupt na INT1

Samo nisem imel 10n kondijev, pa sem dal 100n. in ne moreš vrteti prehitro Smile debounce premočan... bom to uredil

Hvala za debato in pomoč.

Stran 1 od 1

Powered by phpBB © 2001,2002 phpBB Group