ich arbeite mich grad in das Thema ein, wie ich meinen CODE ein wenig zeit- und speicheroptimiert hinbekomme.
Die Manipulation mit bit-Math-Operationen der einzelnen Ports/Register und damit der Pins funzt soweit ganz gut.
Ich würde nun gerne in meinem Hauptprogramm auf eine Funktion mit 3 Variablen verweisen.
Variable 1: Pin (PD0...7 z.B.)
Variable 2: Pin (ebenfalls PD0...7)
Variable 3: Das Register (also hier PIND)
Die Pins zu übergeben ist kein Problem, die deklariere ich einfach z.B. in der Funktion als "int PD0".
Wie aber muss ich das Register deklarieren? Geht das überhaupt?
Für Antworten wäre ich dankbar.
Falls das gar nicht funktioniert wie ich mir das denke, bitte nicht schimpfen
Das sieht ein wenig wüst aus für jemanden, der nicht so häufig programmiert
Ich wühl mich mal durch und melde mich zurück.
Vorher vielleicht noch ein, zwei Verständnisfragen:
Hinter den "Namen" PD0...7 stehen einfach Zahlenwerte richtig? Also einfach Werte von 0-7, die auf die entsprechenden bits 0-7 im entsprechenden Register verweisen? Daher auch die Deklaration als int. Byte, long oder sonst irgendwas numerisches würde als Datentyp auch laufen oder?
Was genau steht hinter dem "Namen" PIND? Steht da ein Wert hinter, der den momentanen Zustand der Pins beschreibt? Ist es eine Adresse im Speicher? Ich denke ich habe da noch ein paar Lücken, um richtig hinter den Kram zu steigen.
PINx und PORTx sind Adressen im Speicher. Da steckt die Adresse eines Special Function Registers dahinter (Stichwort: memory mapped I/O). Das ist ja der Grund weshalb man das als Zeiger übergeben muss.
Habe mir mal ein wenig zu Zeigern durchgelesen.
So wie ich das verstehe verweisen die auf eine Speicheradresse an der dann die Infos stehen, die zu übergeben ich versuche.
In meinem Fall: wenn ich per Zeiger auf die Speicheradresse von PINx/PORTx verweise, wird der an dieser Stelle im Speicher befindliche Wert übergeben, richtig?
make89:
In meinem Fall: wenn ich per Zeiger auf die Speicheradresse von PINx/PORTx verweise, wird der an dieser Stelle im Speicher befindliche Wert übergeben, richtig?
Nein, falsch.
Es wird die Adresse des Ports übergeben, damit man in den etwas schreiben oder aus dem etwas lesen kann.
Das volatile deutet an, dass sich der Wert an der Stelle des Ports jederzeit ändern kann, also ein Cachen nicht zulässig ist.
#include "Pin.h"
// Standard LED auf dem UNO Board
#define LED PINDEF(B,5) //Pin13, PORTB Bit 5
void setup()
{
setOutput(LED);
}
void loop()
{
togglePin(LED);
delay(1000);
}
Okay, heißt das, ich muss auf die Adresse verweisen und dann zusätzlich eine Anweisung zum Lesen der Infos an dieser Stelle geben?
Also zum Beispiel:
void setup() {
}
void loop() {
test_function(PIND,PD2,PD3) //Funktionsaufruf mit Übergabe der Werte
}
void test_function(volatile int* port, int x,int y) { //das Sternchen deklariert jetzt "port" als Pointer, richtig?
int port_adresse = &port; // port_adresse wird die Speicheradresse von port zugewiesen
int port_wert = *port_adresse; //port_wert wird der Wert an der Adresse zugewiesen
....hier wird dann irgendwas cooles mit port_wert,x und y gemacht
}
Ich versuche noch durch das Prinzip zu steigen...
void loop() {
while ((PIND & (1 << PD2))) {}
tempmicros=micros();
while ((PIND & (1 << PD2)) == 0) {}
if ((micros()-tempmicros)>500) { //if the HIGH pulse was longer than 500 micros we are at the start of a new bit sequence
decode(PD2,PD3,&PIND); //decode the bit sequence
}
}
void decode(int x,int y,volatile uint8_t *port) {
sign=1;
value=0;
for (i=0;i<23;i++) {
while ((*port & (1 << x))) {}
while ((*port & (1 << x)) == 0) {}
if ((*port & (1 << y)) == 0) {
if (i<20) {
value|= 1<<i;
}
if (i==20) {
sign=-1;
}
}
}
result=(value*sign);
Serial.println(result); //print result
}
Der Code macht was er soll.
Nun noch der Versuch genau zu verstehen was passiert:
Indem ich die Übergabevariable *port mit dem Sternchen als Pointer deklariere, wird eine Adresse als Übergabewert erwartet --> diese übergebe ich mit &PIND (Adresse des Registers, an der dann die Status der Pins im Port D gespeichers sind).
Die Adresse wird in der Funktion mit "*port" wieder dereferenziert, es wird also der Inhalt an der Position im Speicher gelesen und damit weiter gerechnet.