Ahoi liebe Forengemeinde,
ich versuche gerade, mir die Grundlagen der I2C Programmierung
anzueignen. Habe mir zur Hilfestellung folgendes Tutorial angeschaut
http://www.rn-wissen.de/index.php/TWI_Slave_mit_avr-gcc
Habe den Code soweit verstanden, an der Umsetzung hapert es noch. Der
Slave läuft soweit. Laut implementierung gibt er über UART im
1/2-Sekunden Takt zehn Zahlen aus.
Die Implementierung des Masters lief leider nicht so gut. Es wird zwar
alles kompiliert, nur tut sich leider nichts. Um den Master zu testen
habe ich auch hier eine Ausgabe per UART eingefügt. Nun gibt mir das
Hyperterminal leider überhaupt nichts aus, noch nicht einmal das
Initialisieren der UART Schnittstelle (was laut Code per uart_puts
bestätigt wird). Habe den gleichen Controller genutzt wie beim SLAVE, am
µC kann es folglich nicht liegen. Bin ein wenig verzweifelt, da der UART
Code des Masters identisch mit dem des Slave ist. Bei den Controllern
handelt es sich um Atmega328p, Software ist AtmelStudio6
Über Hilfe würde ich mich sehr freuen!
Hier der Code:
> #include "uart.h" //UART-Lib von P- Fleury
Die UART Lib vom Fleury Peter ist interrupt getrieben.
Wenn du also keinen sei() machst, dann laufen auch keine Interrupts und
dein Programm gibt solange in den internen Puffer aus, bis dieser voll
ist. Danach hängt dann alles.
Ein sei() VOR dem ersten uart_puts() behebt dieses.
Vielen Dank für die schnelle Antwort! Leider ist das problem noch nicht
ganz behoben. Wenn ich den µC resette, empfange ich drei Zeichen, das
wars leider auch schon. Diese sind auch nicht das erwartete, sondern
eher kryptisch. Das Problem hatte ich beim Slave jedoch auch, war aber
nach 1-2 Sekunden weg.
Bin ein wenig mit meinem Latein am Ende :(
Nils K. schrieb:> Vielen Dank für die schnelle Antwort! Leider ist das problem noch nicht> ganz behoben.
Dann speck erst mal ab.
1
intmain(void)
2
{
3
uart_init((UART_BAUD_SELECT((BAUD),F_CPU)));
4
5
sei();
6
while(1){
7
uart_puts("Hello world\r\n");
8
}
9
}
Solange das nicht einwandfrei funktioniert, brauchst du I2C noch nicht
mit dazu nehmen.
> Wenn ich den µC resette, empfange ich drei Zeichen, das> wars leider auch schon. Diese sind auch nicht das erwartete, sondern> eher kryptisch.
"kryptische" zeichen sind meistens ein sicheres Indiz, dass das hier
1
#ifndef F_CPU
2
#define F_CPU 8000000UL
3
#endif
nicht der Realität entspricht. Dein µC läuft nicht mit 8Mhz.
Den Tipp mit dem reduzieren des Codes habe ich umgesetzt, kam jetzt
durchgehend was bei mir anb, leider immernoch Schrott.
Was die Frequenz angeht, war ich mir sehr sicher, dass Frequenz und
Baudrate stimmen, da es ja beim Slave auch funktionier hat. Um sicher zu
gehen, habe ich den Code vom Slave nochmal raufgespielt. Dieser geht
plötzlich auch nicht mehr.
Da ich noch gerne Anfängerfehler mache, hier der Ablauf, wie ich
Übersetzte, vielleciht ist da ja der Wurm drin:
Programm erstelle ich mit AVRStudio6 und kompiliere es. Zum übertragen
nutze ich das myAVR Progtool. Hexfile ausfählen, EEprom in Ruhe lassen,
brennen. Funktioniert auch immer ohne Fehlermeldung. Bei den Fusebist
deaktiviere ich "divide clock by 8" um auf 8MHz zu kommen.
Zur Taktfrequent: Auf einen externen Oszillator muss ich verzichten, da
der Controller in ein Bluetoothmodul (BCA8-BTM) eingebettet ist.
Nils K. schrieb:> Den Tipp mit dem reduzieren des Codes habe ich umgesetzt, kam jetzt> durchgehend was bei mir anb, leider immernoch Schrott.> Was die Frequenz angeht, war ich mir sehr sicher, dass Frequenz und> Baudrate stimmen, da es ja beim Slave auch funktionier hat. Um sicher zu> gehen, habe ich den Code vom Slave nochmal raufgespielt. Dieser geht> plötzlich auch nicht mehr.> Da ich noch gerne Anfängerfehler mache, hier der Ablauf, wie ich> Übersetzte, vielleciht ist da ja der Wurm drin:>> Programm erstelle ich mit AVRStudio6 und kompiliere es. Zum übertragen> nutze ich das myAVR Progtool. Hexfile ausfählen, EEprom in Ruhe lassen,> brennen. Funktioniert auch immer ohne Fehlermeldung. Bei den Fusebist> deaktiviere ich "divide clock by 8" um auf 8MHz zu kommen.> Zur Taktfrequent: Auf einen externen Oszillator muss ich verzichten, da> der Controller in ein Bluetoothmodul (BCA8-BTM) eingebettet ist.
Also läuft dein Controller mit dem internen RC Taktgeber? Das geht nicht
gut, du brauchst einen Quarz!
Der Port für die externe Clock (XTAl1/ PB6) ist leider durch eine LED
belegt. Jetzt funktionieren sowohl das SLAVE als auch das "Hello World"
Programm. Scheint tatsächlich an der Temperatur gelegen zu haben. Beim
Master Programm wird die UART-Initmeldung "I2C-Test" wiedergegeben. Das
wars dann aber auch. Im Moment habe ich noch keinen I2C Verbindung
hergestellt, müsste also eine Fehlermeldung erscheinen.
Zum I2C bzw TWI habe ich noch eine Frage:
wenn ich einen Master und einen Slave habe (mehr brauch ich nicht), sind
dann die Pullupwiderstände nötig?
Tatsächlich funktioniert es gerade mit 1MHz Takt und einer Baudrate von
4800, bei 8MHz und höheren baud jedoch nicht. Ist ja auch nur für
Testzwecke, TWI ist weitaus störender gerade :)
// check value of TWI Status Register. Mask prescaler bits
13
twst=TW_STATUS&0xF8;
14
if(twst!=TW_MT_DATA_ACK)return1;
15
return0;
16
17
}/* i2c_write */
Mir ist nicht ganz klar, was dieser Ausdruck bewirkt:
"i2c_start(SLAVE_ADRESSE+I2C_WRITE)"
SlAVE_ADRESSE erklärt sich selbst, aber warum eine Funktion addieren?
Nils K. schrieb:> SlAVE_ADRESSE erklärt sich selbst, aber warum eine Funktion addieren?
Weil in "C" auch GROSS-klein-Schreibung beachtet wird.
Es gibt die Funktion i2c_write und die Konstante I2C_WRITE. Das ist ein
wenig ungeschickt vom Programmierer, aber legal.
Das Problem liegt meist darin das der Bus hängt. Ich habe in meine
Routinen deswegen einen Abbruch nach zeit eingebaut und probiere es
später nochmal.
Einfach bei den while noch eine zeit mit aufnehmen.
Addieren zur Slave Adresse, weil damit lesen oder schreiben ausgewählt
wird.
Lies dich nochmal in das Thema ein bzw. den Code.
Gruß,
Jörg