Jesses följetång om AVR programmering i C...

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Jesses följetång om AVR programmering i C...

Inlägg av jesse »

a) Varför använder man _BV(bitnr) istället för (1<<bitnr) i AVR-GCC? Är det en fördel eller bara ett annat sätt att skriva samma sak?

b) omvandling av olika former av integer:

Är det OK att blanda heltal med olika bitlängd eller kan det bli konstiga fel då? Hur skulle jag gjort annars?

Kod: Markera allt

int16_t a,b;
int8_t c,d;

a=b+c+d;  // addera 8 bitars och 16 bitars

c=a>>8; // plocka ut de högsta 8 bitarna
Senast redigerad av jesse 29 oktober 2009, 08:38:51, redigerad totalt 4 gånger.
Användarvisningsbild
JockeE
Inlägg: 330
Blev medlem: 4 augusti 2004, 08:46:50

Re: lite undringar om AVR progrannering i C

Inlägg av JockeE »

a) Inte insatt i AVR-GCC, men jag gissar att det bara är ett tydligare (?) sätt att åstadkomma samma sak.

b) Det bör inte vara något problem att blanda på det där viset. Vill man vara säker bör man använda type casting.

Kod: Markera allt

int16_t a, b;
int8_t c, d;

a = b + (int16_t) c + (int16_t) d;    // addera 8 bitars och 16 bitars

c = (int8_t) (a>>8);    // plocka ut de högsta 8 bitarna
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: lite undringar om AVR progrannering i C

Inlägg av jesse »

OK

(flyttade detta stycket från första inlägget då det lades till senare)

När jag ändå är igång och frågar ... kan man göra bitvis operationer i C på enstaka bitar som motsvarar t.ex. sbr r0,bit eller sbi port,bit och cbi port,bit... lite onödigt att gå omvägen att ladda ner och göra or / and för att sedan spara igen, t.ex.

Kod: Markera allt

PORTC |= 0x01 ; // sätt bit 0 i PORTC
Framför allt använder jag bitinstruktionerna i assembler för flaggor, då de ryms 8 st i en byte. ska man använda char som flaggor tar det 8 ggr minnesutrymme. Finns det något bekvämare sätt att sätta/resetta/ändra i en bit i en variabel än

Kod: Markera allt

flaggor |= flagga3; // sätt flagga3
if (flagga&flagga3) ...
eqlazer
Inlägg: 923
Blev medlem: 22 september 2007, 13:53:45
Ort: Göteborg

Re: lite undringar om AVR progrannering i C

Inlägg av eqlazer »

Det där är ju en bitvis operation (|). Har du kollat list-filen hur assemblerkoden ser ut? Kanske är det precis som du brukar göra.
Användarvisningsbild
E85
Inlägg: 1274
Blev medlem: 29 maj 2007, 16:24:19
Ort: Övik

Re: lite undringar om AVR progrannering i C

Inlägg av E85 »

Ibland brukar jag använt bit fields, såhär:

Kod: Markera allt

struct {
     unsigned ready:1;
     unsigned error_occured:1;
     unsigned b2:1;
     unsigned b3:1;
     unsigned b4:1;
     unsigned b5:1;
     unsigned b6:1;
     unsigned b7:1;
} config;

config.ready = 1;
Fast hur det ser ut i assembler har jag inte undersökt.
Johanb
Inlägg: 3406
Blev medlem: 26 mars 2006, 22:26:12
Ort: Smedjebacken

Re: lite undringar om AVR progrannering i C

Inlägg av Johanb »

jesse skrev:a) Varför använder man _BV(bitnr) istället för (1<<bitnr) i AVR-GCC? Är det en fördel eller bara ett annat sätt att skriva samma sak?
Det gör man inte mig veterligen, det var vanligt förr men nu är det nog inte många som skriver så.


Edit: klantade citatet
Senast redigerad av Johanb 20 oktober 2009, 12:19:03, redigerad totalt 1 gång.
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Re: lite undringar om AVR progrannering i C

Inlägg av MicaelKarlsson »

jesse skrev: När jag ändå är igång och frågar ... kan man göra bitvis operationer i C på enstaka bitar som motsvarar
Har du testat:

Kod: Markera allt

#define bit_get(p,m) ((p) & (m))
#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_flip(p,m) ((p) ^= (m))
hornfeldt
Inlägg: 104
Blev medlem: 6 maj 2008, 00:27:07
Ort: Örnsköldsvik

Re: lite undringar om AVR progrannering i C

Inlägg av hornfeldt »

jesse skrev:a) Varför använder man _BV(bitnr) istället för (1<<bitnr) i AVR-GCC? Är det en fördel eller bara ett annat sätt att skriva samma sak?
http://www.nongnu.org/avr-libc/user-man ... faq_use_bv

_BV är ett macro för att göra det mer läsvänligt. Kompilatorn gör ingen skillnad på uttrycken.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: lite undringar om AVR progrannering i C

Inlägg av jesse »

MicaelKarlsson skrev:Har du testat:

Kod: Markera allt

#define bit_get(p,m) ((p) & (m))
#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_flip(p,m) ((p) ^= (m))
Det märks att jag är nybörjare på C. Det tog lite tid att fatta dessa macron, särskilt den översta tills jag fattade att den inte är en "operation" utan ett uttryck.

men bit_clear(PORTB,1<<PB2); skulle vara ett korrekt användande väl?

I så fall kanske jag kunde köra

Kod: Markera allt

#define bit_clear(p,m) ((p) |=(1<<(m))) 
istället, så slipper jag 1<< för varje bit.... (om nu bitarna definieras som 0,1,2,3 och inte 1,2,4,8,16...). Nackdelen är förstås att detta macro bara kan nolla en bit åt gången, men det var ju också det jag ville åt. Om detta nu översätts till sbi PORTB,(1<<PB0) så blir det ju grymt bra.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: lite undringar om AVR progrannering i C

Inlägg av jesse »

fortsätter väl min AVR-C tråd med mer tjafs... kan bli en väldigt lång tråd om alla problem eller undringar jag stöter på ska pratas om här :roll:

men: försökte göra ett enkelt UART program... (har inte testat i hårdvara än) och kunde lite låta bli att försöka få ihop det så det funkade med printf(...). Men herregud vilken mängd kod det genererade... 3368 bytes! Det var precis det fick plats i min ATMega48. Då gäller det att man inte vill göra något annat än att skicka tecken till /från UART...

hoppas nu bara att det stämmer att printf() kopplas till mina egna uart_putch() rutiner och inte nån annastans??? ENda sättet att verifera det är väl att testa i hårdvaran antar jag!
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Re: lite undringar om AVR progrannering i C

Inlägg av MicaelKarlsson »

Jag brukar för enkelhets skull skriva så här:

Kod: Markera allt

#define SET_RELAY_1 bit_set(PORTC,1)
För att i koden senare använda uttrycket:

Kod: Markera allt

SET_RELAY_1;
Om det är lättläst eller ej? Ja och nej.... för mig är det enkelt eftersom jag är van vid att skriva så. :)

Men det känns enklare/mer lättläst än att skriva:

Kod: Markera allt

bit_set(PORTC,1)
vilket i mina ögon säger: "Sätt PC0 till ett"
Medan uttrycket:

Kod: Markera allt

SET_RELAY_1;
säger att relä 1 dras (eller aktiveras eftersom jag i detta fall använde slutande reläer)
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: lite undringar om AVR progrannering i C

Inlägg av stekern »

om du gjort som man ska så kommer den redirektas till din putchar rutin ;)

men som du märkt så tar printf mycket plats, så jag brukar undvika att använda den.

Vill jag skriva ut ett siffervärde till en sträng så använder jag nån funktion liknande denna:

Kod: Markera allt

char string[10];
char *uint_to_string(uint16_t value) {
	char *p;
	p = (string + 10);
	*--p = '\0';
	do {
		char ch = value % 10 + '0';
		if (ch > '9')
			ch += 'a' - '9' - 1;
		*--p = ch;
		 value /= 10;
	} while (value);
	return p;
}
Senast redigerad av stekern 20 oktober 2009, 13:08:55, redigerad totalt 1 gång.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: lite undringar om AVR progrannering i C

Inlägg av bearing »

Jag är personligen emot dessa makron. Tycker koden blir mer lättläst utan. Kanske är vi olika. Jag har svårt att hålla innebörden av makron i huvet, men tycker att en rad fylld med shift/OR/XOR/AND osv i kombination inte är så svår att tyda.

Kompilatorn kan ställas in att producera en fil som innehåller resultatet av kompilatorns arbete som assemblerkod, med C-koden som kommentarer. Filen kan t.ex. användas för att kontrollera att en C-kod inte genererat onödigt krångliga instruktioner.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: lite undringar om AVR progrannering i C

Inlägg av jesse »

Makron som andra har skrivit kan ju vara helt obegripliga om man inte letar upp definitionen. Men jag gillar själv att använda macron , till en viss gräns. det kan bli överdrivet annars - man vill ju inte bygga ett helt nytt eget programspråk!

Onödiga macron:

#define loopTenTimes for(i=0;i<10;i++) {
#define endOfLoop }
#define endOfWhatever }

#define AddOne(x) (x)+=1

osv...
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: lite undringar om AVR progrannering i C

Inlägg av jesse »

Men vad är detta :?: :?: :?:

Kod: Markera allt

#define F_OSC 8000000
#define BAUDRATE 19200
#define	BAUD_PRESCALE (F_OSC/(16*BAUDRATE)-1)
	UBRR0L = BAUD_PRESCALE; 
	UBRR0H = (BAUD_PRESCALE >> 8);
och detta ger: ../uarttest.c:26: warning: integer overflow in expression
för både UBRR0L och UBRR0H.
Värdena som matas in är 121(L) och 254(H) :?:

aha... kom på det medan jag skrev... F_OSC är ju 8E+6 vilket tar upp 23 bitar vilket borde fått plats i ett vanligt integer, men i AVR-GCC är per default "integer" en 16-bitarstyp. Så genom att skriva #define F_OSC 8000000UL så fick det plats. Så löstes det också.... jobbigt i början med så många detaljer man måste vara vaksam på när man inte är van. :|
Skriv svar