Guten Tag,
ich muss mich auf Praktikum vorbereiten und dazu folgende Aufgaben
lösen.
Leider tapp ich zur zeit heftig im dunklen, weil ich eigentlich
überhaupt keine Ahnung habe.Ich hoffe ihr könnt mir helfen
Die Aufgabe:Abfragen eines Sensors über I^2C Bus
Die TWI-Schnittstelle des ATmega erlaubt den Zugriff auf I2C-Bus-Geräte.
Deswegen gelten im folgenden Text TWI und I2C als gleichbedeutend.
a) Machen Sie sich mit dem prinzipiellen Ablauf einer I2C-Kommunikation
vertraut (z.B. ATmega Dokumentation).
b) Laden Sie von der ITI-Page das Template-Paket zu dieser Aufgabe
herunter. Machen Sie sich mit dem TWI-Treiber (iti_twi.c, iti_twi.h)
vertraut.
c) Implementieren Sie in der Hauptdatei Uebung2.c die fehlenden
Routinen:
int twi_writeregister(uint8_t twi_addr, uint8_t reg, uint8_t data)
int twi_readregister (uint8_t twi_addr, uint8_t reg, uint8_t* data)
d) Machen Sie sich mit der Möglichkeit vertraut, den SRF02 Sensor über
I2C-Bus anzu-sprechen (siehe SRF02-Datenblatt auf der ITI-Page).
e) Führen Sie in der Hauptschleife des Programms eine Messung mit dem
SRF02 aus und stellen Sie das Ergebnis auf dem Bildschirm dar.
f) Bringen Sie in Erfahrung, an welchen Pins des ATmega16 der SRF02
angeschlossen werden sollte.
g) Testen Sie sie ausgiebig ihre Lösung
Praktische Anmerkungen zu Aufgabe 1:
Bevor Sie ihre Lösung testen können müssen folgende Einstellun-gen im
AVR-Studio vorgenommen werden: Menu->Project->Configuration
Options->General-> Optimization: -O1 Fuses: Int. Osc. 4MHz. + 64 ms
In der Abbildung rechts ist die Anschlussbox für den Ultraschall-Sensor
und ein Servo dargestellt. Für die Aufgabe 1 sollen alle Anschlüsse bis
auf PWM verbunden werden.
Meine Lösungen:
a)
Der Beginn einer Übertragung wird mit dem Start-Signal vom Master
angezeigt, dann folgt die Adresse. Diese wird durch das ACK-Bit vom
entsprechenden Slave bestätigt. Abhängig vom R/W-Bit werden nun Daten
Byte-weise geschrieben (Daten an Slave) oder gelesen (Daten vom Slave).
Das ACK beim Schreiben wird vom Slave gesendet und beim Lesen vom
Master. Das letzte Byte eines Lesezugriffs wird vom Master mit einem NAK
quittiert, um das Ende der Übertragung anzuzeigen. Eine Übertragung wird
durch das Stop-Signal beendet. Oder es wird ein Repeated Start am Beginn
einer erneuten Übertragung gesendet, ohne die vorhergehende Übertragung
mit einem Stop-Signal zu beenden.
Alle Bytes werden dabei „Most Significant Bit First“ übertragen.
Für den High Speed Mode wird zuerst im Fast oder Standard Mode ein
Master Code geschickt, bevor auf die erhöhte Frequenz umgeschaltet wird.
Der I²C-Bus ist von der Definition her recht einfach, aber auch
störanfällig. Diese Tatsache schränkt die Verwendung auf störungsarme
Anwendungsbereiche ein, wo weder mit Übersprechen, Rauschen,
EMV-Problemen, noch mit Kontaktproblemen (Stecker, Buchsen) zu rechnen
ist.
(Quelle:http://de.wikipedia.org/wiki/I%C2%B2C)
b)Diese Dateien hab ich als Anhang hinzufegügt
c)Leider bin ich hier vollkommmen überfordert
Ich bräuchte dringend hilfe von euch
d)Auch zu diesem Punkt habe ich leider nichts gefunden
Mir ist vor allem die c wichtig ich brauch tatkräftige unterstützung
Danke schon mal
LG
Alfred
Für c)
1. Starte die TWI-Kommunikation.
2. Schreibe die Schreib-Addresse des TWI-Gerätes auf den Bus.
3. Schreibe die Nr. des Registers auf den Bus
4. Schreibe das Byte auf den Bus.
5. Stoppe die TWI-Kommunikation.
also mal fürs senden. fürs empfangen eben nur andersrum.
Frag mich aber nicht, was ihr da für nen IC ansprechen wollt, das was du
da programmieren sollst, ist auf jeden Fall nicht im Standard
vordefiniert.
Offenbar hat der IC mehrere Register die du getrennt ansprechen kannst.
d)Les dir das datenblatt durch.
BTW: Von wikipedia kopieren kommt nicht gut, formuliere a) selbst aus
und verstehe es. Besonders im Bezug auf die atmegas sind da sachen drin
die keinen Bezug haben, weils nicht möglich ist,.
So mehr sag ich jetzt nimmer ;-)
Hi d...,
ich hab mich über deinen Beitrag echt gefreut.
Unglücklicherweise sitz ich immer noch vor der Kuh wie ein Huhn vor dem
Ei oder so^^-
mit anderen worten ich hab große probleme mit der Programmierung des
ganzen.
Ich hatte bislang nur Java und c ist für mich neu.
Allerdings wurde uns gesagt das es viele parallelen gibt.
Ich hab mich am wochenende duch das c tutorial gehangelt.
Nichtsdestotrotz bin ich zur zeit überfordert,
Deswegen brauch ich eure hilfe Jungs und Mädels.
LG und danke noch mal an d...
Alfred
Du kannst hier sicherlich Hilfe erwarten, wenn Du Deinen Code hier
einstellst und um Überprüfung bittest.
Lernen musst Du aber schon alleine, das können wir Dir nicht
abnehmen....
Moin
leider bin ich immer noch nicht viel schlauer,
ich wär echt dankbar wenn ihr mir bei der aufgabe c helfen könnt,
Wie gesagt dort habe ich die meisten probleme,
ich brauch da echt derbe hilfe
wenn ihr helfen könnt wär das toll
danke
LG
alfred
Alfred H. schrieb:> Könnt ihr mir helfen
Na ja
Du rufst ja überhaupt keine Funktionen auf!
Und das was du dem Compiler da an Funktionen verkaufen willst, sind ...
gar keine.
Das beste wird sein, du gehst in die nächte Bibliothek und besorgst dir
erst mal etwas Literatur zum Thema C.
Wenn das alles ist, was du alleine in C hinkriegst, dann fehlt dir da
jede Menge. Das hat keinen Sinn, dir da jetzt an diesem konkreten
Beispiel zu 'helfen'. Denn die Hilfe müsste so aussehen, dass das Forum
dein Programm schreibt. Das würde dir zwar helfen ins Praktikum
hineinzukommen, würde allerdings dein Problem nicht lösen. Denn du
würdest achtkantig sofort wieder hinausfliegen, wenn der Dozent merkt,
dass du keinen Tau hast. Und bei dem was man in deinem Code so sieht,
merkt der in 10 Sekunden dass du die abgegene TWI Lösung nicht selbst
geschrieben hast.
brutal gesagt.
Nichts für ungut.
Alfred H. schrieb:> Die Methoden sind doch in der twi_h und die twi_c Datei schon> vorgegeben.Ich muss doch ledoglich nur drauf zu greifen.
Eben.
Das ist ja das traurige, wenn du nach 9 Tagen immer noch nicht
rausgefunden hast, wie das geht.
Aber ok. Deine Funktion twi_writeregister mal auf C Syntax gebracht
1
/*
2
Schreibt ein Byte in ein Register eines TWI-Gerätes.
3
4
Parameter:
5
uint8_t twi_addr - Addresse des TWI-Gerätes.
6
uint8_t reg - Nr Register des TWI-Gerätes in das geschrieben werden soll.
7
uint8_t data - Byte das geschrieben werden soll.
8
9
Rückgabe:
10
1 falls Schreiben erfolgreich, sonst 0.
11
12
Ablauf:
13
1. Starte die TWI-Kommunikation.
14
2. Schreibe die Schreib-Addresse des TWI-Gerätes auf den Bus.
damit macht diese Funktion zumindest irgendetwas (sie ruft andere
Funktionen auf, getreu deinem 'Fahrplan' und füttert sie mit den Werten.
Ob das in Summe auch das richtige macht ist eine andere Geschichte.
Und aus main aufrufen solltest du sie auch.
Alfred H. schrieb:> Ich hab jetzt die vorschläge versucht in die tat umzusetzten.
Na siehst du.
Jetzt schauts doch schon viel freundlicher aus
> Allerdings brauch ich noch bissl hilfe.
Glaub ich.
Jetzt gehst du erst mal alle Fehlermeldungen vom Compiler durch und
bearbeitest sie. Die bei denen du nicht klar kommst:
* Zeile posten. Auch ein bischen Umfeld mit dazu.
Wenn es so aussieht, als ob eine Variable im Fehler involviert ist,
auch immer die Variablendefinition mit dazu
* Fehlermeldung posten
So, ich hab jetzt versucht, die Fehler soweit wie möglich zu minimieren,
aber bei einem kriege ich es einfach nicht hin:
twi_read(ack, data); //Zeile 84
dazu hier mal der Fehlercode von AVR:
../Uebung2.c: In function 'twi_readregister':
../Uebung2.c:84: error: 'ack' undeclared (first use in this function)
../Uebung2.c:84: error: (Each undeclared identifier is reported only
once
../Uebung2.c:84: error: for each function it appears in.)
twi_read kommt aus der Datei iti_twi.c und das steht das:
1
int twi_read(int ack, uint8_t* data){
2
3
// Falls data ein 0-Pointer ist, beende:
4
if (data==0) { return 0; }
5
6
// Starte den Lesevorgang:
7
if (ack) { // ACK Senden
8
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
9
} else { // NACK Senden
10
TWCR = (1<<TWINT)|(1<<TWEN);
11
}
...
ich komme mit dieser Variable ack einfach nicht klar(aber ich weiß, was
ack an sich ist, nur weiß ich nicht, wie ich den Fehler wegkriege). Wäre
um Hilfe echt dankbar.
Gruß Alfred
Alfred H. schrieb:> So, ich hab jetzt versucht, die Fehler soweit wie möglich zu minimieren,> aber bei einem kriege ich es einfach nicht hin:>> twi_read(ack, data); //Zeile 84>> dazu hier mal der Fehlercode von AVR:>> ../Uebung2.c: In function 'twi_readregister':> ../Uebung2.c:84: error: 'ack' undeclared (first use in this function)
Das bedeutet, dass es keine Variable ack gibt.
Und der Compiler hat recht. In
existiert tatsächlich keine Variable ack. Du versuchst zwar eine zu
benutzen (beim Aufruf von twi_read) aber ich sehe keine Definition einer
derartigen Variablen.
Aber:
Das ist sowieso nur die halbe Miete.
Denn wenn ich mir die Funktionsbeschreibung von twi_read ansehe, dann
hat dieser Parameter eine spezielle Bedeutung.
Dort übergibst du, ob du einen Acknowledge haben möchtest oder nicht.
D.h. die Lösung für das 'Problem' besteht nicht darin, in
twi_readregister eine Variable ack anzulegen, sondern zu überlegen: was
will ich? Will ich einen Ackknowlege mitsenden, in dem Fall lautet der
Aufruf
1
twi_read(1,data);
oder will ich keinen Ackknowledge mitsenden, in dem Fall lautet der
Aufruf
1
twi_read(0,data);
d.h. Wenn du einen Funktionsaufruf hast mit Parametern, dann darfst du
nicht einfach hergehen, holodero, und einfach Variablen übergeben.
Sondern man sieht sich an: Was bedeuten diese Parameter, welche Werte
muss ich da mit reingeben? Ist das vielleicht ein Steuerparameter, mit
dem ich die Funktion veranlassen kann, etwas spezielles zu tun? Wenn ja:
welche Möglichkeiten habe ich? Welche von diesen Möglichkeiten will ich
denn haben?
Ah ja und genau kein Ack habe ich ja auch gebraucht, nur wusste ich
nicht, wie ich das bewerkstelligen soll. Dankeschön dafür.
Noch eine letzte Frage, ich habe jetzt zwar keine Fehler mehr im
Programm, aber dafür zeigt er mir noch 2 Warnings an:
int Lesen = twi_readregister (0xE0,2,distoben); //Zeile 123
Lesen = twi_readregister (0xE0,3,distunten); //Zeile 125
und hier nochmal der Fehlercode von AVR:
../Uebung2.c: In function 'main':
../Uebung2.c:123: warning: passing argument 3 of 'twi_readregister'
makes pointer from integer without a cast
../Uebung2.c:125: warning: passing argument 3 of 'twi_readregister'
makes pointer from integer without a cast
Das ist das letzte, was noch ausgegeben wird, wäre wirklich super, wenn
sie sich das nochmal anschauen. Danke im Voraus!
Gruß Alfred
Alfred H. schrieb:> Noch eine letzte Frage, ich habe jetzt zwar keine Fehler mehr
Oh doch!
> im> Programm, aber dafür zeigt er mir noch 2 Warnings an:
In diesem Fall ist es eine Warnung, die einem Fehler gleichzusetzen ist.
> Das ist das letzte, was noch ausgegeben wird, wäre wirklich super, wenn> sie sich das nochmal anschauen. Danke im Voraus!
Jetzt ist der Zeitpunkt gekommen, an dem du dein C-Buch auspacken und
das ganze grosse Kapitel über Argmuent Passing, insbesondere 'Pass per
Pointer' durcharbeiten solltest.
Das ist einer der Punkte, in dem sich C massiv von Java unterscheidet.
Die Lösung besteht aus dem Hinzufügen eines einzigen Zeichens beim
Aufruf. Aber dieses Zeichen und vor allem das Verständnis dessen was es
bewirkt und warum es notwendig ist, ist genau das, was dieses Kapitel zu
ein paar Buchseiten aufbläht.