www.elektronik.si
Začetniški problem v C-ju pri AVR-ju
Pojdi na stran Prejšnja  1, 2, 3 ... 22, 23, 24, 25, 26, 27  Naslednja  :||:
www.elektronik.si -> Osnove programiranja AVR-jev

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);

Stran 23 od 27

Powered by phpBB © 2001,2002 phpBB Group