Hallo,
an einem Atmega8 sind 10 Sensoren und 10 Aktoren angeschlossen.
(Sensoren und Aktoren sind binär)
Der 1.Atmega8 soll die Signale der Sensoren abfragen und über 2
Leitungen an einen 2.Atmega8 weitergeben dieser soll dann die Signale an
eine SPS weitergeben und die Ausgangssignale der SPS aufnehmen und an
den 1.Atmega8 weitergeben der diese zu den Aktoren weitergibt.
Gibt es evtl Code Beispiele zu einer solchen bidirektionalen Übertragung
zwischen den 2 Atmega 8 find nur Beispiele zur unidirektionalen
Übertragung.
Wäre Dankbar für Beispiele oder Tips dazu danke
@ Michael Dietz (Firma na) (michaeld)
>an einem Atmega8 sind 10 Sensoren und 10 Aktoren angeschlossen.>(Sensoren und Aktoren sind binär)
Schön, aber wie schnell ist das Ganze?
>Der 1.Atmega8 soll die Signale der Sensoren abfragen und über 2>Leitungen an einen 2.Atmega8 weitergeben dieser soll dann die Signale an>eine SPS weitergeben und die Ausgangssignale der SPS aufnehmen und an>den 1.Atmega8 weitergeben der diese zu den Aktoren weitergibt.
Und wozu zwei Prozessoren? Denkst du, ein AVR ist dem nicht gewachsen?
>Gibt es evtl Code Beispiele zu einer solchen bidirektionalen Übertragung>zwischen den 2 Atmega 8 find nur Beispiele zur unidirektionalen>Übertragung.
UART, ist bidirektional.
>Wäre Dankbar für Beispiele oder Tips dazu danke
Nimm EINENAVR, der reicht wahrscheinlich dicke und die Programierung
wird einfacher.
MFG
Falk
>Schön, aber wie schnell ist das Ganze?
Von der Gewschwindigkeit her müsste man ca 2kHz erreichen ohne
Protokoll.
>Und wozu zwei Prozessoren? Denkst du, ein AVR ist dem nicht gewachsen?
zwischen den beiden Prozessoren muss eine Strecke von ca 2m überbrückt
werden auf diesen 2m stehen nur 2 Leitungen zur Verfügung.
der erste Prozessor hängt an den Sensoren und Aktoren(20 an der Zahl).
Dann kommen die 2m mit nur 2 Leitungen.
Und dann der zweite Prozessor der wieder jedes Signal einzeln pro Pin an
die SPS ausgibt.
>UART, ist bidirektional.
OK dann werde ich da mal nach ein paar Codebeispielen suchen.
Da machen die 2m zwischen den beiden Prozessoren kein Problem?
>Nimm EINEN AVR, der reicht wahrscheinlich dicke und die Programierung
wird einfacher.
Naja das wird ein wenig Problemtisch da ja noch 2m dazwischen liegen
oder hab ich da etwas falsch verstanden?
Danke für die schnelle Antwort freue mich auf weitere Beiträge zum Thema
.
Hast du nur zwei Leitungen, oder zwei Datenleitungen und Masse? Bei
ersterem wird USART etwas komplizierter, das benötigt normalerweise je
eine Leitung pro Datenrichtung. One-Wire wäre da vielleicht was...
>Hast du nur zwei Leitungen, oder zwei Datenleitungen und Masse? Bei>ersterem wird USART etwas komplizierter, das benötigt normalerweise je>eine Leitung pro Datenrichtung. One-Wire wäre da vielleicht was...
eine Masse habe ich noch..
Hat jemand schonmal eine Datenübertragung per UART hinbekommen??
Wenn ja hat er noch den Queltext evtl mit Kommentaren??
blicke da noch nicht so ganz durch..Danke
Ja, eine Datenuebertragung per UART ist Standard. Dazu ist das UART da.
Mit passenden Treibern erreicht man eine Meile. Fuer 2m und nur 2
Stationen ist RS232 passend. Das waeren dann MAX232 treiber.
@ Michael Dietz (Firma na) (michaeld)
>Von der Gewschwindigkeit her müsste man ca 2kHz erreichen ohne>Protokoll.
Was meinst du mit 2 kHz? Sollen 2000 mal pro Sekunde alle Kanäle
übertragen werden (-> 40.000 Bit/s) oder sollen pro Sekunde 2000 Bits
übertragen werden (-> 100 mal alle Sensoren / s übertragen). Beides ist
keine grosse Sache für so einen AVR.
>Und dann der zweite Prozessor der wieder jedes Signal einzeln pro Pin an>die SPS ausgibt.
Ohje. Naja, SPS halt. Hat die keinen seriellen Eingang?
>OK dann werde ich da mal nach ein paar Codebeispielen suchen.>Da machen die 2m zwischen den beiden Prozessoren kein Problem?
Nöö.
>Naja das wird ein wenig Problemtisch da ja noch 2m dazwischen liegen>oder hab ich da etwas falsch verstanden?
Wenn das wirklich nur mit 2 Datenleitungen + Masse verbunden werden kann
brauchst du zwei AVRs.
MFG
Falk
>Was meinst du mit 2 kHz? Sollen 2000 mal pro Sekunde alle Kanäle>übertragen werden (-> 40.000 Bit/s) oder sollen pro Sekunde 2000 Bits>übertragen werden (-> 100 mal alle Sensoren / s übertragen). Beides ist>keine grosse Sache für so einen AVR.
genau es sollen alle Sensoren bzw. Aktoren im 10 ms Takt zyklisch
abgefragt bzw. angesteuert werden dh pro Sensor/Aktor eine Zeit von
500µS
also alle Kanäle 2000 mal in der Sekunde bzw. jeder Sensor/Aktor 100 mal
in der Sekunde das ist ja das gleiche denn es sind ja 20
Sensoren/Aktoren und 20*100=2000
Danke freue mich über weitere Hilfe
@ Michael Dietz (Firma na) (michaeld)
>genau es sollen alle Sensoren bzw. Aktoren im 10 ms Takt zyklisch>abgefragt bzw. angesteuert werden dh pro Sensor/Aktor eine Zeit von>500µS
Schnarchlangsam.
>also alle Kanäle 2000 mal in der Sekunde bzw. jeder Sensor/Aktor 100 mal>in der Sekunde das ist ja das gleiche denn es sind ja 20>Sensoren/Aktoren und 20*100=2000
Vorsicht, deine Formulierung ist falsch. Richtig wäre 2000 Kanäle/s, was
bei 20 Kanälen 100 Hz Abtastfrequenz bedeutet.
Naja, alles in allem ist das nix weiter als ein
Multiplexer/Demuliplexer.
Multiplexen
Dafür reicht ein kleiner Tiny2313 + 3 Schieberegister 74HC595 + 3
Schieberegister 75HC165 zur Porterweiterung mit SPI.
MFG
Falk
>Schnarchlangsam.
OK gut zu wissen das mir die Geschwindigkeit keine Probleme machen wird.
>Naja, alles in allem ist das nix weiter als ein>Multiplexer/Demuliplexer.
das heiß Sensoren/Aktoren über I/O Register.
und dann per usart übertragen.
ok so richtig blick ich da noch nicht durch wie das mit dem usart
funktionieren soll.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Der_UART
wollte keinen normalen Multiplexer nehmen wegen dem Vollduplex.
Danke schonmal
@ Michael Dietz (Firma na) (michaeld)
>das heiß Sensoren/Aktoren über I/O Register.
Quasi. Da du aber allein für sie Sensoren/Aktoren 20 IO/s brauchst,
musst du entweder einen grossen AVR nehmen (8515, mega16 oder so) oder
über Schieberegister IO/Pins schaffen.
>und dann per usart übertragen.
Jo.
>ok so richtig blick ich da noch nicht durch wie das mit dem usart>funktionieren soll.>http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
Dann denk nochmal drüber nach und lies diverse Texte im Netz.
>wollte keinen normalen Multiplexer nehmen wegen dem Vollduplex.
Ein normaler Multiplexer braucht auch Steuerleitungen, die du nicht
hast.
MFG
Falk
gg ok
dann werde ich mal sehn wie das mit dem usart hinhaut.
falls jemand ein Beispiel hat kann er es aber trotzdem posten vieleicht
erspart das ein wenig zeit.
Vielen Dank
@ Michael Dietz (Firma na) (michaeld)
>falls jemand ein Beispiel hat kann er es aber trotzdem posten vieleicht>erspart das ein wenig zeit.
Die Beispiele findest du im Tutorial, wahlweise Assembler oder C.
AVR-Tutorial: UARTAVR-GCC-Tutorial
Ist ja praktisch nix zu machen.
Timer mit 10ms Aufsetzen
Wenn der Timer eine Interrupt auslöst, alle Ports einlesen
Ports in drei Bytes verpackt über UART verschicken.
In der Gegenrichtung quasi das gleiche.
MfG
@ Michael Dietz (Firma na) (michaeld)
>muss ich einen extra quarz mit anschließen oder bekommt ein Atmega8 das>so hin mit dem Uart..?
RTFWA!!!
MFG
Falk
R read T he F ine W iki A rticle.
Ich denke sein Problem liegt darin, dass er wohl etwas per UART vrsenden
oder empfangen kann. Aber er muss ja die Verbindung in irgendeiner weise
Zeitlich steuern oder? Also die Bidirektionalität. Wenn ein uC sendet
kann der andere ja nicht gleichzeitig senden oder?!
Also müsste man eine Art Protokoll einbauen das die uCs dazu veranlasst
abwechselnd zu senden bzw. zu empfangen...
jap soweit ich das jetzt gelesen hab kann man das nach ein bzw 2
gesendeten bytes umstellen aber wie ich das bei den beiden dann synchron
hinbekommen soll ist die frage.
@ Michael Dietz
Ich habe am 4.1.2008 TWI Kommunikationsroutinen in die Codesammlung
gestellt (AVR TWI Master und Slave Funtionen in C ). Vielleicht kannst
du diese für deine Zwecke gebrauchen.
Beitrag "AVR TWI Master und Slave Funtionen in C"
Gruß
Manni
Markus Berent wrote:
> Wenn ein uC sendet> kann der andere ja nicht gleichzeitig senden oder?!
Warum sollte er das nicht können? Es gibt ja 2 Datenleitungen, jeweils
eine für eine Richtung.
> Aber er muss ja die Verbindung in irgendeiner weise> Zeitlich steuern oder?
Einfach einen Timerinterrupt verwenden, wie schon geschrieben.
Michael Dietz wrote:
> muss ich einen extra quarz mit anschließen oder bekommt ein Atmega8 das> so hin mit dem Uart..?
unbedingt ein Quarz nehmen, damit erspart man sich viel Ärger!
Du hast übrigens die andere Richtung, also SPS -> anderen Controller
noch nicht spezifiziert.
Falls du in C programmieren willst:
Im Roboternetz gibt es übrigens auch einen wunderschönen Wiki-Artikel
mit Beispielcode über FIFO-gepufferte, interruptgesteuerte
UART-Kommunikation.
http://www.roboternetz.de/wissen/index.php/UART_mit_avr-gcc
Gruß,
David
>Du hast übrigens die andere Richtung, also SPS -> anderen Controller>noch nicht spezifiziert.
was genau meinst du damit??
was für eine baudrate wird der atmega 8 schaffen wo liegen da die
grenzen?
danke für den artikel ja werde es in C programmieren
Als Quarz nehme ich am besten 16MHz und gehe mit jedem pin uber einen
Kondensator ca 22 pf auf Masse oder?
@ Michael Dietz (Firma na) (michaeld)
>was für eine baudrate wird der atmega 8 schaffen wo liegen da die>grenzen?
Schon mal das Datenblatt konsultiert? Er schafft bis zu 1/8 des
Quarztaktes.
>Als Quarz nehme ich am besten 16MHz und gehe mit jedem pin uber einen
AUA!
Fährst du auch mit dem 40-Tonner zum Bäcker um Brötchen zu holen? Ein
Baudratenquarz mit 1,8432 MHz reicht dicke und du kannst immer noch
mit 115200 Baud arbeiten.
>Kondensator ca 22 pf auf Masse oder?
Ja.
MFG
Falk
@ Michael Dietz (Firma na) (michaeld)
>gibt es programme mit denen man das simulieren kann um zu sehen ob die>beiden atmnegas tatsächlich daten austauschen?
Naja, ZWEI AVRs gleichezitig simulieren geht nicht wirklich. Das kann
man einfacher und schneller real testen. Ein Oszi ist da hilfreich.
MFG
Falk
hab mal ne frage zum timer und zwar:
TCCR0 |= (0<<CS00)|(0<<CS01)|(1<<CS02);
Quarztakt wird durch 256 geteilt 16MHz/256=62500Hz T=1/f=1/62500=
0,000016
--> 16µS
um einen overflow zu erreichen muss der timer bis 255 hochzählen
welche zeit benötigt er bis zum ersten overflow?
256*16µS=4,096mS ist das die zeit bis zum ersten overflow?
danke schonmal
wenn ich jetzt genau aller 10ms einen interuppt auslösen will dann
müsste ich ja quasi (10ms/16µS=625) nach 625 einen interuppt auslösen.
kann mir jemand sagen wie das genau geht müsste ja quasi den overflow 2
mal volllaufen lassen 625-256-256=113 und dann bis 113 zählen nur wie
setze ich das um?
@ Michael Dietz (Firma na) (michaeld)
>wenn ich jetzt genau aller 10ms einen interuppt auslösen will dann>müsste ich ja quasi (10ms/16µS=625) nach 625 einen interuppt auslösen.>kann mir jemand sagen wie das genau geht müsste ja quasi den overflow 2>mal volllaufen lassen 625-256-256=113 und dann bis 113 zählen nur wie>setze ich das um?
???
Bleib mal ganz unruhig und liess dir mal ein paar Grundlagen zum Thema
Timer durch. Der hat auch einen Prescaler. Und du brauchst wie
bereits gesagt keine 16 MHz.
AVR-TutorialAVR-GCC-Tutorial
MFg
Falk
die quarze kosten ja alle ca 20 cent rum was macht es also für einen
unterschied oder hat es sonst noch nachteile?
der Prescaler dient nur zum teilen der taktfrequenz so wie ich das
verstanden habe.
mein problem liegt im moment darin den interuppt auszulösen...
irgendwie mit ISR()...und TCNT0 und TOV0 müsste das gehn oder?
@ Michael Dietz (Firma na) (michaeld)
>die quarze kosten ja alle ca 20 cent rum was macht es also für einen>unterschied oder hat es sonst noch nachteile?
Der Controller langweilt sich zu Tode und verbraucht sinnlos Strom.
-> Uncool.
>der Prescaler dient nur zum teilen der taktfrequenz so wie ich das>verstanden habe.
Ja und? Genau DAS brauchst du, um mit 16 MHz Takt und einem 8 Bit Timer
einen Interrupt alle 10ms auszulösen.
16 MHz / 1024 (Prescaler) = 15625 Hz
15625 Hz / 100 Hz = 156,25.
Nimm also 156. Deine Anwendung braucht nicht GENAU 10ms. Wenn du das
doch haben willst, nimm den Timer 1 (16 Bit) und nutzte den CTC Modus.
>mein problem liegt im moment darin den interuppt auszulösen...>irgendwie mit ISR()...und TCNT0 und TOV0 müsste das gehn oder?http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interruptshttp://www.mikrocontroller.net/articles/Sleep_Mode#Quarzgenaue_Zeitbasis
MFG
Falk
@ Michael Dietz (Firma na) (michaeld)
>da muss doch noch was davor oder sonst teilt man den takt ja im TCCR0.
???
Lies dir bitte mal in Ruhe die Kapitel über den Timer durch.
MFG
Falk
Also ich denke das es fast läuft ich habe nur noch ein kleines Problem
und zwar lese ich die verschiedenen Bits von den Sensoren in eine struct
variable ein kann diese aber nicht in den udr schreiben.
Deklaration der Variable:
1
struct{
2
unsignedcharSens1:1;
3
unsignedcharSens2:1;
4
unsignedcharSens3:1;
5
unsignedcharSens4:1;
6
unsignedcharSens5:1;
7
unsignedcharSens6:1;
8
}a;
Einlesen der Sensoren in die Struct Variable(die letzten beiden Bits
bleiben frei):
1
a.Sens1=PINC&(1<<PINC0);
2
a.Sens2=PINC&(1<<PINC1);
3
a.Sens3=PINC&(1<<PINC2);
4
a.Sens4=PINC&(1<<PINC3);
5
a.Sens5=PINC&(1<<PINC4);
6
a.Sens6=PINC&(1<<PINC5);
Warten bis sendepuffer frei ist und udr beschreiben:
@ Michael Dietz (Firma na) (michaeld)
>Also ich denke das es fast läuft ich habe nur noch ein kleines Problem>und zwar lese ich die verschiedenen Bits von den Sensoren in eine struct>variable ein kann diese aber nicht in den udr schreiben.
Wie auch? Deine Struct besteht aus 5 Bytes. Die musst du einzen senden.
Nimm lieber ein Array.
>Einlesen der Sensoren in die Struct Variable(die letzten beiden Bits>bleiben frei):>a.Sens1 = PINC & (1<<PINC0);> a.Sens2 = PINC & (1<<PINC1);> a.Sens3 = PINC & (1<<PINC2);> a.Sens4 = PINC & (1<<PINC3);> a.Sens5 = PINC & (1<<PINC4);> a.Sens6 = PINC & (1<<PINC5);
Und warum in aller Welt brauchst du ein CHAR, um ein popeliges Bit zu
speichern? Du bist hier in der Mikrocontrollerwelt. Da ist es nicht von
Nachteil, auch mal bissel nachzudenken und Daten sinnvoll zu
strukturieren und zu minimieren.
Sensor = PINC;
ist Dutzende Male schneller und kleiner.
MfG
Falk
mit der :1 am ende des des jeweiligen sensors gibt man doch an das der
wert genau 1 BIT ist deswegen sollte der komplette struct 6Bit sein die
letzten beiden bleiben frei also genau 1 Byte
oder es ist es falsch was in diesem pdf auf seite 5 steht??
http://ulrichradig.de/site/infos/pdf/AtmelCprogramming.pdf
@ Michael Dietz (Firma na) (michaeld)
>mit der :1 am ende des des jeweiligen sensors gibt man doch an das der>wert genau 1 BIT ist deswegen sollte der komplette struct 6Bit sein die>letzten beiden bleiben frei also genau 1 Byte
Aber nur, wenn das Struc "packed" wird. Dazu braucht man einen
kryptischen Zusatz. Alles viel Aufwand für nix.
MFG
Falk
@ Michael Dietz (Firma na) (michaeld)
>Damit hat es jetzt funktioniert heißt das jetzt das meine Variable>größer als ein Byte ist?
Du solltest dich mal mit einem C-Buch auseinandersetzten. Dort steht
drin, was Unions sind. Nämlich zwei verschiedene Variablen, die auf dem
gleichen Speicherplatz liegen. Damit kann man auf ein und die selben
Daten verschiedenartig zugreifen. Ist für deine Anwendung aber Overkill.
MfG
Falk
Benutze statt "char" besser "uint8_t" aus dem Header <stdint.h>
Und merke dir, dass man aus Unions immer nur auf die Weise Werte
herausliest, wie man sie auch hereingeschrieben hat. Wenn die Union also
2 Member hat, darf Member1 nur dann auch wieder durch Member1 gelesen
werden, wenn du durch Member1 geschrieben hast. Würdest du über Member1
schreiben und über Member2 lesen, ist das Ergebnis nicht unbedingt
definiert.
@ Simon K. (simon) Benutzerseite
>werden, wenn du durch Member1 geschrieben hast. Würdest du über Member1>schreiben und über Member2 lesen, ist das Ergebnis nicht unbedingt>definiert.
Aber genau DAS wird ja hier gemacht!
Beitrag "struct in udr schreiben"
MfG
Falk
hallo es geht darum ein paar bytes zwischen 2 mikrocontrollern zu
übertragen
muss man um den RXD(µC1) an TXD(µC2) und RXD(µC2) an TXD(µC1)
anschließen oder RXD an RXD und TXD an TXD?
danke
Falk Brunner wrote:
> @ Simon K. (simon) Benutzerseite>>>werden, wenn du durch Member1 geschrieben hast. Würdest du über Member1>>schreiben und über Member2 lesen, ist das Ergebnis nicht unbedingt>>definiert.>> Aber genau DAS wird ja hier gemacht!>> Beitrag "struct in udr schreiben"
Weiß ich. Einer unserer Programmiergötter hat letztens geschrieben, dass
das Ergebnis undefiniert sei (siehe oben.), er aber noch keinen Compiler
gesehen hat, der an dieser Stelle großartig von dem Erwarteten abweicht.
Und wenn Karl Heinz das schon sagt, wird da was dran sein ;)
PS: Okay der Hinweis oben ist somit ein wenig übertrieben. Ich würde es
trotzdem vermeiden, wenn es geht.
mmmhhhh das habe ich schon trotzdem klappts nicht ansonsten nur die
masse miteinander verbinden oder?
muss man die RXD bzw TXD als ein oder ausgänge definieren?
@ Michael Dietz (Firma na) (michaeld)
>mmmhhhh das habe ich schon trotzdem klappts nicht ansonsten nur die>masse miteinander verbinden oder?
Ja.
>muss man die RXD bzw TXD als ein oder ausgänge definieren?
Nein. Wenn du TXEN und RXEN im UART Register gesetzt hast wird das
automatisch eingestellt.
MFG
Falk
TIMSK|=(1<<TOIE0);// Interrupts aktivieren und damit Timer starten
40
41
}
42
43
ISR(TIMER0_OVF_vect)//auslößen des Timerinteruppts
44
{
45
46
TCNT0=100;// Vorladen
47
48
//Sensoren einlesen
49
Sensor_1bis6=PINA;
50
51
while(!(UCSRA&(1<<UDRE)));// warten bis Senden moeglich (bis Sendepuffer frei ist)
52
53
UDR=Sensor_1bis6;//Daten in den Puffer schreiben und damit senden
54
55
}
56
57
58
59
60
voidinit_uart(unsignedintubrr)
61
{//nur ein register(8Bit) vorhanden deswegen
62
UBRRH=(unsignedchar)(ubrr>>8);//die ersten 8 Bit einlesen und um 8 nach rechts verschieben
63
UBRRL=(unsignedchar)(ubrr);//die nächsten 8 Bit einlesen
64
65
UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);// Aktivieren des "Daten empfangen"-Interrupts, des Empfängers, des Senders
66
67
UCSRC=(1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);//URSEL1=da UBRRH UCSRC gleiches register benutzen wird verhindert das man was überschreibt, USBS 0=1StopBit 1=2StopBits,
DDRA=0xff;//Datenrichtungsregister A alles 1 (Ausgänge) Aktoren
18
19
init_uart(UBRR_WERT);//Aufruf von uartinitialisierung übergabe von UBRR_Wert
20
21
22
23
sei();// globale Interrupts zulassen
24
25
26
while(1){}//endlosschleife um programm nicht zu beenden
27
return0;//Rückgabewert an das Betriebssystem (wird nie erreicht wegen while Schleife)
28
}
29
30
31
32
voidinit_uart(unsignedintubrr)
33
{//nur ein register(8Bit) vorhanden deswegen
34
UBRRH=(unsignedchar)(ubrr>>8);//die ersten 8 Bit einlesen und um 8 nach rechts verschieben
35
UBRRL=(unsignedchar)(ubrr);//die nächsten 8 Bit einlesen
36
37
UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);// Aktivieren des "Daten empfangen"-Interrupts, des Empfängers, des Senders
38
39
UCSRC=(1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);//URSEL1=da UBRRH UCSRC gleiches register benutzen wird verhindert das man was überschreibt, USBS 0=1StopBit 1=2StopBits,
40
//8Bit werden für Datenübertragung benutzt
41
}
42
43
ISR(USART_RXC_vect)//Empfangsinteruppt wird ausgelößt sobald ein Byte empfangen wurde
@ Michael Dietz (Firma na) (michaeld)
>ok dann hier mal die codes für den 1. µC und für den 2.µC
Das nächste Mal bitte als Anhang.
>µC1 sender:
Wenn du den RXC Interrupt aktivierst, musst du auch eine ISR zur
Verfügung stellen. Sonst gibt es ein böses Erwachen.
>µC2 empfänger:> Aktor_1bis6= UDR;> //Werte an Aktoren ausgeben> PINA=Aktor_1bis6;
Das wird nix. Eher so
PORTA = UDR;
MfG
Falk
ok die ersten bytes fliegen hin und her hab nur das ein paar leds nach
dem empfänger schon dunkler werden wenn ich mit der hand in die nähe der
platine komme
@ Michael Dietz (Firma na) (michaeld)
>Dateianhang: sender_und_empf_nger.txt (4 KB, 3 Downloads)
häng das direkt al *.c Quelltext, ggf mach zwei Postings.
>mmhhh hab jetzt einfach mal die ISR wieder zur Verfügung gestellt und>den rest geändert aber es klappt nicht hab die Quelltexte im Anhang.
Tja, wie wäre es, wenn man wenigsten die Minimalfunktion in der ISR für
RXC bedient?
tmp = UDR;
Damit wird nämlich erst der Interrupt gelöscht. Ohe bleibt den
Lieblings-AVR ewig in der ISR hängen. Oder was im Moment sinnvoller ist,
aktiviere den RXC Interrupt einfach nicht!
>ok die ersten bytes fliegen hin und her hab nur das ein paar leds nach>dem empfänger schon dunkler werden wenn ich mit der hand in die nähe der>platine komme
Und jetzt das Ganze nochmal auf Deutsch.
MfG
Falk
oh sorry ja hab mich da irgendwie verschrieben.
Also bin soweit das ich ein Byte übertragen kann.
Habe mir quasi eine kleine Schaltung zum Testen gelötet am 1.µC habe ich
ein paar Schalter die beim schließen eine eins auf die Pins geben die
ich einlese.
Am 2. µC hab ich an den Ports an denen ich das übertragene Byte ausgebe
ein paar LEDs drangelötet.
Problem ist das die LEDs alle dunkel leuchten und wenn ich dann den
Taster 1 am 1.µC betätige dann wird die dazugehörige LED am 2.µC etwas
heller dh es ist ja schonmal teilweise richtig aber außerdem ist da noch
das Problem das ich nur mit den Fingern in die nähe der Platine kommen
muss und schon werden die LEDs teilweise heller oder dunkler.
@ Michael Dietz (Firma na) (michaeld)
>Habe mir quasi eine kleine Schaltung zum Testen gelötet am 1.µC habe ich>ein paar Schalter die beim schließen eine eins auf die Pins geben die>
Warum hast du dir nich mal in RUHE das AVR Tutorial angeschaut?
Denn auch so triviale Sachen wie Taster muss man richtig machen. Warum
schaltest du deine Taster nicht gegen GND und nutzt die internen
Pull-Ups? Macht 99% der Welt so. Erfolgreich.
AVR-Tutorial: IO-Grundlagen>das Problem das ich nur mit den Fingern in die nähe der Platine kommen>muss und schon werden die LEDs teilweise heller oder dunkler.
Ja, es fehlen die Pull-down Widerstände.
MfG
Falk
ja habe gerade mal anstatt mit den tastern einzulesen fertige hex werte
übertragen und siehe da die übertragung ist sauber dann werde ich jetzt
mal nochmal genauer die IO Grundlagen anschauen.
DANKE
>Damit wird nämlich erst der Interrupt gelöscht. Ohe bleibt den>Lieblings-AVR ewig in der ISR hängen.
Nee, der bleibt nicht in der ISR hängen, sondern springt immer wieder
rein, bis UDR gelesen wurde (erst dann löscht die Hardware das Bit).
MW
@ Michael Wilhelm (Gast)
>>Damit wird nämlich erst der Interrupt gelöscht. Ohe bleibt den>>Lieblings-AVR ewig in der ISR hängen.>Nee, der bleibt nicht in der ISR hängen, sondern springt immer wieder>rein,
Ist das ein wesenlticher Unterschied?
> bis UDR gelesen wurde (erst dann löscht die Hardware das Bit).
Was im geposteten Quelltext nie passiert. Vorsicht, dort sind die
Quellen von ZWEI uCs drin. Was auch nicht wirklich sinnvoll ist.
MFg
Falk
@ Falk:
>Ist das ein wesenlticher Unterschied?
Ist natürlich kein wesentlicher Unterschied. Aber, wenn solch
elementaren Fehler gemacht werden, trägt die korrekte Darstellung
hoffentlich zum besseren Verständnis bei.
MW
@ Michael Wilhelm (Gast)
>Ist natürlich kein wesentlicher Unterschied. Aber, wenn solch>elementaren Fehler gemacht werden, trägt die korrekte Darstellung>hoffentlich zum besseren Verständnis bei.
Stimmt!
MfG
Falk
so schonmal vielen dank habe jetzt ne saubere übertragung. habe jetzt
wie schon angesprochen einfach die pull up widerstände eingeschaltet.
nochmal vielen dank
und jetzt muss ich das ganze noch zu vollduplex machen und zusätzlich
crc cheksumme und wenn das nicht reicht noch andere prüfwerte berechnen.
hat schonmal jemand probiert mit uart zu übertragen direkt neben nem
motor der von nem fu angesteuert wird über ungeschirmtes kabel glaubt
ihr das bekommt man softwaremäßig hin?
@ Michael Dietz (Firma na) (michaeld)
>und jetzt muss ich das ganze noch zu vollduplex machen und zusätzlich>crc cheksumme und wenn das nicht reicht noch andere prüfwerte berechnen.
Mach mal halblang. Parity reicht hier vollkommen aus. Das ist doch keine
Hochsicherheitsanwendung in einem Flugzeug.
>hat schonmal jemand probiert mit uart zu übertragen direkt neben nem>motor der von nem fu angesteuert wird über ungeschirmtes kabel glaubt>ihr das bekommt man softwaremäßig hin?
???
Hat mit Software gar nix zu tun. Und warum willst du ein ungeschirmtes
Kabel nehmen? So geizig? Wenn das aber genutzt werden MUSS, weil kein
anderes verfügbar ist, dann braucht man entsptrechende
Hardwaremassnahmen, um die Übertragung zu sichern. Z.B. RS485 mit
MAX485. Die ist differentiell und damit wesentlich störsicherer.
MfG
Falk
>Mach mal halblang. Parity reicht hier vollkommen aus. Das ist doch keine>Hochsicherheitsanwendung in einem Flugzeug.
ist den crc ein erheblicher mehraufwand?
>Und warum willst du ein ungeschirmtes>Kabel nehmen? So geizig?
das ist eins von diesen hochflexibelen die viel bewegt werden mit schirm
gehen die immer verdammt schnell kaputt.
>dann braucht man entsptrechende Hardwaremassnahmen, um die Übertragung zu >sichern. Z.B. RS485 mit MAX485.
da ändert sich dann nix an der software dh. man schaltet nur diesen
Baustein MAX485 dazwischen?
@ Michael Dietz (Firma na) (michaeld)
>ist den crc ein erheblicher mehraufwand?
Naja, eigentlich schon.
>da ändert sich dann nix an der software dh. man schaltet nur diesen>Baustein MAX485 dazwischen?
Nicht ganz. Du sagtest ja, dass du nur zwei Adern + Masse zur Verfügung
hast. Da muss du dann mit Halbduplex arbeiten, weil RS458 zwei Adern für
ein Signal braucht (differentiell). Etwa so.
- Beide uC sind auf Empfang geschaltet
- Der Master schaltet nach 10ms (Timer) auf Senden und sendet seine
Daten.
- Am Ende der Übertragung (TXC-Interrupt) schaltet der Master sofort
wieder auf Empfangen
- Der Slave empfängt die Daten
- Der Slave schaltet auf Senden und sendet seine Daten
- Am Ende der Übertragung (TXC-Interrupt) schaltet der Slave sofort
wieder auf Empfangen
- Der Master empfängt die Daten vom Slave
- Alles von vorn
MfG
Falk
Keramikschwinger/Oszillator statt Quarz/Oszillator??
welcher ist da genauer was hat der keramikschwinger für vorteile außer
das er keine kondensatoren braucht?
@ Michael Dietz (Firma na) (michaeld)
>welcher ist da genauer
Quarz (ca, +/- 0.01%). Keramikschwinger ca. +/- 1%
> was hat der keramikschwinger für vorteile außer>das er keine kondensatoren braucht?
Er schwingt schneller an, ca. 1ms, gegenüber ca. 10ms beim Quarz.
MfG
Falk
Hallo
ich hab meinen Atmega jetzt vom Evaluation Board runter genommen und auf
ne Lochplatine draufgelötet will mit der seriellen Schaltung
ISP(http://s-huehn.de/elektronik/avr-prog/avr-prog.htm) auf ihn
einspeißen
aber irgendwie klappt es nicht geht das mit der Schaltung nicht beim
Atmega16? normal schon oder?
@ Michael Dietz (Firma na) (michaeld)
>aber irgendwie klappt es nicht
Tja, alles prüfen. Betriebsspannung, Lötstellen, Kondensatoren, richtige
Verbindungen etc.
> geht das mit der Schaltung nicht beim>Atmega16? normal schon oder?
Doch, der wird ganz normal programmiert.
MfG
Falk
4,3 kann noch reichen, ist aber schon grenzwertig.
Das Problem ist hier, dass die am LPT-Port angeschlossenen Programmer in
der regel volle 5V Spannung liefern.
Wenn der zu programmierende AVR weniger Bestriebsspannung hat, dann kann
da gelegentlich der MISO.Pin durchbrennen - und dann ist der AVR nicht
mehr viel wert (weil nicht mehr programmierbar).
Besser ist es daher, Programmer zu verwenden, die aus der
Target-Spannung selbst versorgt werden.
Für Deinen Mega16 würde ich ggf. den AVR Dragon empfehlen: nicht teuer
und JTAG kommt voll cool, wenn man mal wieder ein Interrupt-Problem
debuggen muss :-)
Auch auf einem 2m-Kabel würde ich schon nicht mehr mit Logik-Pegeln
arbeiten, speziell wenn Störungen aus Motoren oder dergl. zu erwarten
sind.
Hier ist in der Tat ein Halbduplex auf einer RS485 besser geeignet.
Für Vollduplex spendiert man dann eben noch ein Aderpaar für die
Gegenrichtung.
Gegen Logikpegel sprechen vor allem Masseschleifen und die geringen
Treiberleistungen der Portpins. Mit Treibern (232er oder 485er Typ) hat
man hier bessere Karten, die Kabel auch treiben zu können.
Die Max485 sind nette Bausteine, ich benutze aber idR. SN75176 als
Bustreiber. Die sind billiger und genauso störsicher. Brauchen nur mehr
Strom und werden ab ca. 25 Busteilnehmern ggf. etwas zickig, aber wann
hat man die schon? :-) Hier jedenfalls nicht .-)
Die Umschaltung der Senderichtung (also wer grad sendet) mache ich wie
im CB-Funk: am Ende der Sendung steht dann ein "Over"-Zeichen, aus dem
der Empfänger sehen kann, dass er jetzt reden darf.
Man liest immer, dass für UART-Übertragung der RC-Oszillator nicht
geeignet ist sonder dass ein Quarz sein muss.
Das stimmt bedingt, aber nicht ganz :-)
In der Tat kann man mit dem Quarz wenig falsch machen, wenn der damit
getaktet AVR nicht zu vielen Vibrationen ausgesetzt ist (Vibrationen
verstimmen einen Quarz doch deutlich).
Aber der RC-Oszillator reicht aus, wenn man wirklich will und wenn die
Betriebsspannungen der AVRs genau sind.
Die Vcc spielt eine grosse Rolle, denn der RC-Oszillator ist spürbar
spannungsabhängig. ATMega8 liefern bei 5V bei mir in der Regel sehr gute
Baudraten bis 19200, bei 3V dagegen nur noch Bitmüll bis man den
Oszillator nachgetrimmt hat (oder eben die 2 Pins für den Quarz
opfert...).
Wenn man mit der Wortlänge allerdings auf 5Bit runter geht, dann klappt
es selbst bei 3V noch ganz passabel auch ohne Rekalibrierung (wenn auch
schon an der Grenze).
Der Grund ist, dass mit zunehmender Wortlänge (8N1 sind ja 10 Bit
Wortlänge) die Anforderung an die Takte von Sender und Empfänger starkt
ansteigt: Bei 5N1 ist ein grösserer Unterschied zwischen den beiden
Takten erlaubt als bei 8N1.
Also: wenn zwei AVRs miteinander reden sollen über die UARTs und beide
haben dieselbe Spannung und Temperatur, dann tut es auch der
RC-Oszillator normalerweise sehr gut, besonders bei kurzen Wortlängen.
Und wenn man sich nicht den Wolf machen will, jedes Byte als zwei
Nibbles in je einem 5Bit-Wort zu übertragen, dann eben Quarz nehmen :-)
Die Idee, die Übertragung mit CRC zu sichern, halte ich nicht für falsch
oder Overkill.
Zum einen kann man da fertige Routinen in C hernehmen, ist also wenig
Aufwand, hat aber den Vorzug, dass das Ping-Pong-Protokoll zwischen den
beiden AVRs sicherer wieder aufsetzen kann, wenn eine Störung mal
dazwischengefunkt hat und das Spiel der beiden aus dem Tritt gekommen
ist.
ich würde das vermutlich so designen, dass es einen Master gibt, der den
Takt der Kommunikation vorgibt und den Slave quasi pollt. Der Slave
reagierte dann nur auf korrekte Prüfsummen und wartet sonst einfach, bis
die nächste Sendung beginnt.
Ein Problem, das man immer lösen muss, ist, den Start einer Sendung
zuverlässig feststellen zu können.
Ich halte nicht viel davon, eine Break-Condition dafür zu verwenden,
denn die kann auch als Störung mal auftreten und die eingebauten UARTs
können die auch nicht sehr gut erkennen.
Meine bevorzugte Methode ist eine Sync-Praeambel, z.B. eine halbe
Sekunde 0-1-Wechsel. kostet aber Zeit und Programmieraufwand, denn das
muss man zu Fuss programmieren (Pins als IO definieren, UART abschalten
und so), macht man also nur, wenn Übertragungsfehler richtig Geld
kosten...
Alternativ sendet man Datenpakete, die mit einem Magic-Wert anfangen,
der sonst in der Übertragung nicht vorkommen kann. Das erlaubt dann eine
recht zuverlässige Resynchronisierung, wenn einer der Redner nicht mehr
weiss, wo hinten und vorn vom Datenstrom ist.
Für Dein nächstes Projekt möchte ich Dir noch raten, Dir die RS422/RS485
Treiber nochmal anzusehen.
Wenn man ein paar mehr Leitungen spendiert (2 je Signal und Richtung),
dann kann man damit hervorragend Daten übertragen, nicht nur asynchron
sondern auch synchron seriell.
Und bei synchroner Übertragung ist dann wenigstens die Quarzfrage
endgültig gelöst :-)
Gruß
hase
@ Hatmut Semken (Gast)
>Hier ist in der Tat ein Halbduplex auf einer RS485 besser geeignet.>Für Vollduplex spendiert man dann eben noch ein Aderpaar für die>Gegenrichtung.
Das ist nicht verfügbar, siehe Anfang des Threads.
>Die Max485 sind nette Bausteine, ich benutze aber idR. SN75176 als>Bustreiber. Die sind billiger und genauso störsicher. Brauchen nur mehr
Aber hornalt und brauchen Strom ohne Ende!
>Die Umschaltung der Senderichtung (also wer grad sendet) mache ich wie>im CB-Funk: am Ende der Sendung steht dann ein "Over"-Zeichen, aus dem>der Empfänger sehen kann, dass er jetzt reden darf.
Flow Control nennt man das wohl, XON/XOFF.
>Man liest immer, dass für UART-Übertragung der RC-Oszillator nicht>geeignet ist sonder dass ein Quarz sein muss.>Das stimmt bedingt, aber nicht ganz :-)
Es simmt genug, um einen Quarz zu verwenden.
>In der Tat kann man mit dem Quarz wenig falsch machen, wenn der damit>getaktet AVR nicht zu vielen Vibrationen ausgesetzt ist (Vibrationen>verstimmen einen Quarz doch deutlich).
Aber kaum soviel, wie ein RC-Oszillator falsch geht. Dazwischen liegt
mehr als der Faktor 100.
>Aber der RC-Oszillator reicht aus, wenn man wirklich will und wenn die>Betriebsspannungen der AVRs genau sind.
Du bist ein Seelenverkäufer.
>Die Vcc spielt eine grosse Rolle, denn der RC-Oszillator ist spürbar>spannungsabhängig. ATMega8 liefern bei 5V bei mir in der Regel sehr gute>Baudraten bis 19200, bei 3V dagegen nur noch Bitmüll bis man den
Jaja, deine drei die du aufgebaut hast.
>beiden AVRs sicherer wieder aufsetzen kann, wenn eine Störung mal>dazwischengefunkt hat und das Spiel der beiden aus dem Tritt gekommen>ist.
Die Synchronisiation hat mit CRC wenig zu tun.
MFG
Falk
Hallo
Ich habe die Schaltung (Serielles Interface für AVR und Pony Prog)der
folgenden Seite nachgebaut aber kann einfach nicht in den µC übertragen.
Es kommt immer ein Fehler im Pony Prog wenn ich allerdings bei der
Fehlermeldung auf "ignore" gehe dann fängt er an zu übertragen und die
Leds am schon programmiertem Atmega die normalerweise bei
betriebsspannung leuchten gehen für die Zeit des Schreibevorgangs aus.
Danach kommt allerdings "Writing fail".
Hatte jemand das schonmal??Weis einfach nicht was ich da noch machen
soll.
http://s-huehn.de/elektronik/avr-prog/avr-prog.htm <Seite mit Schaltung
Serielles Interface für AVR und Pony Prog
Da habe ich mal die Schaltung drangehangen mit der ich über Com vom PC
aus den Flash im Atmega beschreiben will klappt aber nicht.
externer Quarz ist angeschlossen und geht über kondensatoren 22pF auf
Masse
AVCC und VCC gehen über Kondensator 100nF auf Masse.
Kann einfach nicht auf der Atmega schreiben.
an einem µC empfange ich 2 Bytes hintereinander dadurch wird aber immer
der empfangsinteruppt ausgelößt und er schreibt ihn in die gleiche
variable aber das zweite Byte soll ja in die 2te Variable.
Deswegen habe ich vor in jedes der beiden Bytes 6 Bit Nutzdaten und 2
Bit quasi als Schlüssel einzufügen um zu sehn ob es in die erste oder
zweite Variable geschrieben wird.
Deswegen die Frage wie schreibe ich Bits von zwei verschiedenen Ports in
eine Variable?
@ Michael Dietz (Firma na) (michaeld)
>Deswegen die Frage wie schreibe ich Bits von zwei verschiedenen Ports in>eine Variable?
Also wirklich. Wen SOOOOO eleentat einfach Dinge schon unklar sind, wie
willst du den Rest schaffen?
IF( obere Bits) ...
>mmhhh habe meine übertragung die vorher funktioniert hat jetzt mit einem>kabel probiert was ca 30cm lang ist. macht der uart da schon schlapp?
Kaum. Sag mit bitte nicht, dass du keine Masse verbunden hast....?!
Und denk dran, RXD und TXD kreuzen.
MfG
Falk
denke vom Verständnis her ist das schon klar was ich mit den Bits tun
muss es hackt halt bissl an der Syntax.
Ja habe die Masse verbunden und RXD und TXD gekreuzt.
das seltsame ist das bei der übertragung jeweils das erste und das
letzte bit stimmen die dazwischen aber nicht.
Habe die Schalter gegen Masse und die internen Pull Ups des µC aktiviert
dabei ist mir aufgefallen das wenn die Schalter offen sind fast alle
Pins des µC auf 5V sind aber einer immer nicht obwohl der PullUP
aktiviert ist. Kann es sein das der µC nicht so viele Pull Ups schhafft?
@ Michael Dietz (Firma na) (michaeld)
>denke vom Verständnis her ist das schon klar was ich mit den Bits tun>muss es hackt halt bissl an der Syntax.Bitmanimpultation
1
if((rx_data&0xC0)==1){
2
// erstes Byte
3
PORTA=rx_data;
4
}
5
else{
6
// zweites Byte
7
PORTB=rx_data;
8
9
}
Ja habe die Masse verbunden und RXD und TXD gekreuzt.
>das seltsame ist das bei der übertragung jeweils das erste und das>letzte bit stimmen die dazwischen aber nicht.
Hast du bei BEIDEN AVRs die gleichen Quarze dran und die AVR Fuses
richtig gesetzt?
>dabei ist mir aufgefallen das wenn die Schalter offen sind fast alle>Pins des µC auf 5V sind aber einer immer nicht obwohl der PullUP>aktiviert ist. Kann es sein das der µC nicht so viele Pull Ups schhafft?
Nein, die Pull-up laufen alle problemlos. Klingt nach ne Lötbrücke oder
Programmierfehler.
MfG
Falk
hab die lötbrücken nochmal alle überprüft die stimmen soweit.
habe festgestellt das immer die ersten beiden und die letzten beiden
bits sauber übertragen werden die mittleren 4 bits allerdings nicht das
ist mir ein rätsel
ich post mal meine beiden codes.
@ Michael Dietz (Firma na) (michaeld)
>oh habe grad den code gepostet wo ich mit halbduplex probiert habe hier>nochmal der in vollduplex
Wo soll da der Unterschied sein? Dein Code sieht erstmal OK aus.
MfG
Falk
bei dem einen ist noch ein Teil auskommentiert und die Register werden
erst nochmal in Variablen geschrieben und dann in den UDR.
Naja kein wesentlicher Unterschied hast recht.
Kann sich das denn jemand erklären wie es dazu kommt das die mittleren 4
Bits immer fehlerhaft übertragen werden.
Am Register an dem eingelesen wird habe ich einen 8 poligen DIP Schalter
wenn ich dei beiden äußeren Schalter umschalte so ändert sich auch auch
der Zustand der Leds am Ausgangsregister des anderen µCaber bei den
mittleren Bits passiert nix da leuchten die Leds immer.
@ Michael Dietz (Firma na) (michaeld)
>Kann sich das denn jemand erklären wie es dazu kommt das die mittleren 4>Bits immer fehlerhaft übertragen werden.
Glaub ich nicht. Sende mal statt PINC eine Konstante, z.B. 0x01, 0x02,
0x04 etc.
>Am Register an dem eingelesen wird habe ich einen 8 poligen DIP Schalter>wenn ich dei beiden äußeren Schalter umschalte so ändert sich auch auch>der Zustand der Leds am Ausgangsregister des anderen µCaber bei den>mittleren Bits passiert nix da leuchten die Leds immer.
Mit dem popeligen DIP-Schalter hast du dich schonmal vertan. Prüfe die
Verbindungen und Lötstellen. Prüfe an Pin des uC , ob du sauber schalten
kannst.
MfG
Falk
von den verbindungen an sich stimmt alles der dip schaltet sauber das
einzige problem was ich festgestellt habe und das auch noch an beiden µC
ist das der PINC4 wenn der schalter zu ist 0V hat klar der schltet auf
Masse aber wenn ich ihn aufmache nur 0,8V gibt das ist an beiden
Atmega16 der gleiche PIN am C register bei allen anderen gibt es 5V wenn
der schalter auf ist
hab gerade rausgefunden das die pins am register c fürs jtagn benutzt
werden bin hab also in den fuses jtagn ausgestellt und siehe da die
mittleren 4 bits klappen
soso dh jetzt geht es daran die bytes crc zu prüfen muss man das manuell
machen?
oder gibts da fertige möglichkeiten?
wenn ihr paar gute links habt postet einfach mal
@ Michael Dietz (Firma na) (michaeld)
>soso dh jetzt geht es daran die bytes crc zu prüfen muss man das manuell>machen?
Mit einer Funktion.
>oder gibts da fertige möglichkeiten?
Sicher, hab aber keine Links auf fertigen Code.
CRC
MfG
Falk
P.S. Bei 2 Byte / Datenpaket ist CRC Overkill. Sende einfach die Bytes
doppelt, und das zweite Mal invertiert. Vergleich alles am Empfänger und
gut.
@ Michael Dietz (Firma na) (michaeld)
>So habe mal versucht zwischen den beiden Bytes zu unterscheiden beim>empafangen es klappt aber noch nicht so ganz. hier mal der code und gn8
Tja, man sollte doch hin und wieder mal über Bitmanipulation
nachdenken.
> Sensor_1bis6 = (Sensor_1bis6 | 0x00); //00 f�r Byte Sensor_1bis6
Völlig unsinning, die Variable wird NIE verändert.
> Sensor_7bis12 = (Sensor_7bis12 | 0xC0); // 11 f�r Byte
Knapp daneben ist auch vorbei. Hier werden definitiv Bit 6 und 7
gesetzt. ABER! In Sensor_1bis6 können die auch gesetzt sein :-0. Eher so
1
Sensor_1bis6&=~0xC0);// Bits 6 & 7 loeschen
2
Sensor_7bis12|=0xC0);// Bits 6 & 7 setzen
Und die Auswertung ist auch falsch.
//das empfangene byte wird im UDR gespeichert
rx_data= UDR; // Empfangsregister auslesen
> if ((rx_data & 0xC0) == 1) //11 als h�chste Bits?
Dieser Ausdruck kann NIE wahr werden.
Ja, ist von mir, hab da wohl im Eifer des Gefechts was falsches
geschrieben. Eher so.
oh da hätte man auch selber drauf kommen können....gg es klappt
Wenn ich allerdings einzelne Schalter(Sensoren) so schalte das die reihe
der nutzbits 101010 ist dann kommt es zu fehlern auf der übertragung
zeigt sich durch blinken benachbarter leds. Glaube das ist weil uart nur
ein Stopbit verwendet habs auch schon mit 2 probiert aber da ändert sich
nix bei bestimmten Kombinationen ist die Übertragung nicht mehr sauber.
Wird sich dieses Problem geben wenn ich die Bytes prüfe?
mal wieder vielen dank Falk
MfG
Michael
@ Michael Dietz (Firma na) (michaeld)
>Wenn ich allerdings einzelne Schalter(Sensoren) so schalte das die reihe>der nutzbits 101010 ist dann kommt es zu fehlern auf der übertragung>zeigt sich durch blinken benachbarter leds. Glaube das ist weil uart nur>ein Stopbit verwendet habs auch schon mit 2 probiert aber da ändert sich>nix bei bestimmten Kombinationen ist die Übertragung nicht mehr sauber.
Nein, das hat nix mit der Anzahl Stopbits zu tun. Prüfe nochmal genau,
ob auf beiden AVRs die gleichen UART-Einstellungen vorhanden sind.
>Wird sich dieses Problem geben wenn ich die Bytes prüfe?
Nein, das ist ein anderes Problem. Erstmal muss es ohne Prüfung sauber
laufen.
MfG
Falk
kann es sein das es daran liegt das ich die Quarze an nicht Baugleichen
Kondensatroen gegen Masse habe.
Oder sind die nur beim einschwingen von Bedeutung?
so habe jetzt vor die zwei bytes die ich sende jeweils nochmal negiert
zu senden also beim sender an
Byte1 11 in die höchstwertigen Bits schreiben
an negiert_Byte1 00 in die höchstwertigen Bits schreiben
an Byte2 10 in die höchstwertigen Bits schreiben
an negiert_Byte2 01 in die höchstwertigen Bits schreiben
das hab ich soweit schon realisiert
un dann beim empfänger mit
if(Byte1 == ~negiert_Byte1)
{an ausgangsregister weitergeben}
wenn nicht verwerfen und auf das nächste warten und evtl alle 5ms senden
nur wie kann ich abwarten bis alle 4 Bytes da sind um sie zu vergleichen
kann ich da 4 if schleifen hintereinander machen?
MfG
Michael
@ Michael Dietz (Firma na) (michaeld)
>fehler gefunden fuse bit ckopt war nicht gesetzt was ja ab 8MHz gesetzt>sein sollte
Oder einfach einen niederfrequenten Quarz nutzen. Wie bereits mehrfach
gesagt, 1,8432 MHz reichen für dich LOCKER .
>un dann beim empfänger mit>if(Byte1 == ~negiert_Byte1)>{an ausgangsregister weitergeben}>wenn nicht verwerfen und auf das nächste warten und evtl alle 5ms senden>nur wie kann ich abwarten bis alle 4 Bytes da sind um sie zu vergleichen
Ganz einfach. Du weist ja, dass dein Sender immer in einer bestimmten
Reihenfolge sendet, z.B. so
sensor_1bis6
sensor_1bis6 negiert
sensor_7bis12
sensor_7bis12 negiert
Also musst du in deiner Empfangsroutine nur die Bytes erstmal zwischen
speichern und wenn du am Anfang wieder angekommen bist weisst du, dass
du alle einmal empfangen hast. Dann kannst du alle prüfen und ausgeben.
Etwa so.
1
// in der ISR des Empfängers
2
3
tmp=UDR;
4
code=tmp>>6;
5
tmp&=~0xC0;
6
7
switch(code){
8
case0:sensor_1bis6=tmp;break;
9
case1:sensor_1bis6_negiert=tmp;break;
10
case2:sensor_7bis12=tmp;break;
11
case3:sensor_7bis12_negiert=tmp;
12
if(sensor_1bis6==(~sensor_1bis6_negiert&~0xC0))
13
PORTA=sensor_1bis6;
14
if(sensor_7bis12==(~sensor_7bis12_negiert&~0xC0))
15
PORTB=sensor_7bis12;
16
break;
17
}
>kann ich da 4 if schleifen hintereinander machen?
Es gibt keine "if Schleifen", nur If Abfragen. Du kannst auch tausend
hintereinander machen. Aber wozu? Siehe oben.
MfG
Falk
P.S. Du bist wohl eine Nachteule? Wenn man so die Zeiten einiger deiner
Postings so betrachtet ;-)
@ Michael Dietz (Firma na) (michaeld)
>Hallo so klappt das nicht
Was was klappt denn nicht? Und wenn dann bitte vollständigen Quelltext
als Anhang.
MFG
Falk
Da oben ist Sende und Empfangsroutine beim Sender wird 00,01,10,11 in
die beiden höchstwertigen Bits geschrieben und beim Empfänger wird
dieses ausgewertet und dadurch die Bytes wieder den richtigen Variablen
zugeordnet.
Hier nochmal die Codes ganz.
@ Michael Dietz (Firma na) (michaeld)
>Dateianhang: Atmega16_2.c (3,7 KB, 0 Downloads) | formatierter Code>2ter Code
Ja und? Was geht denn nicht? Ich seh keinen Fehler.
MFG
Falk
mmmmhhhh ich habe auch nichts gesehen...die Übertragung ohne die
Prüfwerte klappt aber mit klappt es nicht deswegen glaube ich das der
Fehler irgendwo da ist wo der empfänger die einzelnen Bytes den
richtigen Variablen zuordnet.
Außer ich bekomme auf meinen 30 cm so viele Fehler das jedes Byte falsch
ist das glaube ich allerdings nicht.
kann es sein das er es nicht schafft in 10 ms an die 4 Packete den code
dranzuhängen und runterzuschicken bzw er unten diese nicht schnell genug
auswerten kann?
@ Michael Dietz (Firma na) (michaeld)
>kann es sein das er es nicht schafft in 10 ms an die 4 Packete den code>dranzuhängen und runterzuschicken bzw er unten diese nicht schnell genug>auswerten kann?
Rechnen?
4 Bytes / 10ms -> 400 Bytes/s
Du arbeitest mit 9600 Baud also 960 Bytes/s.
Lass dir mal jeweils eins der vier Daten auf LEDs anzeigen.
MfG
Falk
ok wenn ich die bytes einzeln verschicke dann kommen die daten sauber an
denke dann liegt der fehler irgendwo bei den beiden prüfbits. die werden
falsch verechnet und er gibt nix mehr raus
@ Michael Dietz (Firma na) (michaeld)
>ok wenn ich die bytes einzeln verschicke dann kommen die daten sauber an>denke dann liegt der fehler irgendwo bei den beiden prüfbits. die werden>falsch verechnet und er gibt nix mehr raus
Du sollst sie nicht einzeln verschicken sondern ANZEIGEN. Ein Griff zum
Oszi wäre auch nicht verkehrt.
Mfg
Falk
ja habe sie anzeigen lassen die kommen alles richtig an und der negierte
wert ist auch immer negiert zu seinem Wert, dh der fehler muss in der if
anweißung unten liegen oder?
@ Michael Dietz (Firma na) (michaeld)
>ja habe sie anzeigen lassen die kommen alles richtig an und der negierte>wert ist auch immer negiert zu seinem Wert, dh der fehler muss in der if>anweißung unten liegen oder?
GENAU!
MfG
Falk
Ich seh keinen Fehler. Hast du auch SPS_in1bis6 etc. anzeigen lassen und
nicht rx_data? Hast du auch das richtige Programm in beiden
Controllern drin?
Mfg
Falk
OH Shit! Ich hasse C! Blöder Mist!
So gehts. Stichwort Integer Promotion. Grrrr.
1
2
if(SPS_in1bis6==(~negiert1bis6&~0xC0))
3
PORTA=SPS_in1bis6;
die Konstante 0xC0 wird auf 16 Bit aufgebohrt und DANN invertiert. Macht
dann NICHT 0x3F, sondern 0xFF3F. Und da kann der Vergleich NIE wahr
sein.
Korrigierte Version im Anhang. Und sag mal, hast du die Compilerwarungen
alle ignoriert? Deine Funktionen müssen VOR main() im Quelltext liegen,
wenn du keine Headerfiles nutzt.
MFG
Falk
hab diese warnung vom compiler irgendwie nie realisiert weil wenn ich
das zweite mal compiliert habe war sie nicht mehr da dachte das wäre ein
bug im avr studio.
Das senden in die eine richtung klappt jetzt habe jetzt auch mal das für
die andere richtung eingebaut aber das klappt noch nicht so ganz.
poste hier mal wieder beide.
@Thread: Etwas ähnliches hatte ich auch mit 2 ATMEGA8 vor. Dieser Thread
ist zwar riesengroß, hat aber sehr weitergeholfen!
@Falk Brunner:
Woher hast du eigentlich dein ganzes Wissen rund um uC?
Arbeitest du in der Branche? Und wie alt bist du eigentlich wenn man
fragen darf.
@ Rainer Milenski (Gast)
>Woher hast du eigentlich dein ganzes Wissen rund um uC?
Hat sich in den Jahren so angesammelt. Das meiste über Hobby, später
Studium, ein wenig im Job.
>Arbeitest du in der Branche?
Ja. Hardwareentwicklung.
> Und wie alt bist du eigentlich wenn man fragen darf.
Staatsgeheimnis! Aber ich darf/muss schon zur Ü30 Party ;-)
MfG
Falk
Michael Dietz wrote:
> hab diese warnung vom compiler irgendwie nie realisiert weil wenn ich> das zweite mal compiliert habe war sie nicht mehr da dachte das wäre ein> bug im avr studio.
Nein keinesfalles!
Die Datei wird nur neu kompiliert, wenn du diese auch verändert hast.
Und wenn die Datei nicht kompiliert wird (da nicht verändert zum
vorherigen Buildvorgang) werden auch keine Kompilier-Fehler dieser Datei
angezeigt.
haber meine beiden Quelltexte von oben nochmal genau überprüft und der
fehler liegt daran das er beim Aktor_1bis8_negiert das 4,5 und 6 Bit
immer als eins rausgibt.
hier nochmal sende und empfangs routinen:
sender:
1
ISR(TIMER0_OVF_vect)//auslößen des Timerinteruppts
@Michael Dietz:
Diese Frage "Datenübertragung zwischen zwei ATxx" taucht andauernd
wieder auf. Normalerweise mag ich es ja gar nicht, wenn die Leute
solche Kommentare abgeben, aber für einmal muss ich es einfach auch
erwähnen: Benutz doch bitte mal die Suchfunktion. Praktisch jeden Tag
taucht ein Thread auf, mit ner Frage wie "ich will Daten vom ATMEGA xy
zum ATMEGA xyz übetragen, wie geht das?".
Auch im AVR-Tutorial wird sowas eingehend beschrieben.
Also bitte, an alle: schaut doch erst mal da rein oder benutzt die
Suchfunktion, wenn ihr was zu der Datenübertragung wissen wollt.
gg ja die übertragung an sich klappt ja soweit darum geht es hier auch
nicht mehr es geht nur noch darum den einen kleinen fehler da zu finden
der rest klappt schon.
Bitmanipultaion ist manchmal schwerer als man denkt.
So sollte es laufen. Und versuch mal deinen Quelltext ordentlich zu
formatieren, das ist wesentlich für die Lesbarkeit und Fehlersuche!
Und arbeite mal mit lokalen Variablen, sonst kommts du bald in Teufels
Küche.
1
/*
2
Empfangsinteruppt wird ausgelößt sobald ein Byte empfangen wurde
mmhhh es funktioniert nich sehe aber auch keinen unterschied außer das 2
Variablen weniger da sind und und jeweils um eine zeile gekürzt wurde
bei der if abfrage bleibt der PORT A komplett auf null
gebe ich Aktor_1bis4 einzeln heraus so stimmen die werte mit den
gesendeten überein
gebe ich aber Aktor_1bis4_negiert einzeln heraus so bleiben die Bits 4
und 5 immer gesetzt auch wenn ich eine null sende
@ Michael Dietz (Firma na) (michaeld)
>mmhhh es funktioniert nich sehe aber auch keinen unterschied außer das 2>Variablen weniger da sind und und jeweils um eine zeile gekürzt wurde
Doch, es ist ein elementarer Unterschied da. Nämlich
rx_data &= 0x0F;
Damit werden die oberen 4 Bit ausmaskiert. In alles vier Bytes. Nur dann
klappt die "Rückvereinigung" per ODER.
>bei der if abfrage bleibt der PORT A komplett auf null
OK, wir sind wieder drauf reingefallen. Integer Promotion. Ich könnte
kotzen!
So gehts.
1
/*
2
Empfangsinteruppt wird ausgelößt sobald ein Byte empfangen wurde
ja es hat wieder an den integerwerten gelegen....
diesmal hat der compiler nix gesagt.
ok jetzt habe ich vor mit dem PC und AVR Terminal verschiedene Bytes zu
versenden und am anderen µC die Daten wieder an den PC zu geben und dort
dann gesendete mit angekommenen zu vergleichen.
eignet sich AVR Terminal dazu arbeitet es mit dem SI Prog I/O zusmmen?
werde es mal testen aber könnt gerne Vorschläge posten wie man es besser
machen könnte
@ Michael Dietz (Firma na) (michaeld)
>eignet sich AVR Terminal dazu arbeitet es mit dem SI Prog I/O zusmmen?
Was ist AVR Terminal? Denk dran, dass du einen MAX232 brauchst, wenn du
mit dem PC kommunizieren willst.
MFG
Falk
das problem ist das ich ja den uart schon verwende aber den brauche ich
auch wenn ich die daten an den pc geben will oder?
gibt es ne möglichkeit entweder die übertragung zum pc oder die
übertragung zwischen den beiden µC auf andere pins als RXD und TXD von
uart aufzulegen..?
avr terminal hatte ich auf soner seite gesehn war aber wohl nix
vernünftiges hab es auch nicht zum download gefunden. habe jetzt
Hyperterminal aber mit meiner schnittstelle über miso und mosi kann ich
da nix senden bzw empfangen.
@ Michael Dietz (Firma na) (michaeld)
>das problem ist das ich ja den uart schon verwende aber den brauche ich>auch wenn ich die daten an den pc geben will oder?
Wäre von Vorteil. Dann nimm einen Multiplexer und schalte zwischen
Datenübertragung zum anderen AVR und PC um. 74HC157 ist dein Freund.
MFG
Falk
Hallo
um die Datenübertragung zum PC hinzubekommen habe ich vor die bytes
einfach an IO Ports rauszugeben bzw. einzulesen und diese mit der
parallelen schnittstelle lpt1 zu verbinden und im PC weiter mit Delphi
zu verarbeiten so das ich die Datenübertragung mal zB. 30 min laufen
lassen kann und ne grafische auswertung der fehler machen kann.
Ist das ne gute Idee das über die parallele schnittstelle zu machen?
Hat jemand evtl schonmal sowas gemacht und tips?
Was gibt es da noch für möglichkeiten?
@ Michael Dietz (Firma na) (michaeld)
>Ist das ne gute Idee das über die parallele schnittstelle zu machen?
Nein. Nimm seriell oder besser USB mit virtuellem COM-Port. FTDI232R ist
dein Freund.
MFG
Falk
klappt das ganze auch ohne zusätzliche hardware.
wenn ich das mit dem FTDI232Rrealisiere klappt es mit diesem über die
normalen IO Ports die UARTS sind ja belegt und wollte wenn möglich nicht
mehr soviel hardware draufbauen.
so wie ich das gelesen habe arbeitet der FTDI232R auch nur mit dem Uart
zusammen dann bräuchte ich auch noch en multiplexer dazwischen.
gibte es keine möglichkeit das mit den normalen IO Pins zu regeln ohne
viel zusätzliche Hardware?
@ Michael Dietz (Firma na) (michaeld)
>so wie ich das gelesen habe arbeitet der FTDI232R auch nur mit dem Uart>zusammen dann bräuchte ich auch noch en multiplexer dazwischen.
Ja.
>gibte es keine möglichkeit das mit den normalen IO Pins zu regeln ohne>viel zusätzliche Hardware?
Was bitte ist an einem 16pinnigen IC viel Hardwareaufwand?
MFG
Falk
>Was bitte ist an einem 16pinnigen IC viel Hardwareaufwand?
der 16 pinnige IC!
mein Lehrer meinte ich soll das ganz einfach über die IO Ports lösen von
da aus einfach an die parallele schnittstelle senden und mit delphi
einlesen und auswerten.
Aber da habe ich auch keine ahnung wie ich das synchronisieren soll usw.
also denke ich ist die schnellste Lößung einfach den Atmega164P zu
bestellen da dieser zwei Uarts hat und dann das ganze mit dem FTDI232R
an den PC zu übertragen.
Ist es denn da möglich über einen COM Port (habe nur einen) an den
ersten µC das bitmuster zu senden und das vom zweiten zu empfangen?
Was bietet sich am besten an um das gesendete mit dem empfangenen zu
vergleichen und auszuwerten.
Danke
MfG
en kumpel hat das mit diesem ftdi mal gemacht und er meinte die
übertragung wäre sehr unzuverlässig.
versuche das jetzt mit nem max232 und dem atmega mit 2 hardware uarts.
@ Michael Dietz (Firma na) (michaeld)
>en kumpel hat das mit diesem ftdi mal gemacht und er meinte die>übertragung wäre sehr unzuverlässig.
Dann hat er was falsch gemacht.
>versuche das jetzt mit nem max232 und dem atmega mit 2 hardware uarts.
Meinetwegen.
MFG
Falk
weshalb ist ftdi so viel besser als die daten per max232 die rs232
schnittstell zu senden kann da keinen nachteil erkennen. außer das ich
halt 2 comports brauche.
@ Michael Dietz (Firma na) (michaeld)
>weshalb ist ftdi so viel besser als die daten per max232 die rs232>schnittstell zu senden kann da keinen nachteil erkennen.
Wer sagt denn VIEL besser? Es ist besser, weil die meisten PCs keinen
COM-Port mehr haben.
MfG
Falk
Habe jetzt 2 Atmega 164P hier die haben jeweils zwei uarts.
Habe den Code auch schon soweit angepasst mit hilfe von diesem tutorial.
http://www.atmel.com/dyn/resources/prod_documents/doc8001.pdf
Das Problem ist allerdings das kein interuppt beim empfangen ausgelößt
wird und senden tut er wohl auch nicht habe an der anderen seite noch
den atmega 16 mit dem es schon funktioniert hat aber auf dem atmega 164P
wird nix empfangen und auch nix gesendet.
Außerdem macht der Atmega164P oft Probleme beim beschreiben hab die
fuses BOOTSZ0 und BOOTSZ1 im ponyprog gesetzt.
MfG
uchar Send2WOne()
{
if( !R || !W ) // Checken ob beide Leitungen High Sind
return 0;
R = 0; // Red Leitung Runter gehen
StartTimeout();
while( W && timeout) // Auf Antwort warten
;
if(!timeout) // Zu lange gewartet!
return 0;
R = 1; // Antwort bestätigen & Leitung wieder Freigeben
StartTimeout();
while( !W && timeout) // Auf Freiwerden der Leitung warten.
;
if (!timeout) // Zu lange gewartet.
return 0;
return 1; // Comm Succ
}
uchar Send2WZero()
{
if( !R || !W ) // Checken ob beide Leitungen High sind!
return 0;
W = 0; // White Leitung Runter gehen
StartTimeout();
while( R && timeout ) // Auf Antwort warten
;
if(!timeout) // Zu lange gewartet!
return 0;
W = 1; // Antwort bestätigen & Leitung wieder Freigeben
StartTimeout();
while( !R && timeout ) // Auf Freiwerden der Leitung warten.
;
if(!timeout) // Zu lange gewartet
return 0;
return 1; // Comm Succ
}
kann es sein das sich hier was an der Schaltung ändert normal nicht
oder??
ich kann den Fehler einfach nicht finden.
wäre dankbar wenn jemand noch eine idee hat
@ Michael Dietz (Firma na) (michaeld)
>irgendwie wird der timerinterrupt einfach nicht ausgelöst seit ich den>Atmega164P draufhabe.
Hast du den Controller im AVR-Studio richtig eingestellt?
Hast du die richtigen Pins angeschlossen, dieser AVR hat ja zwei UARTs.
MFG
Falk
Hallo
ja habe alles richtig angeschlossen aber will eigentlich erstmal nur nen
timerinteruppt auslößen aber das klappt nicht.
Im AVR Studio ist er unter: Project -->configuration options richtig
eingestellt (Atmega164P)und die frequenz (4000000Hz)ebenfalls.
Unter: Debug ->Select Plattform and Device ist AVR Simulator und
Atmega164P gewählt.
Unter Pony Prog zum programmieren gibt es nur den Atmega164 aber er
beschreibt ihn mitr "write successful" und die "Configuration und
Security Bits" lassen sich auch lesen und schreiben habe bei denen
BOOTSZ0 und BOOTSZ1 angehackt.
Könnte es sein das an den fusebits etwas nicht stimmt.
den c code (hauptsächlich die registernamen)habe ich nach der migration
pdf geändert.
http://www.atmel.com/dyn/resources/prod_documents/doc8001.pdf
habe den code nochmal anbei.
an den Interrupt befehlen ändert sich nix oder?
MfG
jetzt gehts!!
1.fuse bits bei cksel auf "Full Swing Crystal Oscillator"
2.TCCR0A=0x00; register auf null setzen obwohl es normal standartmäßig
auf 0 sein sollte
Bin jetzt soweit das ich zwischen Atmega und PC Daten übertragen kann
allerdings ist dies sehr fehlerhaft.
ich benutze docklight1.7 um daten zu senden und zu empfangen.
mit hyperterminal geht es nicht weiß nicht warum.
ich lasse die daten die im Mikrocontroller ankommen einfach wieder
zurück schicken aber es kommt nicht immer was zurück und oft auch noch
fehlerhaft.
woran kann das liegen?