|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
gregoral Član
Pridružen-a: Pet 24 Nov 2006 9:42 Prispevkov: 688 Aktiv.: 3.25 Kraj: Ljubljana
|
Objavljeno: Čet Feb 18, 2010 6:23 pm Naslov sporočila: |
|
|
O typecastingu imaš ogromno materiala.
Princip pri vseh prevajalnikih je (v osnovi) tak: vsaka 'spremenljivka' ima tip in naslov
Globalne spremenljivke imajo statične naslove (odvisno od uC). Recimo:
static int i = 0;
to spremenljivko bo prevajalnik dal na nek naslov v pomnilniku.
unsigned int address = (unsigned int)&i;
v address imaš zdaj naslov kjer je shranjana vrednost spremenljivke i (recimo da je to 512)
kazalec na i zdaj lahko dobiš na več načinov:
int* p = (int*)address;
int* q = &i;
int* r = (int*)512;
Predvsem pa ne pozabi na sledeče:
- osnovni tipi so razlkičnih dolžin na različnih procesorjih (1, 2, 4, 8 bytov) (int ni vedno 4 byte)
- pointerji so tudi različnih dolžin (8, 16, 32, 64 bitov) (int* ni vedno 4 byte)
- data alignment
nekateri procesorji zahtevajo da so:
- 2 bytne sremenljivke na naslovih deljivih z 2
- 4 bytne sremenljivke na naslovih deljivih z 4
- ...
- bigendian/littleendian
kadar želiš dostopati do int byte po byte so byte-i v pomnilniku v različnem vrstnem redu
--------------------------------------------------------------
About Data Alignment
http://msdn.microsoft.com/en-us/library/ms253949(VS.80).aspx
Endianness
http://en.wikipedia.org/wiki/Endianness
Typecasting an Array - C++ Forums
www.cplusplus.com/forum/general/160/
LP, Gregor |
|
Nazaj na vrh |
|
|
clownfish Član
Pridružen-a: Pet 05 Avg 2005 13:05 Prispevkov: 764 Aktiv.: 3.43 Kraj: Povir / Ljubljana
|
Objavljeno: Čet Feb 18, 2010 11:51 pm Naslov sporočila: |
|
|
"gregoral"
Vsaka čast!!
Kot vidim bom imel še precej za naštudirat!
HVALA! |
|
Nazaj na vrh |
|
|
clownfish Član
Pridružen-a: Pet 05 Avg 2005 13:05 Prispevkov: 764 Aktiv.: 3.43 Kraj: Povir / Ljubljana
|
Objavljeno: Pon Mar 15, 2010 12:52 am Naslov sporočila: |
|
|
V povezavi z prejšnjim vprašanjem in odgovorom imam še eno vprašanje..
V spominu imam polje strukture, ki vsebuje različne tipe podatkov. Od bitnih, pa unsigned char do int in tudi long.
In ko kontroler zazna "power down" bi želel te podatke iz ram-a shraniti v eeprom na nek naslov in ob power-up-u spet obnoviti podatke v vsakem elementu polja-strukturi iz eeproma.
Jasno je varianta, da za vsak tip podatka napišem svojo rutino, ki tak podatek vpisuje v eeprom, zanima pa me kako bi se to dalo drugače sprogramirati?
Torej bi rabil rutino ki bi prebrala elemente polja strukture in vse skupaj shranila v eeprom od nekega naslova naprej...
Ideje? |
|
Nazaj na vrh |
|
|
gumby Član
Pridružen-a: Sob 28 Apr 2007 12:32 Prispevkov: 4066 Aktiv.: 19.67
|
Objavljeno: Pon Mar 15, 2010 8:04 am Naslov sporočila: |
|
|
Lahko uporabiš kazalec na strukturo in sizeof(), če prevajalnik podatke nameče na zaporedne lokacije v pomnilnik. _________________ Tule nisem več aktiven. |
|
Nazaj na vrh |
|
|
clownfish Član
Pridružen-a: Pet 05 Avg 2005 13:05 Prispevkov: 764 Aktiv.: 3.43 Kraj: Povir / Ljubljana
|
Objavljeno: Pon Mar 15, 2010 12:09 pm Naslov sporočila: |
|
|
gumby je napisal/a: |
Lahko uporabiš kazalec na strukturo in sizeof(), če prevajalnik podatke nameče na zaporedne lokacije v pomnilnik. |
Hmm...to že vendar ne vem kaj oziroma kako bi si z tem pomagal?
??
Torej kazalec na strukturo mi bo dal lokacijo kje so podatki, "sozeof" pa vrnil velikost strukture v bytih? potem pa iz teh dveh podatkov napišem rutino, ki byte po byte shrani strukturo v eeprom?
?? |
|
Nazaj na vrh |
|
|
gumby Član
Pridružen-a: Sob 28 Apr 2007 12:32 Prispevkov: 4066 Aktiv.: 19.67
|
Objavljeno: Pon Mar 15, 2010 2:22 pm Naslov sporočila: |
|
|
teslo je napisal/a: |
Torej kazalec na strukturo mi bo dal lokacijo kje so podatki, "sozeof" pa vrnil velikost strukture v bytih? potem pa iz teh dveh podatkov napišem rutino, ki byte po byte shrani strukturo v eeprom? |
Točno tako... rabiš kazalec na prvo lokacijo in dolžino strukture, toliko bajtov potem zapišeš v EEPROM. Problem je, ker je v mikrokrmilniku precej malo RAM-a in ni nujno, da bo prevajalnik uporabil zaporedne lokacije. Sicer lahko greš gledat ASM kodo, ampak tule spet ni nujno, da bo pri naslednjem prevajanju enaka...
Ena varianta je še, da uporabiš fiksne RAM naslove, prevajalniku pa nekako dopoveš, da jih ne uporablja za kaj drugega.
Tretja, po moje edina "ziher" varianta, je pa svoja funkcija za vsako strukturo (oz. ena funkcija, ki iz več struktur zapiše v EEPROM, kar pač mora). _________________ Tule nisem več aktiven. |
|
Nazaj na vrh |
|
|
clownfish Član
Pridružen-a: Pet 05 Avg 2005 13:05 Prispevkov: 764 Aktiv.: 3.43 Kraj: Povir / Ljubljana
|
Objavljeno: Tor Mar 16, 2010 2:18 am Naslov sporočila: |
|
|
No tole sem iskal.. Mislim da bo ša marsikomu prav prišlo.
Koda: |
unsigned long longspr; |
Koda: |
longspr=2038070140; |
je enako temu spodaj
Koda: |
//vpis v byte spremnljivke tipa unsigned long - longspr
*((unsigned char *)(&longspr)+3)=121; //MSB
*((unsigned char *)(&longspr)+2)=122; //
*((unsigned char *)(&longspr)+1)=123; //
*((unsigned char *)(&longspr)+0)=124; //LSB
|
enako deluje branje..
torej velja za spremenljivko unsigned int - uint
Koda: |
*((unsigned char *)(&uint)+1)=123; //
*((unsigned char *)(&uint)+0)=124; //LSB |
Sedaj samo še napišem funkcijo kateri za parameter podam pointer na strukturo
in v sami funkciji v eeprom vpišem byte iz spremenljivk strukture v eeprom..
V drugi funkciji pa podatke preberem iz eeproma in jih napolnim v strukturo |
|
Nazaj na vrh |
|
|
clownfish Član
Pridružen-a: Pet 05 Avg 2005 13:05 Prispevkov: 764 Aktiv.: 3.43 Kraj: Povir / Ljubljana
|
Objavljeno: Ned Jul 04, 2010 9:23 am Naslov sporočila: |
|
|
Delam program, ki bo detektiral power down napajanja in mi poslal sms, kdaj je prišlo do izpada in koliko časa že traja izpad napajanja... če se napajanje povrne dobim sms o trajanju izpada in času kdaj se je napajanje povrnilo..
trenutno delovanje testiram tako, da pošiljam string in ga na Pc-ju berem preko RS232..
nekaj čudnega se mi dogaja in si zadeve ne znam logično razložiti..
v main programu imam kodo..
Koda: |
char sms [100]="";
send_msg("Prvi SMS - PRVA REAKCIJA ");
....
send_msg("Prvi SMS - PRVA REAKCIJA "); |
************************************************
sam rutina send_msg pa dela sledeče..
Koda: |
void send_msg(char *sms)
{
strcat (sms, " Ura: ");
str_ura(clock_to_long(), sms);
strcat (sms, " ALARM Power DOWN at: ");
str_ura(zacetni_cas_izpada, sms);
strcat (sms, " Trajanje izpada: ");
str_ura((clock_to_long() - zacetni_cas_izpada), sms);
poslji_msg(sms);
} |
Torej iz main programa dobim kazalec na string in v stringu je že "nekaj".
Nato v ta string dodam še trenutno uro, začetni čas izpada in trajanje izpada
čerav je koda po mojem mnenju popolnoma pravilna na izhodu dobim.. nič..
kot kaže se na koncu zgenerira string, ki je prazen ??
tale rutina spodaj pa najprej skopira en string v drugega in potem v lokalni string doda te podatke in to dela popolnoma pravilno.. pravilno izpiše..
************************************************
sam rutina send_msg pa dela sledeče..
Koda: |
void send_msg(char *[color=red]sms1[/color])
{
char sms[100]=" ";
strcpy (sms, [color=red]sms1[/color]);
strcat (sms, "Clock: ");
str_ura(clock_to_long(), sms);
strcat (sms, " ALARM Power DOWN at: ");
str_ura(zacetni_cas_izpada, sms);
strcat (sms, " Trajanje izpada: ");
str_ura((clock_to_long() - zacetni_cas_izpada), sms);
poslji_msg(sms);
} |
tega ne razumem...
Tudi če pa uporabim tole spodaj rutino..
ta pravilno izpiše string, ki sem ga poslal iz main-a..
************************************************
Koda: |
void send_msg(char *sms)
{
poslji_msg(sms);
} |
torej v samo rutino- podprogram pride pravilen string a čim v ta string nekaj dodajam ga zbriše.. oziroma nekako pokvari..
Če pa sting ki ga dobim v rutino najprej skopiram v drug lokalen string in v tega dodajam.. dela popolnoma pravilno..
v katerem grmu tiči zajec ?? |
|
Nazaj na vrh |
|
|
gregoral Član
Pridružen-a: Pet 24 Nov 2006 9:42 Prispevkov: 688 Aktiv.: 3.25 Kraj: Ljubljana
|
Objavljeno: Pon Jul 05, 2010 1:05 pm Naslov sporočila: Ja kaj ga pa serješ :) |
|
|
Poglej si:
- kam in kako se shranjujejo konstante
- kaj pomeni če ima parameter isto ime kot globalna spremenljivka
Torej konstante ("Prvi SMS - PRVA REAKCIJA ") so shranjene nekje v epromu:
Koda: |
C1_____C2________________________C3______________C4
TEKST\0Prvi SMS - PRVA REAKCIJA\0NEK DRUG TEKST\0TRETJI\0
|
zložene so ena za drugo, vsak string je zaključen z \0 (null character) (en byte za ascii stringe in dva če je string multibyte string (unicode)), ker so stringi v C in C++ null terminirani. In če si dal naslov konstante (const char *) kot parameter v funkcijo (char *) (verjetno je že prevajalnik kaj jamral), potem seveda poskušaš pisat po lokaciji kjer imaš tudi druge konstante, zato se ne čudi če stvar ne dela kot bi morala.
Koda: |
char sms [100]="";
void send_msg(char *sms)
{
//tu notri se globalna spremenljivka sms ne vidi!!
//tukaj je sms pač pointer na char ki si ga dal kot parameter funkciji
}
|
Pa vzami kakšno knjigo o C v roke in osnove funkcij in spremenljivk prouči!
LP, Gregor |
|
Nazaj na vrh |
|
|
davide Član
Pridružen-a: Pet 10 Sep 2010 16:45 Prispevkov: 149 Aktiv.: 0.90 Kraj: Savinjska
|
Objavljeno: Pet Feb 25, 2011 12:03 am Naslov sporočila: |
|
|
http://extremeelectronics.co.in/avr-projects/avr-project-relay-timer-with-atmega8-avr-mcu/
Na zgornjem linku je projekt, kateraga želim v prihodnje izdelati.
V programskem jeziku sem zelo šibek, izdelal sem kakšne enostavne
programe za kakšen senzor ali kj podobnega, sedaj pa bi se lotil tega projekta malo za hobij in bi prosil nekoga, če mi lahko kodo programa, ki je na zgornjem linku, mogoče malo po vrsticah razloži, kaj kateri ukaz pomeni, ker je zelo veliko ukazov, ki jih ne poznam, oz. so zame novi.
Gre pa po eni strani za dokaj preprosto zadevo, relay timer, vendar ne razumem ravno teh pomikov pri izbiri časa zakasnitve izklopa in podobno.
Hvala |
|
Nazaj na vrh |
|
|
davide Član
Pridružen-a: Pet 10 Sep 2010 16:45 Prispevkov: 149 Aktiv.: 0.90 Kraj: Savinjska
|
Objavljeno: Ned Mar 06, 2011 5:27 pm Naslov sporočila: |
|
|
Mi lahko mogoče kdo na hitro obrazloži iz zgornjega linka, kaj se pravzaprav dogaja v naslednjih korakih, ki sem jih prilepil.
Kaj se z samim programom dogaja razumem, ampak od vrstice do vrstice v tem prvem delu kode mi ni ravno najbolj razumljivo, mogoče se da to enostavneje opisati??
Hvala!
//Connection of Load
#define LOAD_DDR DDRC
#define LOAD_PORT PORTC
#define LOAD_POS PC0
//Global variable for the clock system
volatile unsigned int clock_millisecond=0;
volatile char clock_second=0;
volatile char clock_minute=0;
volatile char clock_hour=0;
void Wait(uint8_t n)
{
uint8_t i,temp;
temp=n*28;
for(i=0;i<temp;i++)
_delay_loop_2(0);
}
void LoadOn()
{
LOAD_PORT|=(1<<LOAD_POS);
}
void LoadOff()
{
LOAD_PORT&=(~(1<<LOAD_POS));
}
main()
{
while(1)
{
LOAD_DDR|=(1<<LOAD_POS);
LoadOff();
//Enable Pullups on Keypad
PORTB|=((1<<PB2)|(1<<PB1)|(1<<PB0));
int8_t hr,min; //Target Time
hr=min=0;
//Initialize the LCD Subsystem
InitLCD(0);
//Clear the display
LCDClear();
//Set up the timer1 as described in the
//tutorial
TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10);
OCR1A=250;
//Enable the Output Compare A interrupt
TIMSK|=(1<<OCIE1A); |
|
Nazaj na vrh |
|
|
bostjang Član
Pridružen-a: Tor 03 Jan 2006 15:29 Prispevkov: 3174 Aktiv.: 14.25 Kraj: Postojna
|
Objavljeno: Ned Mar 06, 2011 6:03 pm Naslov sporočila: |
|
|
O C-ju je ogromno literature, najbolje, da se tam izobraziš.
Če ti potem ne bo kaj jasno, pa vprašaj. |
|
Nazaj na vrh |
|
|
davide Član
Pridružen-a: Pet 10 Sep 2010 16:45 Prispevkov: 149 Aktiv.: 0.90 Kraj: Savinjska
|
Objavljeno: Ned Mar 06, 2011 9:14 pm Naslov sporočila: |
|
|
Predvsem ta del me zanima, kjer so uporabljeni ukazi LOAD_PORT|=(1<<LOAD_POS), ter zakaj je pomnoženo temp=n*28.
void Wait(uint8_t n)
{
uint8_t i,temp;
temp=n*28;
for(i=0;i<temp;i++)
_delay_loop_2(0);
}
void LoadOn()
{
LOAD_PORT|=(1<<LOAD_POS);
}
void LoadOff()
{
LOAD_PORT&=(~(1<<LOAD_POS));
}
main()
{
while(1)
{
LOAD_DDR|=(1<<LOAD_POS);
LoadOff(); |
|
Nazaj na vrh |
|
|
damo123 Član
Pridružen-a: Pon 14 Avg 2006 2:22 Prispevkov: 64 Aktiv.: 0.30 Kraj: Nazarje
|
Objavljeno: Ned Mar 06, 2011 9:16 pm Naslov sporočila: |
|
|
Že nekaj časa se ubadam, da bi byte razbil na bite
primer:
spremenljivka = 0000 0000;
spremenljivka.bit3 = 1;
in bi sedaj morala biti vrednost spremenljivka 0000 1000
kako naj to skonfiguriram |
|
Nazaj na vrh |
|
|
gumby Član
Pridružen-a: Sob 28 Apr 2007 12:32 Prispevkov: 4066 Aktiv.: 19.67
|
Objavljeno: Ned Mar 06, 2011 9:58 pm Naslov sporočila: |
|
|
spremenljivka = 0b00001000; _________________ Tule nisem več aktiven. |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 70 dni
Powered by phpBB © 2001, 2005 phpBB Group
|