Denna variant föreslås av B Knudsen till hans cc5x/cc8e. Koden blir jättebra, men jag stör mig på att jag inte förstår hur den funkar. Nån som orkar förklara? Jag programmerar pic18f med cc8e.
const char str[] = "String 1"; // Är ju enkel så den struntar jag i
const struct
{
const char *s;
} tb[] = {"A table of pointer to strings",
"Monday",
"Tuesday",
"W..."};
Betyder helt enkelt:
tb[] är en tabell över char pekare. De olika strängar sparas i minnet som konstanter och i tb[] läggs deras adressor in som pekare. Om man sedan refererar till tb[?].s som underelement är den en char * vilket betyder sträng.
Det hade gått precis lika bra att ange den som:
const char * tb[] = {"A table of pointer to strings",
"Monday",
"Tuesday",
"W..."};
och sedan plocka ut som tb[?]. Men av någon anledning (kan vara casting-grej) väljer den programmör att lägga till en underpost eller också vill han att strängar ska ha namnet som är .s, vem vet?
Där A representerar de första 2 bittarna, B nästa 3 bitar och C de sissta 3 bitarna av ett 8 bitars tal (char)
Hur gör jag nu för att få strukten att lägga sig på adress 0x0F81 som motsvarar portB?
Går det att ha ytterligare en variabel som heter portb på samma adress utan att det sker krockar om man använder båda variablerna samtidigt (direkt efter varandra)?
I "vanlig" C kan man "overlay"a fler variabler på detta sätt:
union struct
{
unsigned long Big_One;
unsigned int As_Word[2];
unsigned char As_Byte[4];
struct
{
unsigned long B00 : 1;
unsigned long B01 : 1;
unsigned long B02 : 1;
unsigned long B03 : 1;
unsigned long B04 : 1;
unsigned long B05 : 1;
unsigned long B06 : 1;
unsigned long B07 : 1;
unsigned long B08 : 1;
unsigned long B09 : 1;
unsigned long B10 : 1;
unsigned long B11 : 1;
unsigned long B12 : 1;
unsigned long B13 : 1;
unsigned long B14 : 1;
unsigned long B15 : 1;
unsigned long B16 : 1;
unsigned long B17 : 1;
// osv.
} Bits;
} Total;
Då är Total en stor enhet men den kan kommas åt i unsigned long, words, bytes och bits på följande sätt:
Total.Big_One är unsigned Long
Total.As_Word[0...1] är som word
Total.As_Byte[0...3] är som byte
Total.Bits.B00 är som bit
Total.Bits.B01
Total.Bits.B02
osv.
Sen kollar man hur kompilern begär att man skriver lokeringen och sen kan du komma åt bits och bytes bäst du vill. Ett tips är att kolla de filer som inkluderas i systemet, speciellt de processor specifika .H-filer, där brukar portar och dylikt vara definierat med adressor på rätt sätt, kopiera detta sätt.
Jag har tittat i headerfilen, det är därifrån jag fått min strukt. Problemet är att i min headerfil (som jag fått från mplab C18) så finns inte en enda adress definierad i headerfilen. jag har letat vart adresserna tilldelas, men har inte htitat det.
Jag har hittat på nätet efter hur man lägger variabler på speciella adresser, men har inte hittat hur man gör det med strukter.
Det exemplet jag hittade använde en define sats som motsvarar en adress, vilket gör att det inte fungerar att byta ut variabeln mot en strukt.
Hur man lägger strukter på speciella adresser är väl inte specifikt för kompilatorn eller har jag fel?
Vet någon nått ord eller liknande jag skulle kunna söka på för att hitta vad jag söker?
Jo, ska man lägga en variabel i en specifik adress är det just kompiler-specifikt hur man gör, det är nämlig ingen C-grej att göra så.
Edit: Om en struct placeras över ett mindre minnesarea kommer det ju i alla fall att vara så att den största "area" bestämmer men man ställer ju enbart startadressen hursomhelst så börjar man med hårdvaruspecifika saker ska man vara "säker på handen"!
Mer edit: Om du inte hittar någon specifik definition inkluderas det nog ytterligare en fil som du ska leta i. Jag hade sökt i alle filer under det bibliotek efter någon fil som innehåller "F81", med lite klurande skulle det inte ta många minuter att hitta rätt fil och definition.
jag har letat, och det närmsta jag kommit är att jag hitat portb i en *.lib fil. Men när jag öppnar den i notepad, så blir det bara en massa konstiga tecken och krumelurer tillsammans med text.
kan man läsa ut nått ur en lib fil och vilket prog ska man använda sig av då?
Det verkar ganska jobbigt att göra på det sättet...
Det borde väl också funka att bara definiera din struct (som en datatyp alltså) och casta den redan definierade PORTB till den typen. Ungefär som sprawl skriver alltså, fast utan pointers eller hårdkodad adress.
Tror inte att cyrs variant fungerar med tanke på att PORTB förmodligen bara är en konstant med ett värde i.
dock kan man byta ut 0x0F81 mot PORTB i mitt exempel, eller definera den som en global.
Jag har inte heller testat koden så jag vet inte om den fungerar