Moin, Ich möchte gerne laufend 128 Schalter über Schieberegister einlesen (refresh(data)), aber nur dann wenn sich der Wert zum vorherigen verändert hat über RS232 verschicken (send(data)). Dazu hatte ich die Idee: data_old=data; refresh(data); if (!(data_old==data)) send(data); Allerdings sind data, sowie data_old in der bisherigen idee char-arrays mit 16 chars. Wie kann ich die inhalte kopieren und dann miteinander vergleichen? Oder gibt es einen 128Bit datentyp? Gruß Phil
@ Phillip Hommel (Firma hs-bremen) (philharmony) >Allerdings sind data, sowie data_old in der bisherigen idee char-arrays >mit 16 chars. Womit du entweder per "Hand" in einer Schleife die Arraysvergleichen musst, oder auf strcmp() zurückgreifen musst. >Wie kann ich die inhalte kopieren und dann miteinander vergleichen? In einer Schleife. >Oder gibt es einen 128Bit datentyp? Nicht auf kleinen Mikrocontrollern. MFG Falk
Gast
#702087
vergleiche doch einfach byteweise:
for(unsigned char i=0; i < 16; i++)
{
if(data[i] != old_data[i])
{
send(data);
break;
}
}
Gast
#702091
Zwei Arrays sind gleich, wenn jede einzelne Zelle gleich ist. Du könntest eine Schleife machen, die bei jedem Durchgang jede Zellen mit dem gleichen Index vergleicht. ungefähr so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Oder so ähnlich
Gast
#702095
Sorry, natürlich so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Gast
#702100
if (!memcmp(data,olddata,16))
{
send(data);
memcpy(olddata,data,16);
}
Gruss Helmi
is memcmp ein sdandard-c ausdruck der muß ich das irgendwoher importieren? Klingt am einfachsten...Nur wie kann ich dem das gesamte array übergeben? Phil
Phillip Hommel wrote: > is memcmp ein sdandard-c ausdruck der muß ich das irgendwoher > importieren? memcmp, memcpy usw. sind Funktionen aus dem (Standard-Header) string.h.
Gast
#702117
memcpy und auch memcmp sind Teile der Standart C Bibilothek meistens sind sie in der "string.h" enthalten Du uebergibst nicht das Array sondern einen Pointer auf das Array. Die angabe von 16 in meinem Code heisst das die beiden Arrays 16Byte lang sind -> 128 Bit Daten. Du musst in deinem Programm das Header File string.h inkludieren. #include <string.h> Gruss Helmi
gut, werd ich mal versuchen... Gibt es für das Kopieren von Data nach Data_old auch so ne funktion, oder muß ich das per Schleife machen?
memcpy wurde doch oben schon erwähnt... (Helmis Posting von 11:08)
oh, oohps, nich gesehn...dankeschön
Hmm, gibt ein Problem:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Fehlermeldung: ../Overhead_Board.c:65: Fehler: in Konflikt stehende Typen für »memcpy«
Gast
#702751
Opps ich hatte einen kleinen Fehler in dem Programm
nimm mal das '!' zeichen vor dem memcmp weg.
memcpy b.z.w. memcmp funktioniert auf byte (char) ebene
if (memcmp(data,olddata,16))
{
send(data);
memcpy(olddata,data,16);
}
gruss helmi
Gast
#702821
Caste die Varibeln mal mit (char*)
da könnte deine Fehlermeldung herkommen
if (memcmp((char*)data,(char*)olddata,16))
{
send(data);
memcpy((char*)olddata,(char*)data,16);
}
Gruss Helmi
helmi wrote: > Caste die Varibeln mal mit (char*) > > da könnte deine Fehlermeldung herkommen > > if (memcmp((char*)data,(char*)olddata,16)) > { > send(data); > memcpy((char*)olddata,(char*)data,16); > } > sollte aber keinen Unterschied machen, da char Data_to_send[16], Data_to_send_old[16], Data_received_LED[16]; und somit der cast implpizit vom Compiler gemacht wird. Wenn schon, dann würde ich mal in der string.h nachschauen wie auf dem System die Funktionen memcmp und memcpy deklariert sind Eventuell ist er in Wirklichkeit ja auf einem C++ Compiler. Dort sind die Argumente als const void* bzw void* deklariert und muss explizit nach void* casten if (memcmp((void*)data,(void*)olddata,16)) { send(data); memcpy((void*)olddata,(void*)data,16); } Wenn mans dann ganz exakt machen will, dann castet man beim memcmp in beiden Fällen nach const void* bzw. beim memcpy das 2. Argument nach const void*
lag an nem syntaxfehler weiter oben...die Fehlermeldungen von AVR-Studio führen manchmal echt in die Irre... Aber hat jemand ne Idee warum das hier nicht funktioniert?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
Wenn ich das ganze Simuliere verändert sich der Wert in Data_to_send kein bisschen, egal was ich an PINC mache...
Grmpf Wenn ich anstatt Pin_Input (steht ja für PINC, PINC0) PINC&0x01 einsetze dann gehts. Gibt mir denn die PINC,PINC0-Abfrage keinen Wert zurück?
Gast
#702852
Naja, mit
((Pin_input)<<i)
findet ja auch kein Portzugriff statt. Es wird vom Preprozessor
erweitert zu
(((PINC,PINC0))<<i)
Der C-Compiler nimmt dann PINC als Ergebnis dieses Ausdrucks und schiebt
den entsprechend.
Schreib doch einfach mal:
if ((PINC & (1<<PINC0)) != 0)
Data_to_send[a] |= 1<<i;
Wenn es aber wirklich Bit 0 von PORTC ist, hast Du Glück und könntest
einfacher schreiben:
Data_to_send[a] |= (PINC & 1)<<i;
Gast
#702859
Du hast Dir etwas ausgedacht, was der Compiler übersetzt, aber nicht das macht, was Du willst :-) Du wolltest eine Abfrage, die Dir 1 liefert, wenn Dein Bit auf 1 ist, ansonsten auf 0. Das geht so aber nicht. Dein #define müßte lauten: #define Pin_Input ((PINC & (1<<PINC0)) != 0 ? 1 : 0) Reichlich unübersichtlich....
> (((PINC,PINC0))<<i) > > Der C-Compiler nimmt dann PINC als Ergebnis dieses Ausdrucks und > schiebt den entsprechend. (PINC,PINC0) ist eine comma expression; Resultat ist der letzte Operand.
Puuh, ich glaub ich muß dringend meine C-Kenntnisse erweitern. Danke für die Tips. Da ich die selbe Abfrage eventuell später noch mit anderen Pins als dem 0-ten machen möchte, werde ich Eddie´s Vorschlag mal versuchen. Vielen Dank
Gast
#703701
Ja, probier's mal. Deine Code läßt sich übrigens perfekt mit
for-Schleifen realisieren:
unsigned char a,i;
for (a=0; a<16; a++)
{
Data_to_send[a] = 0; // Annahme: Alles ist 0
for (i=0; i<8; i++)
{
PORTC |= (1<<Input_Clock);
_delay_us(10);
PORTC &= ~(1<<Input_Clock);
Data_to_send[a] >>= 1; // Platz schaffen für's nächste Bit
if (PINC & (1<<PINC0))
Data_to_send[a] |= 0x80; // Ggf. Bit setzen
}
}
Der Typ von Data_to_send muss ein unsigned char sein (nicht signed), da
sonst beim Rechtsschieben das Vorzeichen erweitert wird. Das gibt
schönen Datenmüll.
Dein Eingang darf nun auch wieder auf einem beliebigen Bit vom Port
liegen.
Eine fiese Version einer for-Schleife wäre noch:
unsigned char a,i;
for (a=0; a<16; a++)
{
Data_to_send[a] = 0; // Annahme: Alles ist 0
for (i = 1; i; i <<= 1) // Wir schicken ein Bit durch ein Byte,
// bis es hinten heraus fällt
{
PORTC |= (1<<Input_Clock);
_delay_us(10);
PORTC &= ~(1<<Input_Clock);
if (PINC & (1<<PINC0))
Data_to_send[a] |= i; // Ggf. Bit setzen
}
}
So etwas läßt sich gerade für so eine Anwendung wie Deine sehr oft
gebrauchen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.