Stefan S. schrieb:
> Das war was ich dazu gefunden hab, passt aber so wie ich das sehe nicht
> so wirklich.
> http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html
korrekt. Da gehts um was ganz anderes
Zum Programm
> /* main.c */
> #include <avr/io.h>
> #include "mylib.h"
>
> int main()
> {
> mylib_init(DDRB, PORTB3);
Das kann so nicht funktionieren.
Wenn du in C eine Funktion aufrufst1 | void foo( int a )
|
2 | {
|
3 | ...
|
4 | }
|
5 |
|
6 | int main()
|
7 | {
|
8 | int i = 5;
|
9 |
|
10 | foo( i );
|
11 | }
|
dann kriegt die Funktion bei ihrem Aufruf den momentan aktuellen Wert
des Arguments (hier: i. Also den Wert 5).
Änderst du nach dem Funktionsaufruf das i, so wie hier
1 | int main()
|
2 | {
|
3 | int i = 5;
|
4 |
|
5 | foo( i );
|
6 | i = 8;
|
7 | }
|
dann beeindruckt das die Funktion nicht weiter. Denn: Die Funktion weiss
ja gar nichts von deinem i. Die Funktion hat nur einen Wert bekommen.
Wenn die Funktion wissen soll/muss, wo der Wert eigentlich herkommt,
dann musst du ihr schon die Adresse davon geben.
1 | void foo( int * a )
|
2 | {
|
3 | ...
|
4 | }
|
5 |
|
6 | int main()
|
7 | {
|
8 | int i = 5;
|
9 |
|
10 | foo( &i );
|
11 | }
|
Jetzt kann sich die Funktion diese Adresse in einer Variablen merken, zb
in einer globalen, um dann in weiterer Folge diese Adresse wieder zur
Verfügung zu haben, wenn siegebraucht wird.
So auch hier bei dir. Deine Lib-Funktionen brauchen die Adresse! Der
aktuelle Wert vom Port Register ist zwar nett, aber eigentlich sollen
die Funktionen ja das Port register manipulieren. Daher brauchen sie die
Adresse, wo diese Manipulation stattfinden soll:
1 | mylib_init(&DDRB, &PORTB, 3);
|
und da die Bitnummer eine Konstante ist und sich nie ändert, muss die
Funktion davon auch keine Adresse kriegen. Da braucht sie sich nur die
Bitnummer merken. Daher kriegt sie die auch einfach nur als Zahl
du übergibst der Funktion hier die aktuellen Werte von DDRB, PORTB und
ich nehme mal an, du hast da ein Komma zwischen PortB und der 3
vergessen.
Das ist aber nicht das was du willst!
Du willst der Funktion ja nicht die aktuellen Werte geben, sondern du
willst der Funktion nmitteilen, wo es die aktuellen Werte herkriegen
kann!
Daher hast du ja auch hier
1 | void mylib_init(uint8_t *DDR, uint8_t *PORT, uin8t_t *PORT_BIT);
|
ja auch vereinbart, dass die Funktion die Adressen kriegt (wo auch immer
du das abgeschrieben hast). Aber dann musst du ihr auch Adressen geben!
1 | void mylib_init(uint8_t *DDR, uint8_t *PORT, uin8t_t PORT_BIT);
|
(UNd schreib die Variablen nicht gross. Namen komplett in
Grossbuchstaben sind weltweit eine Konvention um anzuzeigen, dass es
sich um ein Makro handelt. Das hier ist aber kein Makro. Das sind
normale Funktionsargumente.
1 | void mylib_init(uint8_t *Ddr, uint8_t *Port, uin8t_t PortBit);
|
Und der korrekte Datentyp für die Register ist 'volatile uint8_t *' und
nicht nur 'uint8_t *'
> {
> *DDR |= (1 << *PORT_BIT);
Dann eben1 | *Ddr |= ( 1 << PortBit );
|
Vor das Ddr muss ein *, weil DDr ja eine Adresse ist. Das PortBit
braucht keinen *, weil da ja schon die Zahl selber in der Variablen
steht.
> my_lib_ddr = *DDR;
> my_lib_port = *PORT;
> my_lib_port_bit = *PORT_BIT;
Hier speicherst du dir die übergebenen Werte, weil du sie ja für spätger
brauchst. Aber: Du willst dir wieder nicht speichern, welcher aktuelle
Wert am Ddr gerade vorliegt, sondern du willst dir die Adresse merken,
welcher DDrd gemeint ist. Die Adresse hast du ja vom Aufrufer gekriegt.
Also musst du dir die auch merken, wenn du sie später wieder brauchst.
1 | volatile uint8_t* my_lib_ddr = 0;
|
2 | volatile uint8_t* my_lib_port = 0;
|
3 | uint8_t my_lib_port_bit = 0;
|
4 |
|
5 | void mylib_init(volatile uint8_t *Ddr, volatile uint8_t *Port, uin8t_t PortBit)
|
6 | {
|
7 | *Ddr |= ( 1 << PortBit );
|
8 |
|
9 | my_lib_ddr = Ddr;
|
10 | my_lib_port = Port;
|
11 | my_lib_port_bit = PortBit;
|
12 | ]
|
> Wäre über eure Hilfe dankbar. Gruß Stefan
Ein gutes C Buch, aufgeschlagen in einem der Kapitel in dem es erstmalig
um Pointer geht und ein paar Übungssstunden auf dem PC würden Wunder
wirken.