mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Arrays Vergleichen


Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: tubbu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vergleiche doch einfach byteweise:

for(unsigned char i=0; i < 16; i++)
{
    if(data[i] != old_data[i])
    {
         send(data);
         break;
    }
}

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
int i;
int sendok;
for (i=0;i<data.length;i++){
if (data_old[1]!= data[1]){
int sendok = 0;
i=data.length;}
else sendok = 1;}

if (sendok)
send(data);

Oder so ähnlich

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, natürlich so:
unsigned char i;
unsigned char sendok;
for (i=0;i<data.length;i++){
if (data_old[i]!= data[i]){
sendok = 0;
i=data.length;}
else sendok = 1;}

if (sendok)
send(data);

Autor: Helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (!memcmp(data,olddata,16))
 {
    send(data);
    memcpy(olddata,data,16);
 }

Gruss Helmi

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
memcpy wurde doch oben schon erwähnt...

(Helmis Posting von 11:08)

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh, oohps, nich gesehn...dankeschön

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, gibt ein Problem:
char Data_to_send[16], Data_to_send_old[16], Data_received_LED[16];
...
if (!memcmp(Data_to_send,Data_to_send_old,16)) //Vergleichen, ob Änderung
  {
  Send_To_PC(Data_to_send);//wenn ja, dann an PC senden
  memcpy(Data_to_send_old, Data_to_send, 16);//als "gesendet" ablegen
      }

Fehlermeldung:
../Overhead_Board.c:65: Fehler: in Konflikt stehende Typen für 
»memcpy«

Autor: helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: helmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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*

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?
#define Pin_Input       (PINC,PINC0) //PIN C0 ist der Input Pin für das Input-Schieberegister
#define Input_Load_Shift   2      //PIN C2 als Load-Shift Wähler
#define Input_Clock     1      //PIN C1 als Clock am Input Register

...

while (a <16)
{
 while(i<8)
 {
 PORTC |= (1<<Input_Clock);
 _delay_us(10);
 PORTC &= ~(1<<Input_Clock); //1 Clock, um das Register um eine Stelle zu schieben
 Data_to_send[a] &= ~(1<<i);
 Data_to_send[a] |= ((Pin_input)<<i);  
 i++;
 }
i=0;
a++;
} 

Wenn ich das ganze Simuliere verändert sich der Wert in Data_to_send 
kein bisschen, egal was ich an PINC mache...

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Eddie Current (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Eddie Current (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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....

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> (((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.

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Eddie Current (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.