Hi, ich benötige mindestens 3 UARTs (also normale serielle Schnittstellen) an meinem AVR (4433). Ich möchte, wenn's irgendwie geht, nicht einen "großen" AVR mit 2 UARTs verwenden. Gibt es da nicht auch eine Lösung per I2C? Danke! Sebastian
Hi Markus, also 9600 Baud wären super! Folgende Geräte müssen ran: - Handy (dient als Modem) - GPS-Gerät - PC - anderer AVR (eventuell) Hast Du Ideen? Danke! Sebastian
Hm, also der 4433 hat ja einen Hardware UART. Bei Atmel gibt es eine AppNote für einen Software UART. Vielleicht kann man das ja irgendwie verdoppeln
Hallo dein GPS Gerät sendet ja vermutlich nur jede sek. mal kurz - du könntest versuchen mit Transistoren eine Schaltung aufzubauen, die zwischen dem einem Gerät (gps) und dem anderen (PC) hin und herschalten kann - die Schaltung wird einfach durch einen Portpin gesteuert - dazu musst du natürlich wissen wann wer was sendet - beim GPS kannst du ja versuchen die Zeit zu messen oder aber du hängst die TX Leitung vom GPS an einen externen Interrupt - vielleicht geht das schnell genug. 2. Mgl.: du verbindest den 2. AVR via SPI oder Parallel mit dem anderem und nutzt einfach dessen UART 3. Mgl.: SoftUart Viel Erfolg!!!!
Hallo Christian, danke für die Antwort! :-) Wenn ich zwei AVRs per SPI verbinde, wie muß ich das dann (in Assmbler) programmieren? Und was heißt parallel? SoftUART klingt sehr interessant! Wie genau soll das funktionieren? Wie lässt sich das (in Assembler) programmieren? Da habe ich aber keine Interrupts, oder? Danke! :-) Sebastian
Hallo, tut mir leid aber ich habe fast keine Ahnung von Assembler für AVR - such doch mal im Netz da wirst du mit Sicherhiet fündig!!! Mit Parallel hab' ich gemeint, dass du ähnlich wie bei einem Display beispielsweise jeweils einen ganzne Port deiner AVR's miteinander verbindest und dann noch ein paar pins zur Steuerung einsetzt (senden/empfnagen/aktiv......) Ich denke schon dass du einen Empfangsinterupt verwenden kannst - nimm halt einen externen interrupt - wenn der hochgeht dann spring schnell in deine Empfangsroutine. Beim senden gibts natürlich keinen interrupt..... mfg Christian
Hallo Sebastian! Ich bin gerade dabei, 2 AVR (AT90S8515)per SPI miteinander kommunizieren zu lassen. Wenn man es einmal gebacken gekriegt hat, ist es gar nicht so schwer... :) Bei meiner Methode läuft das im Polling, da ich (noch) keine Zeitkritischen Abläufe habe und zwischendurch nix anderes machen muß. Eleganter wäre es sicher per Interrupt... So funktioniert es programmtechnisch (bei mir): 1. Ein AVR muß als Master koviguriert werden, der andere als Slave. das geschieht über das SPCR (SPI-Control-Register). In diesem register stellt man auch noch ne ganze Menge anderer Sachen ein, wie: Taktfrequenz, Interrupt en-/dis-able, Phasenlage, etc. 2. Pro Durchgang wird ein Byte zwischen Master und Slave "getauscht". Du schreibst also ein Byte in das SPDR (SPI-Data-Register) des Slaves. Dieser Wartet dann einfach. (SPI muß natürlich enabled sein, das kann mit Schritt 1 zusammen machen, da gleiches Control-Register). Theoretisch kannst Du während des Wartens auch was anderes machen, kommt bei mir aber nicht vor. Achso, wichtig ist noch, daß der Eingang /SS am Slave-µC auf low gehalten wird, sonst is nix mit SPI... 3. Beim Master wird ebenfalls das SPI enabled (geschieht bei mir mit Schritt 1 zusammen) und anschließend in das SPDR-Register das zu übertragende Byte geschrieben. das schreiben des zu übertragenden Bytes startet automatisch die Hardware SPI. Nun kann man auch hier entweder abwarten (Schleife) oder was anderes machen. 4. Die Hardware überträgt jetzt im Hintergrund mit der in Schritt 1 eingestellten Geschwindigkeit. Nachdem die Übertragung zu Ende ist, wird entweder ein Interrupt aufgerufen (wenn enabled) oder man kann das Status-Bit im SPSR (Status-Register) abrufen um zu prüfen, ob die Übertragung fertig ist. Letztere Methode benutze ich beim Warten, um zu prüfen, ob die Übertragung fertig ist. 5. Wenn alles erledigt ist, hast Du im Master SPDR (Data-Register)das Byte, welches vorher im Slave war, und im Slave jenes aus dem Master. Die Bytes wurden also in einem Rutsch zwischen master und Slave getauscht. Hier ist meine Subroutine des Slaves. Wird sie aufgerufen, wartet sie eine gewisse Zeit lang darauf, daß der Master sendet. Sendet er nicht bis die Warteschleife abgelaufen ist, wird zu "Carderror" verzweigt. In dem Register "tosend" muß beim Aufrufen das Byte stehen, welches der Master bekommen soll. Nach der Übertragung und Beendigung der Subroutine steht im Register "recvd" das Byte, welches vom Master kommt. Klingt alles ganz kompliziert, ist aber ganz einfach: ; ************************* SPI Slave Routine ************************ spislave: ldi temp, 0b01001001 ; SPI enable, Interrupt disable, Slave, Clock= f/16 out SPCR, temp ; Init-werte ins SPI-Control-Register out SPDR, tosend ; das Byte für den Master bereit stellen ldi r17, $FF waitSPI1: ; **** warten, bis die Daten übertragen wurden dec r17 ; Zähler einen erniedrigen breq carderror ; wenn zulange gedauert hat, dann fehler in temp, SPSR ; Hole werte vom SPI Status Register sbrs temp, 7 ; Wenn SPIF gesetzt (=Übertragung Ende), dann... rjmp waitSPI1 ; ...verlasse schleife, sonst nochmal in recvd, SPDR ; Byte vom SPI in "recvd" speichern ldi temp, 0b00001001 ; SPI disable out SPCR, temp ; -> ret ; ********** (sorry, daß die Formatierung beim Posten verloren gehen... ich hoffe, man kann es lesen) Hardware-technisch habe ich hierbei die SPI-Pins "Mosi(PB5)"/"Miso(PB6)"/"SCK(PB7)" beider µCs 1zu1 miteinander verbunden, Pin "/SS(PB4)" liegt auf Masse (wichtig!). Der Code des Masters sieht genauso aus, nur ist hier die erste Zeile etwas anders, damit das Ding als Master arbeitet. Außerdem entfällt die Verzweigung zur Fehlerroutine, wenns zu lange dauert. ldi temp, 0b01011001 ; SPI enable, Interrupt disable, Master, Clock= f/16 So, ich hoffe, ich konnte die SPI-Geschichte etwas erklären. Keine Haftung/Garantie für Richtigkeit und Vollständigkeit ;) ciao, Andi
Hi Andreas, danke für die super Erklärung! :-) Ich werde es in den nächsten Tagen mal nachbauen. Sehe ich das mit SoftUART richtig: Ich definiere einfach zwei Ports als TX und RX und bastle mir dann mein Byte zusammen? Danke! :-) Sebastian
Bei Maxim gibt es UART-Bausteine die an die SPI Schnittstelle angeschlossen werden können. Ich denke das würde für dein Vorhaben ideal sein. Infos unter http://www.maxim-ic.com/quick_view2.cfm?qv_pk=1731 lG XCyber
Hi XCyber, danke für den Tip, klingt super! Die Frage ist nur, wie man die SPI-Schnittstelle ansteuert. Was ist eigentlich der Unterschied zwischen SPI und UART? Mein C-Control habe ich immer per serielle Schnittstelle programmiert, deswegen ist SPI für mich neu. Danke! :-) Sebastian
Wie du mit der SPI-Schnittstelle umgehst steht recht genau in den Atmel Datenblättern der einzelenen Prozessoren. lG XCyber
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.