Läsa av ingång
Re: Läsa av ingång
> RB4 måste ju på något sätt expanderas till C-kod...
Nej. Det räcker med att kompilatorn förstår vad som ska göras
och genererar rätt *assembler* kod. Det finns ingen som helst
anledning att ta omvägen över någon slags "C-kod" först, d.v.s
någon annan "C-kod" än den som redan finns i programmet.
> Problemet här är ju det sätt som C-kompilatorer jobbar på.
Finns det bara *ett* sätt ?
Nej. Det räcker med att kompilatorn förstår vad som ska göras
och genererar rätt *assembler* kod. Det finns ingen som helst
anledning att ta omvägen över någon slags "C-kod" först, d.v.s
någon annan "C-kod" än den som redan finns i programmet.
> Problemet här är ju det sätt som C-kompilatorer jobbar på.
Finns det bara *ett* sätt ?
Re: Läsa av ingång
RB4 är inte ett reserverat ord i C och har alltså ingen betydelse för kompilatorn.
RB4 måste alltså vara definierat i include-filerna.
Alla kompilatorer börjar med att bygga ett parse tree och en symboltabell, och det är just där som jag undrar vad det blir av RB4 i den där symboltabellen. Det kan ju inte bli en adress, eftersom det är en BIT i en port. Och C i sig har ju inget stöd för att sätta en enskild bit till 1 genom att tilldela den värdet 1 (i uttrycket RB4=1 så är 1:an en INT, inte en bit med värdet ett).
För AVR använder man funktioner (eller om der är makron), minns inte exakta namnen men typ set_bit(port,bit) och clr_bit(port,bit).
Och de expanderas ju då till nåt i stil med:
*port &= (1 << bit);
RB4 måste alltså vara definierat i include-filerna.
Alla kompilatorer börjar med att bygga ett parse tree och en symboltabell, och det är just där som jag undrar vad det blir av RB4 i den där symboltabellen. Det kan ju inte bli en adress, eftersom det är en BIT i en port. Och C i sig har ju inget stöd för att sätta en enskild bit till 1 genom att tilldela den värdet 1 (i uttrycket RB4=1 så är 1:an en INT, inte en bit med värdet ett).
För AVR använder man funktioner (eller om der är makron), minns inte exakta namnen men typ set_bit(port,bit) och clr_bit(port,bit).
Och de expanderas ju då till nåt i stil med:
*port &= (1 << bit);
Re: Läsa av ingång
Det där är bara spekulationer kring hur just denna kompilator fungerar.
Jag kan inte argumentera mot eftersom jag inte vet något om just den.
Men det finns ingen anledning att det måste gå via någon annan C-liknande
kod. Det beror ju helt på hur den aktuella kompilatorn är konstruerad.
Jag kan inte argumentera mot eftersom jag inte vet något om just den.
Men det finns ingen anledning att det måste gå via någon annan C-liknande
kod. Det beror ju helt på hur den aktuella kompilatorn är konstruerad.
Re: Läsa av ingång
Blev nyfiken pga detta, kan man få en förklaring:
Fick Bola programmet att fungera?
Menas "öppen" ingång att den inte är ansluten någonstans, varken jord eller plus? Varför får den inte vara öppen? Gäller det även AVR?sodjan skrev:Har du funderat på vad som händer då knappen *inte* är
nertryckt ? Ingången är "öppen" vilket den aldrig får vara...
Fick Bola programmet att fungera?
Re: Läsa av ingång
Googla "unused cmos inputs" eller "open cmos inputs".
Det finns *massor* av sidor som förklarar detta...
Det finns *massor* av sidor som förklarar detta...
Re: Läsa av ingång
PIC-processorer har instruktioner som gör att man kan adressera enskilda bitar i en byte. Jag vet inte om det finns i några andra småprocessorer. Hursomhelst är det förfarandesättet inte särskilt stött av C-protokollet vilket gör att man måste ta en massa kluriga genvägar om man skriver äkta C (CC5X fuskar lite med det här) till en PIC och vill göra så.
En anledning till att inte lämna ingångar öppna är att man inte har någon kontroll över vilket värde de har.
En anledning till att inte lämna ingångar öppna är att man inte har någon kontroll över vilket värde de har.
Re: Läsa av ingång
En "öppen" CMOS-ingång har väldigt hög inimpedans. Det innebär att signalnivån blir vad den vill. Och ofta fångar den lösa tråden upp störningar i luften och börjar svänga i t.ex. 50 Hz.... Det ger felaktiga signaler in. Dessutom så drar CMOS-grindar mer ström om de inte får en vettig logisk nivå på ingången.
En annan anledning att inte lämna ingången "öppen" är givetvis att den då blir oanvändbar: Du har ingen aning om du tryckt ner knappen eller om du har fått "falsklarm". De logiska nivåerna måste vara tydliga både när knappen är nedtryckt och när den inte är det. Det åstadkommer man med t.ex. ett pull-up motstånd.
En annan anledning att inte lämna ingången "öppen" är givetvis att den då blir oanvändbar: Du har ingen aning om du tryckt ner knappen eller om du har fått "falsklarm". De logiska nivåerna måste vara tydliga både när knappen är nedtryckt och när den inte är det. Det åstadkommer man med t.ex. ett pull-up motstånd.
Re: Läsa av ingång
JustNeed: "PIC-processorer har instruktioner som gör att man kan adressera enskilda bitar i en byte"
Nej, det har de INTE!
De har instruktioner till att läsa en byte, maska ut en specifik bit och sedan använda detta värde.
De kan hoppa till ny adress baserat på bit'ens värde och de kan nolla eller "etta" dessa bit, det görs vid att utföra logiska operationer på HELA byte'n vilket ställer till problem ibland (så kallad Read-Modify-Write instruktion, RMW)
Nej, det har de INTE!
De har instruktioner till att läsa en byte, maska ut en specifik bit och sedan använda detta värde.
De kan hoppa till ny adress baserat på bit'ens värde och de kan nolla eller "etta" dessa bit, det görs vid att utföra logiska operationer på HELA byte'n vilket ställer till problem ibland (så kallad Read-Modify-Write instruktion, RMW)
Re: Läsa av ingång
Jag misstänkte väl att de inte kunde adresseras bitvis. Att kunna ändra i bitarna en och en är ju en annan sak, det gör man ju även i AVR. Men adressen är ju portens adress, inte bitens, om man nu inte använder begerppet "adressera" på ett vidare sätt än det gängse.
Re: Läsa av ingång
Semantik.
Man anger ju ett värde i instruktionen (en "adress" om man så vill)
till en specific "bit". Att denna "adress" inte, så att säga, förs ut på
någon "adressbus" och når det aktuella registret, är väl mer en bagatell
i sammanhanget. För *programmeraren* upplevs det att man adresserar
en specifik bit.
> om man nu inte använder begerppet "adressera" på ett vidare sätt än det gängse.
Och det är ? Förrutom att instruktionen har ett fält för en "bit-adress" ?
Man anger ju ett värde i instruktionen (en "adress" om man så vill)
till en specific "bit". Att denna "adress" inte, så att säga, förs ut på
någon "adressbus" och når det aktuella registret, är väl mer en bagatell
i sammanhanget. För *programmeraren* upplevs det att man adresserar
en specifik bit.
> om man nu inte använder begerppet "adressera" på ett vidare sätt än det gängse.
Och det är ? Förrutom att instruktionen har ett fält för en "bit-adress" ?
Re: Läsa av ingång
Att C-kompilatorn inte kan använda sig av en minnesadress för att skriva till en bit, utan man måste använda portens adress och bitens adress... jag kan bara ta AVR-exempel:
man skriver:
sbi PORTC, BIT3 , inte sbi PORTC_BIT3
PORTC |= BIT3, inte PORTC_BIT3 = 1
man skriver:
sbi PORTC, BIT3 , inte sbi PORTC_BIT3
PORTC |= BIT3, inte PORTC_BIT3 = 1
Re: Läsa av ingång
Nerre:
"Och C i sig har ju inget stöd för att sätta en enskild bit till 1 genom att tilldela den värdet 1 (i uttrycket RB4=1 så är 1:an en INT, inte en bit med värdet ett)."
Där har du fel. Det finns ju bit-fält i C.
Om man vet hur C-kompilatorn allokerar bitarna i ett bit-fält, går det att bygga t.ex. en struct innehållande 8 separata bitar som sedan mappas (med nån kompilatorspecifik feature) till en specifik minnes address. I det fallet är följande C-kod för att sätta en enda bit helt ok:
RB4 = 1;
"Och C i sig har ju inget stöd för att sätta en enskild bit till 1 genom att tilldela den värdet 1 (i uttrycket RB4=1 så är 1:an en INT, inte en bit med värdet ett)."
Där har du fel. Det finns ju bit-fält i C.
Om man vet hur C-kompilatorn allokerar bitarna i ett bit-fält, går det att bygga t.ex. en struct innehållande 8 separata bitar som sedan mappas (med nån kompilatorspecifik feature) till en specifik minnes address. I det fallet är följande C-kod för att sätta en enda bit helt ok:
RB4 = 1;
Re: Läsa av ingång
Får man inte typvarning av kompilatorn då?
1 är ju en int, men RB4 är inte en int?
1 är ju en int, men RB4 är inte en int?
Re: Läsa av ingång
Nej, det skall inte komman nån varning. Bit-fält är definierade med en viss datatyp. Dessutom är ju C väldigt förlåtande när det gäller typkonverteringar. Och speciellt med bit-fält är det upp till programmeraren att se till vart bitarna hamnar.
Här är lite kod copy/paste'at från #include filen för Renesas R8C/21:
Alltså, pm03 är nu bit 3 på adress 4 i minnet. pm03 kan användas för att läsa och skriva denna bit.
"#pragma ADDRESS" är givetvis kompilatorspecifikt, men man kan åstadkomma samma sak med vanlig C kod. Notera också att bit-fält inte är helt portabla mellan olika kompilatorer. Dvs, kompilatorn har *viss* frihet hur bitarna mappas i datatypen.
Här är lite kod copy/paste'at från #include filen för Renesas R8C/21:
Kod: Markera allt
#pragma ADDRESS pm0_addr 0004H /* Processor mode register 0 */
struct bit_def {
char b0:1;
char b1:1;
char b2:1;
char b3:1;
char b4:1;
char b5:1;
char b6:1;
char b7:1;
};
union byte_def{
struct bit_def bit;
char byte;
};
union byte_def pm0_addr;
#define pm0 pm0_addr.byte
#define pm03 pm0_addr.bit.b3 /* Software reset bit */
"#pragma ADDRESS" är givetvis kompilatorspecifikt, men man kan åstadkomma samma sak med vanlig C kod. Notera också att bit-fält inte är helt portabla mellan olika kompilatorer. Dvs, kompilatorn har *viss* frihet hur bitarna mappas i datatypen.
Re: Läsa av ingång
Det går alltså i C. Men frågan är hur effektivt det blir. Om koden omvandlas till "läs byte; om (bit==1) gör OR (1<<bit_position) annars gör AND ~(1<<bit_position); spara byte " eller om den använder processorns bitoperationer sbi, cbi , sbrs direkt?