Forum: Mikrocontroller und Digitale Elektronik ATmega168 GPIO mit Zeigern


von Andreas L. (feuerlink)


Lesenswert?

Hallo zusammen,

ich sitze zur Zeit dabei, meinen Rechner so einzurichten, dass ich uCs 
mit einem Arduino Uno als ISP flashen kann. Dazu nutze ich zum Testen 
einen Atmega168. avr-gcc und avrdude läuft. Noch nutze ich notepad++ und 
cmd (Win10) zum proggen, bei Zeiten werde ich eine IDE einrichten.

Typischer erster Versuch: LED blinken lassen, bzw. erst einmal 
einschalten. Mithilfe der avr/io.h funktioniert's auch prima, mit 
direkten Registerzugriffen über selbstdefinierte Zeiger aber nicht. Ich 
möchte aber gerne, dass das auch klappt.


Mein Code sieht wie folgt aus:
1
//#define __AVR_ATmega168A__
2
3
#include <stdint.h>
4
5
volatile uint8_t *DDRB_p = (uint8_t*)0x24;  //Pointer to DDRB:   Direction
6
volatile uint8_t *PORTB_p = (uint8_t*)0x25; //Pointer to PORRTB; DATA
7
8
int main(){
9
10
  *DDRB_p = 0xFF; //set output
11
  
12
  while(1) {                
13
    *PORTB_p |= (1<<1);    //set Bit
14
  }
15
  return 0;
16
}

Mein erstmal minimalistisches Makefile:
1
#MAKEFILE
2
3
all: test.o
4
#avr-gcc -o -mmcu=atmega168a test test.o | DOESNT WORK
5
  avr-gcc -o test test.o
6
  avr-objcopy -O ihex test.o test.hex
7
  avrdude -c avrisp -p atmega168 -P COM4 -b 19200 -U flash:w:test.hex
8
  
9
  
10
%.o: %.c
11
  avr-gcc -c $<
12
13
clean:
14
  rm -f test.o test.hex test

Kann mir jemand sagen, was ich falsch mache? Die Registeradressen stehen 
so im Datenblatt. Zusätzlich habe ich die avr/io.h und die 
avr/sfr_defs.h nachverfolgt und komme auf die gleichen Adressen.


Gruß

von jemand (Gast)


Lesenswert?

Zeiger im Adressraum sind 16 bit nicht 8 bit

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andreas L. schrieb:
> #avr-gcc -o -mmcu=atmega168a test test.o | DOESNT WORK

weil du "-mmcu=atmega168a" als Ausgabedatei angibst.

>   avr-gcc -o test test.o
>   avr-objcopy -O ihex test.o test.hex

Die Ausgabe nach dem Linken heißt "test", aber du wandelst "test.o" nach 
IHEX um.  test.o ist vermutlich ein nicht-lokatiertes Object-File.

> volatile uint8_t *DDRB_p = (uint8_t*)0x24;  //Pointer to DDRB:
> Direction

Besser:
 
1
#include <avr/io.h>
2
volatile uint8_t *DDRB_p = &DDRB;

vermeidet magische Zahlen.

von spess53 (Gast)


Lesenswert?

Hi

> Die Registeradressen stehen so im Datenblatt.

Kommt darauf an wie auf die Adressen zugegriffen wird. Probiere doch mal 
0x04/0x05.

MfG spess

von Andreas L. (feuerlink)


Lesenswert?

Danke für eure Antworten!

jemand schrieb:
> Zeiger im Adressraum sind 16 bit nicht 8 bit

Denke ich nicht und selbst wenn, macht das hier keinen Unterschied.

Johann L. schrieb:
> weil du "-mmcu=atmega168a" als Ausgabedatei angibst.

Nein, die Zeile ist auskommentiert.

> Die Ausgabe nach dem Linken heißt "test", aber du wandelst "test.o" nach
> IHEX um.  test.o ist vermutlich ein nicht-lokatiertes Object-File.

geändert:
1
#MAKEFILE
2
3
all: test.o
4
  avr-gcc -o test test.o
5
  avr-objcopy -O ihex test test.hex
6
  avrdude -c avrisp -p atmega168 -P COM4 -b 19200 -U flash:w:test.hex
7
  
8
  
9
%.o: %.c
10
  avr-gcc -c $<
11
12
clean:
13
  rm -f test.o test.hex test

> vermeidet magische Zahlen.

Naja, es geht mir aber ja gerade genau darum, dass es ohne die AVR 
Bibliotheken auch funktionieren muss.

spess53 schrieb:
> Hi
>
>> Die Registeradressen stehen so im Datenblatt.
>
> Kommt darauf an wie auf die Adressen zugegriffen wird. Probiere doch mal
> 0x04/0x05.
>
> MfG spess

Habe ich auch ausprobiert. Also ohne den Offset. Hilft leider auch 
nicht.

von Andreas L. (feuerlink)


Lesenswert?

Johann L. schrieb:
> weil du "-mmcu=atmega168a" als Ausgabedatei angibst.

Oh, sorry, hab verstanden wie du's meinst.

Jetzt läufts. Makefile sieht jetzt wie folgt aus:
1
#MAKEFILE
2
3
all: test.o
4
  avr-gcc -mmcu=atmega168a -o test test.o
5
  avr-objcopy -O ihex test test.hex
6
  avrdude -c avrisp -p atmega168 -P COM4 -b 19200 -U flash:w:test.hex
7
  
8
  
9
%.o: %.c
10
  avr-gcc -c $<
11
12
clean:
13
  rm -f test.o test.hex test

Also war es ein Fehler vom compilieren und nicht vom Code? Muss der 
Compiler zwingend wissen, für welchen Controller er compilieren muss?


EDIT: Ups, sorry für den Doppelpost

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andreas L. schrieb:
> Johann L. schrieb:
>> weil du "-mmcu=atmega168a" als Ausgabedatei angibst.
>
> Nein, die Zeile ist auskommentiert.

Genau.  Weil sie falsch war.

>   avr-gcc -o test test.o

Hier fehlt ein -mmcu=...

>   avr-gcc -c $<

Ditto.

>> vermeidet magische Zahlen.
>
> Naja, es geht mir aber ja gerade genau darum, dass es ohne die AVR
> Bibliotheken auch funktionieren muss.

Die Bibliotheken brauchst du nicht, die Header genügen.

Und wenn du auf (Standard)-Header und Bibliotheken verzichten willst, 
dann willst du mindestens mit

-nostartfiles -nostdlib -nodefaultlibs -nostdinc

übersetzen / linken.

> spess53 schrieb:
>> Kommt darauf an wie auf die Adressen zugegriffen wird. Probiere doch mal
>> 0x04/0x05.
>
> Habe ich auch ausprobiert. Also ohne den Offset. Hilft leider auch
> nicht.

avr-gcc verwendet RAM-Adressen.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.