Hallo Leute, ich muss folgende Aufgabe lösen und komme nicht mehr weiter. Vielleicht kann mir jemand weiterhelfen. Aufgabenstellung: In einer Auslieferhalle für Obst und Gemüse können sich Kunden zum Abtransport ihrer Ware einen Gabelstapler leihen. Dazu müssen sie sich mittels einer personifizierten RFID-Karte an diesem Gerät identifizieren. Die Karten besitzen ID-Nummern von 0 bis 511. Da das EEPROM ebenfalls 512 Adressen(Adresse 0 bis Adresse 511) besitzt, soll dort unter der Adresse der jeweiligen Kartennummer die Nutzungsdauer zwecks Abrechnung in Minuten aufsummiert werden. Es ist davon auszugehen, dass die Nutzungsdauer innerhalb eines Tages den Wert 255 Minuten nicht überschreitet. Alle Tage wird dann der Wert ausgelesen und wieder auf 0 zurückgesetzt. Erstellen Sie nun zum Speichern einer einzelnen Gabelstaplernutzung eine Funktion in C++ mit dem Namen addiere_Nutzungsdauer() mit folgenden Anforderungen: - Die Funktion hat keinen Rückgabewert - Der Funktion werden zwei Byte-Parameter übergeben: - RFID-ID (=Adresse im EEPROM) - Ganzzahliger Wert für die Nutzungsdauer in Minuten (1 bis 255) - Die Nutzungsdauer soll stets zu dem Wert im EEPROM hinzugezählt werden. Mein Code bisher: void addiere_Nutzungsdauer (unsigned int EEAdresse, unsigned char EEDaten) { //Schreiben while(EECR & (1<<EEWE); EEAR = EEAdresse; EEDR = EEDaten; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); //an dieser Stelle weiß ich nicht, wie ich die Nutzungsdauer dazuaddieren soll? //Auslesen und zurücksetzen while(EECR & (1<<EEWE); EEAR = EEAdresse; EECR |= (1<<EERE); cout<< "Nutzungsdauer: "<< EEDaten; EECR &= ~(1<<EEAR)|(1<<EEDR); } Ich hoffe, dass der Code soweit stimmt, wenn nicht bitte korrigieren. Die Lücke bitte ergänzen...vielen Dank im voraus ;-) Gruß Daniel
Du musst erst die entsprechende Speicherstelle auslesen, dann die geloggte Nutzungsdauer dem ausgelesenen Wert hinzuaddieren und dann das Ergebnis zurück an die entsprechende Speicherstelle schreiben. Hoffe das hilft dir zum Anstoß. Für die Neunmalklugen: Und ja, sowas würde man eher weniger auf ein EEPROM speichern aber hier gehts ja um den Lerneffekt ;)
Dan N. schrieb: > Erstellen Sie nun zum Speichern einer einzelnen Gabelstaplernutzung eine Klingt nach Hausaufgaben. > Funktion in C++ mit dem Namen addiere_Nutzungsdauer() mit folgenden WOW!!! C++. Das nenn ich mal Luxus ;-) > Anforderungen: > - Die Funktion hat keinen Rückgabewert > - Der Funktion werden zwei Byte-Parameter übergeben: > - RFID-ID (=Adresse im EEPROM) > - Ganzzahliger Wert für die Nutzungsdauer in Minuten (1 bis 255) > - Die Nutzungsdauer soll stets zu dem Wert im EEPROM hinzugezählt > werden. Trivial > void addiere_Nutzungsdauer (unsigned int EEAdresse, unsigned char > EEDaten) Warum nennst du deine Parameter nicht entsprechend. Daß die Daten im EEPROM landen, hat damit nix zu tun. > { > //Schreiben > while(EECR & (1<<EEWE); > EEAR = EEAdresse; > EEDR = EEDaten; > EECR |= (1<<EEMWE); > EECR |= (1<<EEWE); > > //an dieser Stelle weiß ich nicht, wie ich die Nutzungsdauer > dazuaddieren soll? Im Ernst? Vor allem, warum schreibst du ZUERST auf en EEPROM? > > //Auslesen und zurücksetzen > while(EECR & (1<<EEWE); > EEAR = EEAdresse; > EECR |= (1<<EERE); > cout<< "Nutzungsdauer: "<< EEDaten; > EECR &= ~(1<<EEAR)|(1<<EEDR); > } > Ich hoffe, dass der Code soweit stimmt, wenn nicht bitte korrigieren. Die Hoffnung stirbt zuletzt. Uuuup, schon ist sie tot! > Die Lücke bitte ergänzen... Nö. Beitrag "Einheitlicher Umgang mit faulen Schülern etc.?"
M. K. schrieb: > Du musst erst die entsprechende Speicherstelle auslesen, dann die > geloggte Nutzungsdauer dem ausgelesenen Wert hinzuaddieren und dann das > Ergebnis zurück an die entsprechende Speicherstelle schreiben. Hoffe das > hilft dir zum Anstoß. Danke für den Anstoß...ich versuche es mal: void addiere_Nutzungsdauer (unsigned int ID, unsigned char Dauer) { //Schreiben while(EECR & (1<<EEWE); EEAR = ID; EEDR = Dauer; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); //Auslesen while(EECR & (1<<EEWE); EEDR = Dauer; EECR |= (1<<EERE); //Addieren Dauer = Dauer + ???; //Was soll ich hier dazuaddieren? Ich hab ja keine Variable mit der eingelesenen Nutzdauer? Hast du vielleicht wieder einen Anstoß für mich? //Schreiben while(EECR & (1<<EEWE); EEDR = Dauer; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); cout<< "Nutzungsdauer: "<< Dauer; EECR &= ~(1<<EEAR)|(1<<EEDR); } @Falk B.: Ich erwarte nicht, dass jemand für mich die komplette Lösung hinschreibt. Ich bin froh wenn jemand hilft und ich von selbst drauf komme, schließlich will ich dazu lernen. Ich schreibe bald eine Prüfung in Mikrocontollertechnik. Du hast recht...evtl hab ich mich falsch ausgedrückt, aber auf solche Kommentare kann ich trotzdem verzichten. Danke trotzdem für deine Mühe.
:
Bearbeitet durch User
Da wirst Du wohl innerhalb deiner Routine eine lokale Variable definieren müssen, diese mit dem alten EEPROM-Wert befüllen, die Nutzungsdauer dazu addieren und das ganze wieder im EEPROM abspeichern müssen.
Hallo Dan, ich würde ja die avr libc Funktionalität in <avr/eeprom.h> nutzen: https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html Andere falls eine paar Methoden (Funktionen) in einer eigenen Klasse anlegen und dann diese nutzen.
Wolfgang R. schrieb: > Da wirst Du wohl innerhalb deiner Routine eine lokale Variable > definieren müssen, diese mit dem alten EEPROM-Wert befüllen, die > Nutzungsdauer dazu addieren und das ganze wieder im EEPROM abspeichern > müssen. ja so in etwa hätte ich mir das auch gedacht, aber laut aufgabe soll ich ja nur die "Funktion" schreiben. Verstehe ich das richtig, wenn ich innerhalb meiner "Funktion" per cin-Befehl einen wert für die nutzungsdauer einlese? Ich dachte nämlich, dass ich dies im "int main"-Bereich tun müsste und den wert dann als übergabeparameter an die funktion übergeben muss. Aber da ich ja nur dir funktion schreiben soll, stehe ich irgendwie am schlauch...
Die lokale Variable in der Funktion interessiert das Main Programm überhaupt nicht, du kannst ja prinzipiell auch eine Funktion nach dem Motto "schreibe EEPROM(gelesenes EEPROM + Nutzungsdauer) erstellen, da taucht die lokale Variable nicht explizit auf... Du kannst in deiner Funktion immer lokale Variablen für die nötigen Daten anlegen...
Noch ein Versuch: void addiere_Nutzungsdauer (unsigned int ID, unsigned char Dauer) { int x; //Schreiben while(EECR & (1<<EEWE); EEAR = ID; EEDR = x; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); //Auslesen while(EECR & (1<<EEWE); EEDR = x; EECR |= (1<<EERE); //Addieren x = x + Dauer; //Schreiben while(EECR & (1<<EEWE); EEDR = x; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); cout<< "Nutzungsdauer: "<< x; EECR &= ~(1<<EEAR)|(1<<EEDR); } Was sagt ihr dazu? könnte das sol klappen?
EEDR = x; sollte wohl andersrum beim Lesen... und ein Ganzzahlwert sollte hier wohl eher uint sein.
:
Bearbeitet durch User
Wolfgang R. schrieb: > Die lokale Variable in der Funktion interessiert das Main Programm > überhaupt nicht, du kannst ja prinzipiell auch eine Funktion nach dem > Motto "schreibe EEPROM(gelesenes EEPROM + Nutzungsdauer) erstellen, da > taucht die lokale Variable nicht explizit auf... > > Du kannst in deiner Funktion immer lokale Variablen für die nötigen > Daten anlegen... Ach ja stimmt...ich hatte einen Denkfehler! Sorry. Ich hab erst angefangen zu programmieren.
Dan N. schrieb: > cout<< "Nutzungsdauer: "<< x; Ausgaben würde ich nicht in Unterfunktionen machen. Gib nur den Wert zurück und mach die Ausgaben im Main. Dan N. schrieb: > EECR &= ~(1<<EEAR)|(1<<EEDR); Was soll das machen und wozu? Eine gute Idee wäre es, auch endlich mal den AVR-Typ zu nennen.
Dan N. schrieb: > Mein Code bisher: > ........ > Ich hoffe, dass der Code soweit stimmt, wenn nicht bitte korrigieren. > Die Lücke bitte ergänzen...vielen Dank im voraus ;-) Warum nutzt du nicht die vorgefertigten EEPROM Routinen der AVR-Libc? Und falls das gar ein Arduino sein sollte, dann geht das noch viel einfacher. Im Anhang mal ein Testprogrämmchen aus meiner Wühlkiste
Wolfgang R. schrieb: > EEDR = x; sollte wohl andersrum beim Lesen... wie meinst du das? > > und ein Ganzzahlwert sollte hier wohl eher uint sein. Ok. also ändere ich char auf int
Arduino Fanboy D. schrieb: > Im Anhang mal ein Testprogrämmchen aus meiner Wühlkiste Sorry, da war/ist ein Fehler drin! Hier jetzt eine korrigierte Version.
Du musst schon ein wenig selber denken... die Verwendung von char, int uint (unsigned int) etc. ist Dir überlassen, du musst die Datentypen kennen, um zu verstehen, was damit alles passieren kann. Char ist o.k bei zahlen bis 255. Wenn ich ein Datenregister in eine Variable auslese, dann muss ich schreiben variable = Register; Wenn ich ein Register aus einer Variable befülle, dann schreibe ich Register = variable; Also: Ziel = Quelle;
Peter D. schrieb: > Dan N. schrieb: >> cout<< "Nutzungsdauer: "<< x; > > Ausgaben würde ich nicht in Unterfunktionen machen. Gib nur den Wert > zurück und mach die Ausgaben im Main. In der Aufgabe steht, dass die Funktion keinen Rückgabewert haben soll. Kann man dann trotzdem mit "return" etwas zurückgeben? Wenn ja, wie geht das dann? > > Dan N. schrieb: >> EECR &= ~(1<<EEAR)|(1<<EEDR); > > Was soll das machen und wozu? Dieser Befehl setzt die beiden Bits wieder auf Null, so wie es gefordert wird. > > Eine gute Idee wäre es, auch endlich mal den AVR-Typ zu nennen. Atmega 16
Dan N. schrieb: > Noch ein Versuch: > > void addiere_Nutzungsdauer (unsigned int ID, unsigned char Dauer) > { Willst du uns eigentlich veralbern? Warum um alles in der Welt willst du den EPRROM zuerst beschreiben? Hat du mal versucht, den logischen Ablauf normal ohne Programmiersprache zu beschreiben? Dir ist doch nicht mal der Ablauf klar!
Dan N. schrieb: > Kann man dann trotzdem mit "return" etwas zurückgeben? Wenn ja, wie geht > das dann? Mit return... ;-) int myfunction(a, b) { int c = a+b; return(c); }
Wolfgang R. schrieb: > Wenn ich ein Register aus einer Variable befülle, dann schreibe ich > > Register = variable; > > Also: > > Ziel = Quelle; Ach so...jetzt verstehe ich es langsam. Danke das hat schon mal geholfen
Was Peter meint, ist Das Register EECR besitzt keine Bits mit Namen: EEAR und EEDR ! Dan N. schrieb: >> >> Dan N. schrieb: >>> EECR &= ~(1<<EEAR)|(1<<EEDR); >> >> Was soll das machen und wozu? > > Dieser Befehl setzt die beiden Bits wieder auf Null, so wie es gefordert > wird. >> >> Eine gute Idee wäre es, auch endlich mal den AVR-Typ zu nennen. > > Atmega 16
Wolfgang R. schrieb: > Dan N. schrieb: >> Kann man dann trotzdem mit "return" etwas zurückgeben? Wenn ja, wie geht >> das dann? > > Mit return... ;-) > > int myfunction(a, b) > { > int c = a+b; > return(c); > } ok, aber geht das denn, wenn oben in der Funktion "void" steht?
Dan N. schrieb: > Wolfgang R. schrieb: >> Dan N. schrieb: >>> Kann man dann trotzdem mit "return" etwas zurückgeben? Wenn ja, wie geht >>> das dann? >> >> Mit return... ;-) >> >> int myfunction(a, b) >> { >> int c = a+b; >> return(c); >> } > > ok, aber geht das denn, wenn oben in der Funktion "void" steht? Ups, jetzt wirst Du höre, C lernen zu müssen! Void heist soviel wie nichts. Also Keine Daten. Aber man kann es ja mal versuchen und sich die Compilermeldungen ansehen.
Dan N. schrieb: > ok, aber geht das denn, wenn oben in der Funktion "void" steht? Natürlich nicht. eine void-Funktion erwartet keinen Rückgabewert, deswegen ist sie ja auch vom Typ void. Deswegen habe ich die Funktion ja auch vom Typ int deklariert in meinem Beispiel!
Dir fehlen die einfachsten Grundlagen von C! Kauf Dir ein Buch für Anfänger oder schau Dir im Internet entsprechende Beispiele gut an! Hier hast Du auf jeden Fall genug Antworten auf Deine Frage bekommen, der Rest sollte Selbststudium sein, sonst ist der Lerneffekt fast null.
Dan N. schrieb: > Dieser Befehl setzt die beiden Bits wieder auf Null, so wie es gefordert > wird. In welchem AVR-Typ sind EEAR und EEDR Bits? Im Datenblatt wird nichst gefordert (siehe auch Beispielcode).
void addiere_Nutzungsdauer (unsigned int ID, unsigned char Dauer) { int x; x = Dauer; //Schreiben while(EECR & (1<<EEWE); EEAR = ID; EEDR = x; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); //Auslesen while(EECR & (1<<EEWE); x = EEDR; //hab es umgedreht,aber in meine Unterlagen stehts andersrum EECR |= (1<<EERE); //Addieren x = x + Dauer; //Schreiben while(EECR & (1<<EEWE); EEDR = x; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); return x; EEAR = 0x00; EEDR = 0x00; }
Dan N. schrieb: > Wolfgang R. schrieb: > >> Wenn ich ein Register aus einer Variable befülle, dann schreibe ich >> >> Register = variable; >> >> Also: >> >> Ziel = Quelle; > > Ach so...jetzt verstehe ich es langsam. Danke das hat schon mal geholfen Ich auch. Du hast NULL Plan von Programmierung und C und kopierst hirnlos irgendwelchen Scheiß zusammen. Tolles Konzept. Wirst bestimmt bald Bachelor.
> Ups, jetzt wirst Du höre, C lernen zu müssen! > > Void heist soviel wie nichts. Also Keine Daten. > > Aber man kann es ja mal versuchen und sich die Compilermeldungen > ansehen. Das weiß ich selbst, dass VOID "nichts" heißt, deswegen frag ich ja, weil Wofgang geschrieben hat, dass ich mit "return" zurückgeben soll...aber meiner meinung nach geht das nicht
Dan N. schrieb: > In der Aufgabe steht, dass die Funktion keinen Rückgabewert haben soll. Es ist guter Programmierstil, wenn man Funktion und Anzeige voneinander trennt. Denn das wird schnell ein Chaos, wenn jede Funktion wild auf das Display schreibt. Dan N. schrieb: > Kann man dann trotzdem mit "return" etwas zurückgeben? Wenn ja, wie geht > das dann? Steht in jedem C-Tutorial.
Peter D. schrieb: > Dan N. schrieb: >> Dieser Befehl setzt die beiden Bits wieder auf Null, so wie es gefordert >> wird. > > In welchem AVR-Typ sind EEAR und EEDR Bits? > > Im Datenblatt wird nichst gefordert (siehe auch Beispielcode). Sorry, da hab ich mich vertan...
Wolfgang R. schrieb: > Dan N. schrieb: >> ok, aber geht das denn, wenn oben in der Funktion "void" steht? > > Natürlich nicht. eine void-Funktion erwartet keinen Rückgabewert, > deswegen ist sie ja auch vom Typ void. > > Deswegen habe ich die Funktion ja auch vom Typ int deklariert in meinem > Beispiel! Ja das verstehe ich ja, aber das darf ich in meinem Fall laut Angabe nicht, deswegen verwirrt mich das und bekomme von gewissen Personen unschöne Kommentare wenn ich nachfrage :-)
Peter D. schrieb: > Dan N. schrieb: >> In der Aufgabe steht, dass die Funktion keinen Rückgabewert haben soll. > > Es ist guter Programmierstil, wenn man Funktion und Anzeige voneinander > trennt. Denn das wird schnell ein Chaos, wenn jede Funktion wild auf das > Display schreibt. > > > Dan N. schrieb: >> Kann man dann trotzdem mit "return" etwas zurückgeben? Wenn ja, wie geht >> das dann? > > Steht in jedem C-Tutorial. Nochmal für alle: ich persönlich würde es auch nicht so schreiben, aber laut Angabe darf die Funktion keinen Rückgabewert haben!
Danke an Alle :-) Irgendwie werde ich schon dahinter kommen...
Ich denke man hat sich hier von Deiner Verwendung von cout in Deinem ersten Code, den Du gezeigt hat, auf einen unnötigen Weg führen lassen. Es ist schon richtig, dass es stilistisch nicht gut ist, eine evtl. Ausgabe in so einer Art von Funktion zu machen. Aber der Schwerpunkt lag ohnehin, soweit ich die Aufgabe verstehe, darin aus dem EEPROM zu lesen und darein zu schreiben. Falls also eine Ausgabe erfolgt, so ist das nicht schön, aber nicht geradewegs falsch. In der Aufgabe selbst, steht nichts von Ausgabe; also brauchst Du das auch nicht implementieren. Ausserdem wird in der Aufgabe ausdrücklich gesagt, dass die Funktion keinen Rückgabewert haben soll. Wie auch immer also auch die Ausgabe machst oder ob überhaupt; mit dem Rückgabewert (wie man es normalerweise schön machen würde) darfst Du es gar nicht machen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.