Hallo,
ich bin in dieser Sache auch gerade am Experimentieren, leider bisher ohne Erfolg.
Ich werden den Thread mit Spannung verfolgen, und sofort Meldung geben, wenn sich bei mir was tut.
Hallo,
aufbauend auf meinem Thread der sich mit µC mit mehr als 50 Ports beschäftigt bin ich nun dazu übergegangen eine Lösung zu suchen, wie ich mehrere µController (genauer mega32) miteinander Komunizieren lassen kann.
Das Bussystem ist mir dabei fast egal, wobei ich I2C favorisiere. Leider ist es mit meinen Programmierkenntnissen nicht so gut bestellt wie bei der Mechanik. Daher brauch ich jetzt eure Hilfe:
Ich Suche einen möglichst einfachen Code (so einfach, dass auch ich ihn verstehe) mit dem ich oben genannte Komunikation realisieren kann.
Das TWI Tutorial im avr-gcc RN Wissen hat mir leider nicht wirklich weiter geholfen, den ich bekomm es nicht hin, bzw. ich versteh es nicht (wie es funktionieren sollte schon, nur den Code nicht!). Ich bekomm beim I2C Slave immer Fehler beim Compilieren und weis nicht was die Lösung ist.
Wenn also jemand eine einfachere Lösung die auch funktioniert wäre ich sehr dankbar. Auch Erfahrungen mit anderen Bussystemen die Funktionieren sind hilfreich.
Verständlicherweise helfen mir Vorschläge wie: "Einfach über I2C oder über CAN verbinden" nicht weiter, da es bei der konkreten Umsetzung in C-Code hapert.
ich hoffe inständig auf eure Hilfe weil davon meine weiteren Projekte abhängen
Grüße
Hanno
Hallo,
ich bin in dieser Sache auch gerade am Experimentieren, leider bisher ohne Erfolg.
Ich werden den Thread mit Spannung verfolgen, und sofort Meldung geben, wenn sich bei mir was tut.
Grüsse Nechegris
Das Leben ist schön, man muss sich nur daran beteiligen!
Hi,
am allereinfachsten ist's eigentlich über die UART.
Hardwaremässig muss man nur TxD von Prozessor A mit RxD von Prozessor B verbinden und umgekehrt.
Softwaremässig ist das auch recht einfach zu realisieren. Wenn interesse besteht, bastel ich mal einen Beispielcode zusammen. Allerdings steht auch im RN Wissen einiges an Code dazu drin: http://www.rn-wissen.de/index.php/UART_mit_avr-gcc
Gruß,
askazo
TWI-Master Routinen kann ich hier gerne posten. Bei den Slave wirds dann aber etwas schwieriger. Es kommt auf deine Anwendung an, wie der Code empfangen/zwischengespeichert/gesendet wird. Außerdem kommt es darauf an, ob der Master nur senden, oder auch empfangen können soll.
Wenn du deine Anwendung beschreibst, könnt ich dir sicherlich bei der Erstellung eines Protokolls helfen, was geeignet ist.
Hier schonmal der TWI-Master code
Auf einem ATmega32 hab ich den Code noch nicht getestet, allerdings sollte das keine Probleme machen.Code:Header-Datei: #include <avr/io.h> #define READ 1 #define WRITE 0 #define TWI_READY (TWCR & (1<<TWINT)) void TWIInit(void); void TWIStart(uint8_t addr, uint8_t RW); void TWIStop(void); //Byte senden uint8_t TWIWrite(uint8_t data ); //Byte empfangen uint8_t TWIReadAck(void); //letztes zu empfangendes Byte empfangen uint8_t TWIReadNack(void); .c Datei: void TWIInit(void){ PORTC |= 0x03; //PULLUP Widerstaende (für ATmega32 geeignet) TWBR = 0xFF; } void TWIStart(uint8_t addr, uint8_t RW){ uint8_t temp = 1; while(temp == 1){ TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //START while(!TWI_READY); if(TWSR == 0x00) {TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);} if(TWSR != 0x08 && TWSR != 0x10) {continue;} TWDR = addr + RW;//LCD_BOARD_ADR; //send ADR+W TWCR = (1<<TWINT) | (1<<TWEN); while(!TWI_READY); if(TWSR == 0x00) {TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);} if(TWSR != 0x18 && TWSR != 0x40) {continue;} temp = 0; } } void TWIStop(void){ TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); while(TWCR & (1<<TWSTO)); } //Byte senden uint8_t TWIWrite(uint8_t data ){ TWDR = data; TWCR = (1<<TWINT) | (1<<TWEN); while(!TWI_READY); if(TWSR != 0x28){return 1;} return 0; } //Byte empfangen uint8_t TWIReadAck(void){ TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN); while(!TWI_READY); return TWDR; } //letztes zu empfangendes Byte empfangen uint8_t TWIReadNack(void){ TWCR = (1<<TWINT) | (1<<TWEN); while(!TWI_READY); return TWDR; }
Zuerst muss eine Start-Anweisung ausgeführt werden, die dem Slave sagt, was zutun ist. READ: Master liest, WRITE: Master schreibt.
Wenn Master schreibt, dann musst du die TWIWrite Funktion verwenden, um ein Byte zu senden. Wenn er liest, dann musst du die TWIReadAck Funktion verwenden, um Bytes zu lesen (außer das letzte Byte), für das letzte Byte verwendest du die TWIReadNack Funktion.
Am Ende kommt eine stop-Anweisung.
Wenn du einfach nur etwas an den Slave senden möchtest und nichts zurück erwartest, würde ich dir aber eher den SPI-Bus empfehlen, er ist deutlich schneller und für diesen Zweck am einfachsten zu programmieren.
Gruß, Yaro
Hallo ihr beiden,
zuerst einmal die Hardwareseite: Da der Bus ja in beide Richtungen geht, kann niemand die Leitung auf "High" ziehen, ohne zu riskieren dass sein Ausgang abraucht weil der Gegenüber gerade beschlossen hat, "Low" ausgeben zu wollen. Daher werden die beiden Leitungen SDA (Daten) und SCL (Takt) über einen Pullup von ~10kOhm (je nach Anwendung/Geschwindigkeit/Leitungslänge) auf "High" gezogen.
Die Kommunikationspartner ziehen die Leitung also nur noch auf "Low", der "High"-Pegel stellt sich von alleine wieder ein.
Dann die Softwareseite: Ich denke am sinnvollsten wäre es, einmal das Kapitel zum TWI im Datenblatt durchzulesen, evtl. noch die I2C-Spezifikation (auch wenn das im Datenblatt eigentlich schon ausreichend abgehandelt wird).
Informationen (und die aktuelle Bus-Spezifikation) findet ihr unter http://www.i2c-bus.org/
mfG
Markus
Mit UART ist es nur mit ziemlichen Krampf möglich mehrere Prozessoren
zu verbinden. Da muss man dann dafür sorgen (Protokoll) das immer
nur der eine Antwortet da adressiert war. Also letztendlich schwieriger
als I²C. Dafür klappt I²C eher nur über kurze Leitungswege.
RS 485 kann gut 1200 m, CAN in etwa auch bei 485 muß man aber
auch das Protokoll selber schreiben (entwickeln) und braucht bei
voll Dublex 4 Daten Leitrungen. Beim CAN - Bus gibt es ein Protokoll,
das ist aber extrem aufwändig und braucht da eher spezielle Harware
und ODER nen AVR mit intregierten CAN Interface.....
Bei kurzen Verbindungen ist also I²C die einfachste und beste Methode,
leider kann ich kein c und in Bascom sieht das recht einfach aus. Ich
habe vor ca 20 Jahren einmal I²C auf einem PIC in Assemler selber
geschrieben, sehr schwer war das nicht. Die Start,senden, empfangen,
Stopp Signale sind ja sehr einfach und gut beschrieben.
Aber ich vermute stark das sich auch für C Bibliotheken finden lassen
in denen I²C schon wie in Bascom "vorgekaut" enthalten sind.
Gruß Richard
@yaro das sieht zumindest für mich schon mal verständlicher aus als der Code im Wiki.
@markusj die Spezifikation von einem I2C Bus ist nicht meine Sorge, ich weis genau wie der funktioniert und wann wo welche Leitung auf High für wie lange gelegt werden muss. Mein Problem ist, dass ich dieses Wissen nicht in einen C-Code verwandeln kann.
@Richard deswegen auf I2C und kein UART bei meinem ersten Versuch. Ich versuch gerade entsprechende Programme bzw. Bibliotheken zu finden aber komm nicht weiter.
Im Prinzip such ich ein Programm das beim Master einen Tastendruck einliest und beim Slave ne LED angehen lässt und umgekehrt. Anhand so eines Beispielprogramms könnte ich vermutlich alle anderen Funktionen extrapolieren. Ich fände es nur etwas zu dreist jemanden um so etwas zu bitten.
Versuche es einmal bei http://openpdf.com/ebook/gcc-i2c-avr-pdf.html
Der 4..5...Eintrag?
Gruß Richard
So schwer ist das auch nicht, sich ein passendes UART-Protokoll zu basteln. (im einfachsten Fall 1.Byte = Adresse, 2.Byte = Daten). Das Senden und Empfangen geht über eine simple State Machine.
Aber ich merke schon, gegen die I2C-Fraktion habe ich keine Chance
Gruß,
askazo
Stimmt, aber für I²C gibt es deutlich mehr Hardware wie Sensoren,Zitat von askazo
Uhren, eeproms.........dafür jedes mal eigne Hardware und ein eigenes
Protokoll zurecht fummeln ist echt mühsam.
Gruß Richard
Lesezeichen