www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zwei 90S2313 verbinden und definierte Daten lesen


Autor: Mo. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ein Problem, dass mir schon eine Woche schlaflose Nächte
bereitet und hoffe nun hier auf ein paar aufmunternde Worte und etwas
Hilfe.

a) Ich treffe die Annahme, dass ein AT90S2313 (getaktet mit 7,3728MHz)
jeweils einmal eine der folgenden Daten über TxD ausgibt. Dabei ist die
Ausgabe als Reaktion auf einen Tastendruck zu verstehen. Dabei handelt
es sich um:

0xC1 -> Ausgabe für Taste 1
0xC2 -> Ausgabe für Taste 2
0xC4 -> u.s.w.
0xC8 ->
0xD0 ->
0xE0 -> Ausgabe für Taste 6

(Anmerkung: 9600Bd, 8 Daten Bits, 1 Stop Bit, no Parity, LSB first)

b) Der in a) genannte Sachverhalt lässt sich leider nicht
beeinflussen/ändern

c) Ein zweiter AT90S2313 (gleiche Taktung) soll mit RxD direkt an den
TxD aus a) angeschlossen werden.

Was nun passieren soll, kann ich zunächst nur mal in Worte fassen. Er
soll in einer Routine prüfen, ob etwas an RxD empfangen wird, wenn ja -
ob es eins der o.g. 6 Stück ist - wenn ja, dann soll er an einem Pin ein
Relais oder einen Schaltkontakt herstellen und dann wieder prüfen, ob
etwas empfangen wird.

Also werden doch auch 6 I/O Pins als Ausgänge benötigt.

Ich habe absolut keine Idee, wie ich das in C umsetzen kann. Hab auch
schon das super WIKI-Tut durch, aber da ist nur das Senden mit dem UART
genauer beschrieben.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
switch (received_byte){
case 0xC1: tu_irgend_was:break;
.
.
}

Autor: Mo. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau das tu_irgend_was würde mich genauer interessieren! Aber so
abzufragen ist ne gute Idee!

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C scheint mir dafür ein ziemlicher Overkill zu sein. Mit Assembler hat
man sowas in vielleicht 50 Zeilen schnell programmiert.

In C passiert im Prinzip dasselbe:
UCR richtig setzen, USR permanent abfragen ob es was neues gibt (RXCIE
(RX Complete Interrupt Enable)), wenn nein, weiter warten, ansonsten
UART Data Register lesen und eine case - Anweisung durchlaufen, in der
die Ausgangspins gesetzt werden.

Wo ist jetzt das Problem? Was hast Du denn bis jetzt programmiert? Was
klappt nicht? Was hast Du bisher getan, um die Ursache zu finden und
was hast Du herausgefunden?
Hast Du schonmal in ein "normales" C-Buch geschaut? Ich denke, das
wird im Tutorial ebenso vorausgesetzt wie ein bißchen
Programmiererfahrung...

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hä??
tu_irgend_was könnte z.B. sein:
PORTB=0x01;

Wird unter
http://www.mikrocontroller.net/wiki/AVR-GCC-Tutori...

erklärt.

Autor: Mo. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die ersten Antworten. Ich habe mal einen Wntwurf
gemacht. Ist der Ansatz so ok? Also wo ich noch mal ran muss ist die
Taktfrequenz (ist nicht 4000000) und die Aktion, die kommt, wenn Daten
empfangen werden. -> Es soll ja nur ein Pin gesetzt werden!

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sieht doch schon nicht schlecht aus.
Jetzt kannst Du z.B. schreiben:

data_received = USART_RECEIEVE();
    if(data_received == 0xC1) PORTB = 0b00000001;
    if(data_received == 0xC2) PORTB = 0b00000010;
    if(data_received == 0xC4) PORTB = 0b00000100;
    if(data_received == 0xC8) PORTB = 0b00001000;
    if(data_received == 0xD0) PORTB = 0b00010000;
    if(data_received == 0xE0) PORTB = 0b00100000;

und damit Pin 1 bis Pin6 an Port B schalten...

Autor: Mo. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke! So macht es mal Spaß weiterzumachen ;)

Habe es jetzt so ergänzt. Wie lange soll er nach dem "Pin-freigeben"
denn warten, damit ein Schaltkontakt überhaupt zustande kommen kann?

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um das zu entscheiden, müßtest Du mal sagen, was genau passieren soll.

- soll der Pin dauerhaft eingeschaltet bleiben, auch wenn ein neues
Zeichen empfangen wurde?
- Wie oder wann soll wieder  abgeschaltet werden?

So wie es jetzt ist, bleibt PortB in dem Zustand, in den er zuletzt
gesetzt wurde.

Wenn der Relais-Kontakt einfach nur kurz klappern soll müßtest du eine
Wartefunktion aufrufen und danach wieder eine 0 auf den Port
schreiben.

Relais erzeugen übrigens gerne Störungen, die den Controller abstürzen
lassen. Über die Forumssuche findest Du Infos, wie das zu vemeiden ist.

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe erst jetzt Deinen Code gesehen... Warte doch erstmal 500msec -
verkürzen kann man die Zeit immer noch. Oder wie sehen Deine
Anforderungen aus?

Autor: Mo. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Johannes,

habe eine Warteschleife eingebaut WAIT(); aber ich weiß nicht, wie
lange die reale Wartezeit ist. Das muss ich testen. Danke für den Tipp
mit dem Relais. Ist es besser eine Transistor-Schaltung zu nehmen. Muss
im Prinzip insgesamt 6 Schalter/Taster bedienen können. Wenn ich das
über einen Transistor laufen lasse, kann ich mir Entprellen (oder wie
das heißt) sparen?

Neuer Code im Anhang ;)

Autor: josef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UDR ist ein Register, dass du in der for-Schleife direkt abfragen
kannst. Das solltest du auch mal löschen. Du solltes dieses auch auf
ungleich 0 abfragen.
Würde aber besser eine Bit-Variable bei jedem UART-Interrupt setzen und
nach Auswertung des empfangenen Zeichens diese Variable wieder löschen.
So kannst du auch die 0 auswerten. Geht ntürlich auch über das UART-RI
Bit.


SG Josef

Autor: josef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Johannes: Das löschen des PORTB bringt nichts, da niemand das
data_received Byte löscht.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

es ist eben die Frage ob deine Ausgaenge galvanisch getrennt sein
muessen, wenn nicht reichen Transistoren oder Mosfets aus.

Vielleicht reichen aber auch Optocoupler mit Open Collector.

Mfg
Dirk

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Josef: Hm, bei Assembler wird das RXC - BIT doch automatisch beim
Abholen des Zeichens gelöscht - bei C nicht? Wie war das doch
gleich...
Ich sehe gerade, ein UCSRA gibt es beim 2313 ebensowenig wie einen
USART. Vielleicht einfach nochmal ins Wiki gucken...
Ich würde das USR auf RXC prüfen. Wenn was gesetzt ist, UDR auslesen
und auswerten.

Transistoren gehen je nach Spannung ohne Probleme - bei AC klappt das
nicht. Du hast noch nicht geschrieben, was Du überhaubt machen willst.

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In ASM sieht das dann so aus:

loop:   in temp, USR
        sbrs temp, RXC  ;Daten empfangen -> Sprung nach loop
überspringen
        rjmp loop
        in temp, UDR
        rcall serout    ; echo (das Zeichen in Temp ausgeben)

anschließend in Abhängigkeit von temp was Tolles anstellen.

Autor: Mo. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Dirk: Ich denke nicht, dass sie galvanisch getrennt sein müssen. Es
erfolgt ja lediglich nur eine Ausgabe gleichzeitig.

@ Josef: received_data wird doch immer "neu" gefüllt, d.h. man müsste
es eigentlich nicht löschen, oder? Falls doch, würde dann ein
received_data = ""; reichen?

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

naja vielleicht reicht dir ja der Logikpegel (5V/20mA)

ich wuerde die Daten anders loeschen ....

#define clear      0x00

received_data = clear;

Autor: Mo. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Johannes: Du hast Recht. USART kann ich vergessen. Leider finde ich im
Wiki nichts mehr darüber. Das einzige, was ich noch gemacht habe, dass
ich am Ende received_data = CLEAR; gesetzt habe (CLEAR ist zuvor mit
0x00 definiert).

Tja und nun stecke ich richtig fest!!!

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

die richtigen Registernamen solltest du im Datasheet finden.
Suchbegriff: UART .... bei den neueren AVR's heisst es USART.

Mfg
Dirk

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du sowieso wartest, bis ein neues Zeichen da ist, brauchst Du IIRC
nichts löschen.
USART gibt's nicht, dafür den UART. Genau dieser wird auch im Wiki
beschrieben, und mehr brauchst Du ja auch nicht.
Wo ist denn jetzt jenau das Problem? Du brauchst im Prinzip nur noch
das, was  ich Dir beschrieben und in Assembler gepostet habe in C
umzusetzen. Wenn ich es richig sehe, mußt Du dazu lediglich UCSRA durch
USR ersetzen.
Die UART - Initialisierung wirst Du ja auch wohl irgendwo finden.
Am besten nicht nur irgendwoher kopieren, sondern auch mal ins
Datenblatt gucken und versuchen, etwas zu verstehen.
"Galvanisch getrennt" bedeutet übrigens, daß der Stromkreis vom
Controller und der von dem, was Du schalten willst, keinerlei
elektrische Verbindung haben. Je nachdem, was Du ansteuern willst ist
das unabdingbar.

Gute Nacht

Johannes

Autor: Mo. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Dirk & Johannes,

werde morgen weitermachen und dann von meinen Ergebnissen berichten.

Gute Nacht,
Moritz

Autor: Mo. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So,

habe es noch einmal abgeändert. Die UART-Initialisierung war wohl
korrekt, hatte nur USARD geschrieben und dann fälschlicherweise mit dem
"Begriff" weitergesucht ;)

Sollte es jetzt so gehen, oder wo ist noch Verbesserungsbedarf?

@ Johannes: Leider kann ich Deinen Assembler-Code nicht richtig
interpretieren. Ist schon in C relativ haarig für mich.

Zur Schaltung: Geschaltet werden sollen (zur Zeit noch SMD) Taster, die
ich gänzlich ersetzen möchte. Dabei läuft die externe Schaltung mit
3,9V. D.h. es ist besser, wenn ich die beiden Schaltkreise, die an sich
nichts miteinander zu tun haben, trenne. Ich denke, dass hier der von
Dirk empfohlene Optokoppler (hab mich auf elektronik-kompendium
informiert) eine gute Wahl ist ;)

Autor: Johannes Raschke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bis auf die Tippfehler (|= und UARD_RECEIVE();) sieht das nach meinem
Verständnis gut aus. Compiliere das Programm doch mal und lade es in
Deinem Atmel oder Simulator!

Johannes

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

im include hast Du noch arv/io.h statt avr/io.h stehen, ist mir spontan
aufgefallen.

In der Wait-Schleife: time und x sind unsigned char, haben also einen
max. Wert von 256. WAIT(500) ist also nicht möglich/macht nicht das,
was Du erreichen willst.

Bei 4Mhz Takt braucht ein Befehl 250ns, damit kannst Du abschätzen, wie
lang der Ausgang geschaltet bleibt->sehr kurz! Ohne zu wissen, wieviele
asm-Befehle eine For-Schleife braucht (4?) würd ich schätzen, dass
Deine Wartezeit im us-Bereich liegt. Ob das reicht, musst Du selber
wissen.

Was passiert, wenn jd. einen Taster an a) dauerhaft drückt? Sendet der
uC1 dann immer wieder z. B. 0xC1...0xC1...0xC1 Oder nur 1x? Im ersteren
Fall macht Dein Programm aus einem Dauerhaft gedrückten Taster ein
AN........AUS.AN..........AUS.AN..........AUS.AN.......usw.

Ob das, was ich hier erzähle, in Deiner Schaltung relevant ist, musst
Du selber wissen.

Ich würds mal ausprobieren.

Gruß,
Sebastian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.