Hjälp med rutiner/funktioner i mikroC

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Fick inte riktigt rätt på din kod Icecap men jag hittade en annan lösning som jag fick att fungera.

Kod: Markera allt

int line3;                  // Om line3 är 0x2548
char lineLL;
char lineHH;
...

lineLL = line3;             // Blir lineLL = 0x48
lineHH = line3 >> 8;        // Blir lineHH = 0x25
:)
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

lineLL = *(char*)&line3; // lineLL = "innehållet av minnescellen där char pekaren som har värdet 'adressen av line3' pekar"
lineHH = *(char*)(&line3 + 1); // Samma sak fast 1 steg upp i minnet.

Alternativ (bättre):

Kod: Markera allt

union // Betyder att de delar adress med varandra
  {
  int Line3; // deklarera en int
  struct
    {
    char LineLL;
    char LineHH;
    } Parts; // För att skapa en struktur som är i "förlängning" av varandra
  } Lines; // "grund"variablens namn

Lines.Line3 = 0x2548;
// Nu är Lines.Parts.LineLL == 0x48 och
// Lines.Parts.LineHH == 0x25.
lineLL = Lines.Parts.LineLL;
lineHH = Lines.Parts.LineHH;
Kruxet med ">> 8" är att den utför 8 shifts och att en (char) = (int) utför en 16->8 bit konvertering. Använder du även värden som unsigned bör du ange det också (int -> unsigned int, char -> unsigned char).

Observera att det kan vara ett problem att flytta kod med dessa "trick" mellan "little endian" och "big endian" system.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Jag vet att det är en liten "ful"lösning som jag har gjort än så länge...
Men det funkar :eh:

Jag tar tacksamt mot dina förslag och alla andras då jag är nybörjare med C har bara kört ASM innan.

När man ser och läser andras lösningar och sätt att programmera så lär man sig mycket.

Din (Icecap) programmering ligger på en lite högre nivå än min men jag jobbar på det! :?
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Alltså.... så länge det fungerar och man inte har prestandaproblem.... då är det bättre att det fungerar än att man gör "coola" grejer eller hur?

Jag började programmera 1982, först i BASIC (*tungt suck*) men skaffade snabbt grejer till att köra CP/M-80 + assembler. Jag har testat samtliga op-koder i Z80-processorn och en massa annat.... i assembler såklart!

Jag har programmerat Pascal sedan 1984 och bytte till C 1990.

Det tog ganska lång tid innan jag kom överens med pointers, adresser och speciellt unions hade jag kontroverser med, vi kom liksom inte överens.

Så visst befinner vi oss på "olika nivå" eller rättare: olika erfarenhetsnivå. Jag har ju programmerat C(++) i 16 år (satan vad tiden skenar iväg) och gjorde mitt första kommercielle program 1986 (körte klickfritt i 16 år till fabriken stängdes ner av lönsamhetsskäl, styrde 3 laboratorie-ugnar på en klinkersfabrik).

Så "var inte ledsen" för att du kanske inte hänger med sådär helt exakt, det kommer.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Ny fråga!!! :?

Som jag har nämnt tidigare så använder jag mikroC när jag programmerar och behöver lite hjälp.

Jag vill gå in och styra/ändra enskillda bitar i tex ett unsigned (int) eller ett unsigned long (int)

Det finns bra kommando i mikroC som gör det för 8-bitars ord men inte för längre. Se exempel nedan.

Kod: Markera allt

PORTB.F3 = 1;
Jag löser det nu väldigt omständing genom att först dela upp unsigned (int) och unsigned long (int) i flera 8-bitars ord för där efter påverka enskillda bitar och sedan sammanfogar jag dom igen till unsigned (int) eller ett unsigned long (int) beroenda på vad det skall vara.

Hjälp mig nu att hitta en bättre lösning där jag lätt kan påverka enskillda bitar i längre ord.

Mvh

Jeppsson
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Om det är så att du har en int som består av flaggor kan den deklareras såhär:

Kod: Markera allt

union
  {
  struct
    {
    int Flagganamn01 : 1; // ": 1" betyder att den tar 1 bit i en int (bit 0 startar det på)
    int Flagganamn02 : 2; // Här fyller den 2 bitar
    int Flagganamn03 : 13; // Här tar vi resten
    } Bitwise;
  int Whole_Word;
  } My_Special_Var;
Med denna deklaration kan du nu ha åtkomst till dels
int My_Special_Var.Whole_Word;
int My_Special_Var.Bitwise.Flagganamn01;
int My_Special_Var.Bitwise.Flagganamn02;
osv.

Ett sätt kan även vara att göra bitwise operationer:
Kolla bit 14: if(Variabeln & 1 << 14)....
Setta bit 14: Variabeln |= 1 << 14;
Nolla bit 14: Variabeln &= ~(1 << 14);
Växla bit 14: Variabeln ^= 1 << 14;

Det vill kanske gå en aning snabbare att dela upp i olika bytes om det är fasta positioner som gäller.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Tackar så mycket för ditt svar Icecap!

Det här men flaggnamn ser intressant ut...

Skall testa det!
Skriv svar