mindestens 3 UARTs

Gast #13015
Lesenswert?

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
Gast #13019
Lesenswert?

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!!!!
Gast #13020
Lesenswert?

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
Gast #13021
Lesenswert?

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
Gast #13022
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren