Twi write und read ATmega 16 Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte
Autor |
Twi write und read ATmega 16 Suche nach: atmega (406) |
|
|
|
|
BID = 688062
Zuse1936 Gerade angekommen
Beiträge: 5
|
|
Hallo liebe Techniker, ich bin biotechnolgin und habe folgende aufgaben zu lösen.leider hab ich bisher nie c programmiert, aber ich hab am wochenende ein tutorial durchgearbeitet,
Bis auf den Programmierteil (c) hab ich alles durchgearbeitet.
Ich hoffe ihr könnt mit dort 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
Gegeben ist folgendes Programm, dass um read und write erweitert werden soll
Code : |
#include "iti_twi.h"
#include "lcd.h"
#include <avr/io.h>
// Informiert den Compiler über die CPU-Taktfrequenz: 4 MHz
// Nötig für <util/delay.h>
#define F_CPU 4000000UL
#include <util/delay.h>
/*
Schreibt ein Byte in ein Register eines TWI-Gerätes.
Parameter:
uint8_t twi_addr - Addresse des TWI-Gerätes.
uint8_t reg - Nr Register des TWI-Gerätes in das geschrieben werden soll.
uint8_t data - Byte das geschrieben werden soll.
Rückgabe:
1 falls Schreiben erfolgreich, sonst 0.
Ablauf:
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.
*/
int twi_writeregister(uint8_t twi_addr, uint8_t reg, uint8_t data) {
// ...
return 1;
}
/*
Liest ein Byte aus einem Register eines TWI-Gerätes.
Parameter:
uint8_t twi_addr - Addresse des TWI-Gerätes.
uint8_t reg - Nr Register des TWI-Gerätes von dem gelesen werden soll.
uint8_t* data - Addresse einer Variable, in die das gelesene Byte
geschrieben werden soll.
Rückgabe:
1 falls Lesen erfolgreich, sonst 0.
Insbesondere soll 0 zurückgegeben werden, falls der Pointer data==0.
Ablauf:
1. Starte die TWI-Kommunikation.
2. Schreibe die Schreib-Addresse des TWI-Gerätes auf den Bus.
3. Schreibe die Nr des Registers.
4. Stoppe die Kommunikation
5. Starte die TWI-Kommunikation.
6. Schreibe die Lese-Addresse (LSB==1!!!) des TWI-Gerätes auf den Bus.
7. Lese das Byte aus dem Register, setze dabei kein ACK.
5. Stoppe die TWI-Kommunikation.
*/
int twi_readregister(uint8_t twi_addr, uint8_t reg, uint8_t* data) {
// ...
return 1;
}
int main () {
int dist = 0; // Entfernung
// ...
// Initialisiere den TWI-Bus:
// ...
// Initialisiere den Bildschirm:
// ...
while (1) {
// Sende den Befehl für "Messung in cm Starten"
// an den SRF02 Sensor:
// ...
// Warte bis das Ergebnis bereit steht:
_delay_ms (80.0);
// Lese das Ergebnis vom SRF02:
// ...
// Schreibe das Ergebnis auf dem Bildschirm:
lcd_write(VT); // erste Zeile, erste Spalte
lcd_puti(dist);// schreibe Ergebnis
// Füge Wartezeit hinzu, um nicht zu häufig zu lesen
}
return 0;
}
[\code]
|
|
Ich hab zusätzlich noch folgendes in Erfahrung bringen können:
Die TWI-Einheit des ATmega enthält die folgenden 5 Register:
Register Bezeichnung
TWBR TWI Bit Rate Register
TWCR TWI Control Register
TWSR TWI Status Register
TWDR TWI Data Register
TWAR TWI Adress Register
TWINT TWI Interrupt Flag
Dieses Bit wird immer dann gesetzt, wenn die
TWI-Einheit mit einer Aktion fertig ist. Solange
das Bit gesetzt ist, wird die TWI-Einheit angehalten.
Um das Bit wieder zu löschen muss es mit
einer logischen 1 beschrieben werden.
TWSTO TWI STOP Condition Bit Dieses Bit löst eine STOP-Condition aus.
TWWC TWI Write Collision Flag
Dieses Bit wird gesetzt, wenn auf das Datenregister
TWDR geschrieben wird, während die TWIEinheit noch beschäftigt ist.
TWIE TWI Interrupt Enable
Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, sobald TWINT gesetzt wird.
TWSTA TWI START Condition Bit
Dieses Bit löst eine START-Condition aus, sobald der Bus frei ist.
Ihr seit meine letzte hoffnung
ich weiß nicht wie ich das programmieren soll.ich sitz schon seit einer woche daran
LG
Zuse1936
Ps:
Als Anhang hab ich die gesamten Dateien hinzugefügt die wir mitbekommen.
|
|
BID = 688087
Jornbyte Moderator
      
Beiträge: 7242
|
|
BID = 688135
Zuse1936 Gerade angekommen
Beiträge: 5
|
Ersteinmal dickes dankeschön für deinen Hinweis.
Diesen Post habe ich mir schon vorher durchgelesenn bevor ich mich dazu entschlossen habe das Thema zu posten.
Leider brauch noch einen Schubser wie ich die analogien übertragen kann
ich würd mich echt freuen wenn mir jemand helfen kann ich verzweifle echt schon lange an dieser aufgabe
danke schon mal
Zuse1936
|
BID = 688136
DonComi Inventar
     
Beiträge: 8605 Wohnort: Amerika
|
Hallo,
Ich habe zwar momentan, wegen des Studiums und einem Projekt (  @Jornbyte) wenig Zeit, aber wo hakt es denn genau?
Ich sehe, du hast eine leeren Rumpf der Funktion int twi_writeregister.
Kommst du da nicht weiter?
Wenn ja, dann empfehle ich dir dringend die Lektüre des Datenblatts des Chips, der ausgelesen werden. Bei guten Datenblättern sind dort sogenannte Bus-Timing-Diagramme (oder nur Timing Diagrams) drin, wo der Ablauf der einzelnen Bus-Zugriffe erläutert wird.
Grundsätzlich:
Ist denn der Bus schon richtig aufgebaut?
Pullup-Widerstände an SDA und SCL? Welche Spannungsversorgung benötigt der Slave und welche hat der Atmega (Im Optimalfall die gleiche  )?
Funktioniert der Programmteil für das LCD schon? Sodass du dort nicht auch noch eine offene Baustelle hast?
Ein Tipp noch:
AVR haben keine Hardware zum Rechnen mit Gleit- oder Festkommazahlen. Daher soltest du das _delay_ms(80.0); durch _delay_ms(80); ersetzen.
_________________
|
BID = 688221
Zuse1936 Gerade angekommen
Beiträge: 5
|
Also ersteinaml bin ich euch echt sehr dankbar für eure Hilfe
Die Aufgaben a,b,d,e,f stellen kein Problem da.
Das einzige was uns fehlt sind die von die genannten leeren rümpfe:
int twi_writeregister...
int twi_readregister...
alles andere ist vorgegeben.mir wurde gesagt, dass ich nur auf methoden aus den mitgeschickten dateien zugreifen soll um die leeren rümpfe zu füllen.und das mir folgende codefragement dabei helfen sollen:
Code : |
// Init-, Start- und Stop-Routinen:
////////////////////////////////////////////////////////////
/* Setzt die Geschwindikeit des Busses abhängig von der
CPU-Geschwindigkeit.
==> SLCfreq==50KHz bei 1MHz CPU-Takt
*/
void twi_init();
/* Leitet einen TWI (I2C) Sende- oder Empfangsvorgang ein.
Falls erfolgreich gibt 1 zurück, sonst 0; */
int twi_start();
int twi_rep_start(); // kann auch durch twi_stop(); twi_start(); ersetzt werden.
/* Beendet einen TWI (I2C) Sende- oder Empfangsvorgang. */
void twi_stop();
|
|
Code : |
////////////////////////////////////////////////////////////
// Senderoutinen:
/* Alle Senderoutinen geben eine 0 zurück,
falls Sendevorgang nicht erfolgreich.
*/
/* Sendet eine 8Bit-Slave-Addresse, um anschließend zu schreiben.
(8Bit, LSB muss 0 sein) */
int twi_sla_w(uint8_t slave_adress);
/* Sendet eine 8Bit-Slave-Addresse, um anschließend zu lesen.
(8Bit, LSB muss 1 sein) */
int twi_sla_r(uint8_t slave_adress);
/* Schreibt ein Byte auf den Bus */
int twi_send(uint8_t data)
|
|
Code : |
////////////////////////////////////////////////////////////
// Empfangsroutine:
/* Liest ein Byte vom Bus.
Parameter:
int ack - ACK-Bit
uint8_t* data - Unter *data wird das gelesene Byte gespeichert
Falls ack!=0 wird der Empfang mit einem ACK-Bit bestätigt (== Erwarte nächstes
Byte). Sonst wird das Bit nicht gesetzt (== Transmission beendet).
Rückgabewert:
Die Methode gibt eine 0 zurück falls ein Fehler auftritt. Sonst eine 1.
Ein Fehler tritt auf wenn:
- data==0 (null-pointer)
- Lesen nicht erfolgreich war.
Falls das Lesen nicht erfolgreich war, wird *data auf 0x00 gesetzt.
*/
int twi_read(int ack, uint8_t* data);
|
|
Die ganze Theorie dahinter habe ich verstanden.nur leider kann ich nur mäßig bzw. schlecht programmieren
Nochmals ich bin euch echt dankbar für eure Unterstützung vll bekommen wir das gemeinsam hin
LG
Zuse1936
|
BID = 688233
Zuse1936 Gerade angekommen
Beiträge: 5
|
Hallo, ich bins jetzt nochmal, ich hab versucht die noch fehlenden Rümpfe wie vorgegeben aufzufüllen.Aber irgendwie funktioniert es noch nicht ganz:
Code : |
#include "iti_twi.h"
#include "lcd.h"
#include <avr/io.h>
// Informiert den Compiler über die CPU-Taktfrequenz: 4 MHz
// Nötig für <util/delay.h>
#define F_CPU 4000000UL
#include <util/delay.h>
/*
Schreibt ein Byte in ein Register eines TWI-Gerätes.
Parameter:
uint8_t twi_addr - Addresse des TWI-Gerätes.
uint8_t reg - Nr Register des TWI-Gerätes in das geschrieben werden soll.
uint8_t data - Byte das geschrieben werden soll.
Rückgabe:
1 falls Schreiben erfolgreich, sonst 0.
Ablauf:
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.
*/
int twi_writeregister(uint8_t twi_addr, uint8_t reg, uint8_t data) {
//1//
int twi_start();
//2//
int twi_sla_w(uint8_t slave_adress);
//3//
int twi_send(uint8_t reg);
//4//
int twi_send(uint8_t data);
//5//
void twi_stop ();
return 1;
}
/*
Liest ein Byte aus einem Register eines TWI-Gerätes.
Parameter:
uint8_t twi_addr - Addresse des TWI-Gerätes.
uint8_t reg - Nr Register des TWI-Gerätes von dem gelesen werden soll.
uint8_t* data - Addresse einer Variable, in die das gelesene Byte
geschrieben werden soll.
Rückgabe:
1 falls Lesen erfolgreich, sonst 0.
Insbesondere soll 0 zurückgegeben werden, falls der Pointer data==0.
Ablauf:
1. Starte die TWI-Kommunikation.
2. Schreibe die Schreib-Addresse des TWI-Gerätes auf den Bus.
3. Schreibe die Nr des Registers.
4. Stoppe die Kommunikation
5. Starte die TWI-Kommunikation.
6. Schreibe die Lese-Addresse (LSB==1!!!) des TWI-Gerätes auf den Bus.
7. Lese das Byte aus dem Register, setze dabei kein ACK.
5. Stoppe die TWI-Kommunikation.
*/
int twi_readregister(uint8_t twi_addr, uint8_t reg, uint8_t* data) {
/*1*/
int twi_start();
/*2*/
int twi_sla_r(uint8_t slave_adress);
/*3*/
int twi_send(uint8_t reg);
/*4*/
int twi_stop();
/*5*/
int twi_start();
/*6*/
int twi_send(uint8_t data);
/*7*/
int twi_read(int ack, uint8_t* data);
/*8*/
void twi_stop ();
return 1;
}
int main () {
int dist = 0; // Entfernung
// ...
// Initialisiere den TWI-Bus:
// ...
// Initialisiere den Bildschirm:
// ...
while (1) {
// Sende den Befehl für "Messung in cm Starten"
// an den SRF02 Sensor:
// ...
// Warte bis das Ergebnis bereit steht:
_delay_ms (80.0);
// Lese das Ergebnis vom SRF02:
// ...
// Schreibe das Ergebnis auf dem Bildschirm:
lcd_write(VT); // erste Zeile, erste Spalte
lcd_puti(dist);// schreibe Ergebnis
// Füge Wartezeit hinzu, um nicht zu häufig zu lesen
}
return 0;
}
|
|
Was meint ihr?
hab ich irgendwelche methoden falsch aufgerufen?
Wo liegt mein Fehler?
danke für hilfe
Zus1936
|
BID = 688260
Zuse1936 Gerade angekommen
Beiträge: 5
|
So ich hab noch mal n update.aber so ganz bin ich mir ganz sicher ob das so korrekt
Code : |
#include "iti_twi.h"
#include "lcd.h"
#include <avr/io.h>
// Informiert den Compiler über die CPU-Taktfrequenz: 4 MHz
// Nötig für <util/delay.h>
#define F_CPU 4000000UL
#include <util/delay.h>
/*
Schreibt ein Byte in ein Register eines TWI-Gerätes.
Parameter:
uint8_t twi_addr - Addresse des TWI-Gerätes.
uint8_t reg - Nr Register des TWI-Gerätes in das geschrieben werden soll.
uint8_t data - Byte das geschrieben werden soll.
Rückgabe:
1 falls Schreiben erfolgreich, sonst 0.
Ablauf:
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.
*/
int twi_writeregister(uint8_t twi_addr, uint8_t reg, uint8_t data) {
//1//
twi_start();
//2//
twi_sla_w(twi_addr);
//3//
twi_send(reg);
//4//
twi_send(data);
//5//
twi_stop ();
return 1;
}
/*
Liest ein Byte aus einem Register eines TWI-Gerätes.
Parameter:
uint8_t twi_addr - Addresse des TWI-Gerätes.
uint8_t reg - Nr Register des TWI-Gerätes von dem gelesen werden soll.
uint8_t* data - Addresse einer Variable, in die das gelesene Byte
geschrieben werden soll.
Rückgabe:
1 falls Lesen erfolgreich, sonst 0.
Insbesondere soll 0 zurückgegeben werden, falls der Pointer data==0.
Ablauf:
1. Starte die TWI-Kommunikation.
2. Schreibe die Schreib-Addresse des TWI-Gerätes auf den Bus.
3. Schreibe die Nr des Registers.
4. Stoppe die Kommunikation
5. Starte die TWI-Kommunikation.
6. Schreibe die Lese-Addresse (LSB==1!!!) des TWI-Gerätes auf den Bus.
7. Lese das Byte aus dem Register, setze dabei kein ACK.
5. Stoppe die TWI-Kommunikation.
*/
int twi_readregister(uint8_t twi_addr, uint8_t reg, uint8_t* data) {
/*1*/
twi_start();
/*2*/
twi_sla_r(twi_addr);
/*3*/
twi_send(reg);
/*4*/
twi_stop();
/*5*/
twi_start();
/*6*/
twi_send(twi_addr);
/*7*/
twi_read(int ack, data);
/*8*/
twi_stop ();
return 1;
}
int main () {
int dist = 0; // Entfernung
int distoben = 18;
int distunten = 15;
// Initialisiere den TWI-Bus:
void twi_init();
// Initialisiere den Bildschirm:
void lcd_init();
while (1) {
// Sende den Befehl für "Messung in cm Starten"
// an den SRF02 Sensor:
twi_writeregister(0xE0,0,0x51);
// Warte bis das Ergebnis bereit steht:
_delay_ms (80.0);
// Lese das Ergebnis vom SRF02:
Lesen = twi_readregister (0xE0,2,distoben);
distoben = Lesen;
Lesen = twi_readregister (0xE0,3,distunten);
distunten = Lesen;
int dist = ( (*distoben)+256)+(*distunten);
// Schreibe das Ergebnis auf dem Bildschirm:
lcd_write(VT); // erste Zeile, erste Spalte
lcd_puti(dist);// schreibe Ergebnis
// Füge Wartezeit hinzu, um nicht zu häufig zu lesen
_delay_ms (100.0);
}
return 0;
}
|
|
|
|
Zum Ersatzteileshop
Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum
Datenschutz
Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland
gerechnet auf die letzten 30 Tage haben wir 13 Beiträge im Durchschnitt pro Tag heute wurden bisher 5 Beiträge verfasst © x sparkkelsputz Besucher : 184111209 Heute : 6912 Gestern : 55982 Online : 257 15.5.2025 17:00 13 Besucher in den letzten 60 Sekunden alle 4.62 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
|
xcvb
ycvb
0.0638248920441
|