bidirektionale Datenübertragung zwischen 2 Atmega 8

OP #743566
Lesenswert?

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
#743582
Lesenswert?

@ 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 EINEN AVR, der reicht wahrscheinlich dicke und die Programierung 
wird einfacher.

MFG
Falk
OP #743627
Lesenswert?

>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 
.
#743764
Lesenswert?

@ 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
OP #743782
Lesenswert?

>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
#743807
Lesenswert?

@ 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
OP #743866
Lesenswert?

>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
#743954
Lesenswert?

@ 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
#744060
Lesenswert?

@  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: UART
AVR-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
Gast #744507
Lesenswert?

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...
#744555
Lesenswert?

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
OP #744985
Lesenswert?

>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?
#745012
Lesenswert?

@  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
#746321
Lesenswert?

@ 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
OP #747159
Lesenswert?

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?
OP #747233
Lesenswert?

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?
#747256
Lesenswert?

@ 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-Tutorial
AVR-GCC-Tutorial

MFg
Falk
OP #747275
Lesenswert?

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?
#747283
Lesenswert?

@  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_Interrupts
http://www.mikrocontroller.net/articles/Sleep_Mode#Quarzgenaue_Zeitbasis

MFG
Falk
OP #748945
Lesenswert?

so der timer läuft
1
#include <avr/io.h>   //Bibliotheken(Headerfiles einbinden) 
2
#include <avr/interrupt.h>
3

4
#define F_CPU 16000000UL
5

6
volatile int a=0;
7

8
  ISR ( TIMER0_OVF_vect ) //auslößen des Timerinteruppts
9
  {
10
     
11
   TCNT0  = 100;  // Vorladen  
12
      
13
     a++;  //das gleiche wie a=a+1
14
    if (a >= 500) //500*9,984ms=4,992s
15
    {PORTD |= (1<<PD5);} //led1 setzen
16
  }
17

18
int main (void) 
19
{           
20

21
         DDRD = (1 << DDD5) | (1<<DDD7) | (1<<DDD6); //DDRD 5(Led1) 6(LED2) 7(Summer) als Ausgänge
22
    
23
    // Initialisierung des Timers:
24

25
      TCCR0 |= (1<<CS00)|(0<<CS01)|(1<<CS02); //Quarztakt wird durch 1024 geteilt 16MHz/1024=15625Hz
26

27
      TCNT0  = 100;  // Vorladen  15625Hz/101,16Hz(9,984ms)=156  256-156=100
28

29
      TIMSK |= (1<<TOIE0);  // Interrupts aktivieren und damit Timer starten  
30

31
        sei();  // globale Interrupts zulassen
32

33
 
34
   while(1) { }     //endlosschleife um programm nicht zu beenden                   
35
 
36
   
37
   return 0;       //Rückgabewert an das Betriebssystem (wird nie erreicht wegen while Schleife)          
38
}
OP #750926
Lesenswert?

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
       unsigned char Sens1:1;
3
      unsigned char Sens2:1;
4
      unsigned char Sens3:1;
5
      unsigned char Sens4:1;
6
      unsigned char Sens5:1;
7
      unsigned char Sens6: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:
1
while (!(UCSRA & (1<<UDRE))); 
2
UDR=(struct)a;

habe es auch schon mit
1
 
2
UDR=(char)a;
probiert aber das geht auch nicht.
#750948
Lesenswert?

@ 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
#750999
Lesenswert?

@ 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
OP #751013
Lesenswert?

Damit hat es jetzt funktioniert heißt das jetzt das meine Variable 
größer als ein Byte ist?

Variablendeklaration:
1
union{
2
    struct {
3
       unsigned char Sens1:1;
4
      unsigned char Sens2:1;
5
      unsigned char Sens3:1;
6
      unsigned char Sens4:1;
7
      unsigned char Sens5:1;
8
      unsigned char Sens6:1;
9
       }a;
10
      char a1;
11
       } Byte1;

Einlesen:
1
Byte1.a.Sens1 = PINC & (1<<PINC0);
2
      Byte1.a.Sens2 = PINC & (1<<PINC1);
3
      Byte1.a.Sens3 = PINC & (1<<PINC2);
4
      Byte1.a.Sens4 = PINC & (1<<PINC3);
5
      Byte1.a.Sens5 = PINC & (1<<PINC4);
6
      Byte1.a.Sens6 = PINC & (1<<PINC5);

Senden:
1
UDR=Byte1.a1;
#751018
Lesenswert?

@ 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
Persönliche Seite #751036
Lesenswert?

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.
Persönliche Seite #753602
Lesenswert?

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.
#753609
Lesenswert?

@  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
OP #753682
Lesenswert?

ok dann hier mal die codes für den 1. µC und für den 2.µC

µC1 sender:
1
#include <avr/io.h>   //Bibliotheken(Headerfiles einbinden) 
2
#include <avr/interrupt.h>
3

4
#define F_CPU 16000000UL
5

6
#define BAUD       9600UL
7
#define UBRR_WERT   ((F_CPU/(16UL*BAUD))-1) //16MHz/((16UL*9600UL)-1)= 104,16
8

9
  //Variablendeklaration
10
  char Sensor_1bis6;
11

12

13

14
int main (void) 
15
{           
16

17
      DDRA = 0x00;          //Datenrichtungsregister A alles 0 (Eingänge) Sensoren      
18

19
           init_uart(UBRR_WERT); //Aufruf von uartinitialisierung übergabe von UBRR_Wert
20

21
      init_timer(); //Aufruf von timerinitialisierung
22

23
        sei();  // globale Interrupts zulassen
24

25
 
26
   while(1) { }     //endlosschleife um programm nicht zu beenden                   
27
   return 0;       //Rückgabewert an das Betriebssystem (wird nie erreicht wegen while Schleife)          
28
}
29

30
    void init_timer(void)
31
      {
32

33
      // Initialisierung des Timers:
34

35
      TCCR0 |= (1<<CS00)|(0<<CS01)|(1<<CS02); //Quarztakt wird durch 1024 geteilt 16MHz/1024=15625Hz
36

37
      TCNT0  = 100;  // Vorladen  15625Hz/101,16Hz(9,984ms)=156  256-156=100
38

39
      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
    void init_uart(unsigned int ubrr) 
61
      {                //nur ein register(8Bit) vorhanden deswegen
62
          UBRRH = (unsigned char)(ubrr>>8);//die ersten 8 Bit einlesen und um 8 nach rechts verschieben
63
          UBRRL = (unsigned char)(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, 
68
                                  //8Bit werden für Datenübertragung benutzt
69
      }

µC2 empfänger:
1
#include <avr/io.h>   //Bibliotheken(Headerfiles einbinden) 
2
#include <avr/interrupt.h>
3

4
#define F_CPU 16000000UL
5

6
#define BAUD       9600UL
7
#define UBRR_WERT   ((F_CPU/(16UL*BAUD))-1) //16MHz/((16UL*9600UL)-1)= 104,16
8

9
  //Variablendeklaration
10
  char Aktor_1bis6;
11

12

13

14
int main (void) 
15
{           
16

17
      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
   return 0;       //Rückgabewert an das Betriebssystem (wird nie erreicht wegen while Schleife)          
28
}
29
      
30
      
31

32
    void init_uart(unsigned int ubrr) 
33
      {                //nur ein register(8Bit) vorhanden deswegen
34
          UBRRH = (unsigned char)(ubrr>>8);//die ersten 8 Bit einlesen und um 8 nach rechts verschieben
35
          UBRRL = (unsigned char)(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
44
      {        //das empfangene byte wird im UDR gespeichert
45
      // Empfangsregister auslesen
46
          Aktor_1bis6= UDR;
47
      //Werte an Aktoren ausgeben
48
      PINA=Aktor_1bis6;
49
      }
#753700
Lesenswert?

@  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
#754850
Lesenswert?

@ 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
OP #755223
Lesenswert?

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.
#755253
Lesenswert?

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

>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
#755344
Lesenswert?

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

@ 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
OP #755401
Lesenswert?

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?
#755439
Lesenswert?

@ 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
OP #756295
Lesenswert?

>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?
#756321
Lesenswert?

@ 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
#757665
Lesenswert?

@ 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
#759013
Lesenswert?

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

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
#759148
Lesenswert?

@ 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
OP #759595
Lesenswert?

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
OP #760580
Lesenswert?

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?
#760755
Lesenswert?

@  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
OP #760948
Lesenswert?

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?
#761165
Lesenswert?

@ 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
OP #761291
Lesenswert?

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.
#761295
Lesenswert?

@ 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
OP #761327
Lesenswert?

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
#761349
Lesenswert?

@ 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.
#761797
Lesenswert?

@ 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.

1
      if ((rx_data & 0xC0) == 0xC0)

MfG
Falk
OP #762115
Lesenswert?

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
#762231
Lesenswert?

@ 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
OP #762538
Lesenswert?

die UART einstellungen sind komplett identisch:
1
#define F_CPU 16000000UL
2

3
   #define BAUD       9600UL
4
   #define UBRR_WERT   ((F_CPU/(16UL*BAUD))-1)
5

6
   UBRRH = (unsigned char)(ubrr>>8);              
7
   UBRRL = (unsigned char)(ubrr);               
8
   UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);              
9
   UCSRC = (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);

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?
OP #762587
Lesenswert?

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
#762685
Lesenswert?

@ 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
  case 0: sensor_1bis6=tmp; break;
9
  case 1: sensor_1bis6_negiert=tmp; break;
10
  case 2: sensor_7bis12= tmp; break;
11
  case 3: 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 ;-)
OP #764300
Lesenswert?

Hallo so klappt das nicht
Sender:
1
ISR (TIMER0_OVF_vect)
2
      
3
    {
4
      TCNT0  = 100;
5

6

7
        //Einlesen
8
        Sensor_1bis6 = ~PINC;
9
          negiert_Sensor_1bis6 = ~Sensor_1bis6;
10
        Sensor_7bis12 = ~PINB;
11
        negiert_Sensor_7bis12 = ~Sensor_7bis12;
12
        
13
        //Aufbereiten
14
        Sensor_1bis6 &= ~(0xC0);          // Bits 6 & 7 loeschen 00 am höchstwertigem Bit
15
        
16
        
17
        negiert_Sensor_7bis12    |=  (0xC0);    // Bits 6 & 7 setzen   11 am höchstwertigem Bit
18

19
        Sensor_7bis12 &= ~(0xC0);        // Bit 6 7 löschen 00
20
                Sensor_7bis12 |= (0x80);        // Bit 7  setzen   10
21
            
22
        negiert_Sensor_1bis6 &= ~(0xC0);    // Bit 6 7 löschen 00
23
                negiert_Sensor_1bis6 |= (0x40);      // Bit 6  setzen   01
24

25

26
         while (!(UCSRA & (1<<UDRE)));         // warten bis Senden moeglich (bis Sendepuffer frei ist)
27
         
28
           UDR=Sensor_1bis6;          //Sensor_1bis6;//Daten in den Puffer schreiben und damit senden  00
29
        
30
        while (!(UCSRA & (1<<UDRE)));
31

32
          UDR=negiert_Sensor_1bis6;           //01
33
         
34
        while (!(UCSRA & (1<<UDRE)));
35

36
          UDR=Sensor_7bis12;             //10       
37

38
        while (!(UCSRA & (1<<UDRE)));
39

40
          UDR=negiert_Sensor_7bis12;            //
41
  
42
      }
Empfänger:
1
ISR(USART_RXC_vect)     //Empfangsinteruppt wird ausgelößt sobald ein Byte empfangen wurde
2
    {
3
      rx_data = UDR;
4
          code = rx_data >> 6;   //schreibt die  Prüfbits in code
5
          rx_data &= ~0xC0;
6

7
      switch (code) 
8
      {
9
          case 0: SPS_in1bis6 =   rx_data; break;     //00? ja-->schreibe niedrigsten 6 Bits 
10
          case 1: negiert1bis6 =  rx_data; break;    //01
11
          case 2: SPS_in7bis12 =  rx_data; break;     //10
12
          case 3: negiert7bis12 = rx_data;      //11
13
          
14
          if (SPS_in1bis6 == ((~negiert1bis6) & ~0xC0))
15
                PORTA = SPS_in1bis6;
16

17
              if (SPS_in7bis12 == ((~negiert7bis12) & ~0xC0))
18
          PORTB = SPS_in7bis12;
19
              break;
20
      }
OP #764724
Lesenswert?

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.
#764808
Lesenswert?

@ 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
#765227
Lesenswert?

@ 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
OP #765291
Lesenswert?

wenn ich die beiden if abfragen rausnehme gibt er alle richtig aus
1
ISR(USART_RXC_vect)     //Empfangsinteruppt wird ausgelößt sobald ein Byte empfangen wurde
2
    {
3
      rx_data = UDR;
4
          code = rx_data >> 6;   //schreibt die  Prüfbits in code
5
          rx_data &= ~0xC0;
6

7
      switch (code) 
8
      {
9
          case 0: SPS_in1bis6  =   rx_data;  break;     //00? ja-->schreibe niedrigsten 6 Bits 
10
          case 1: negiert1bis6 =  rx_data; break;    //01
11
          case 2: SPS_in7bis12 =  rx_data;  break;     //10
12
          case 3: negiert7bis12 = rx_data;      //11
13
          
14
          //if (SPS_in1bis6 == ((~negiert1bis6) & ~0xC0))
15
                PORTA = SPS_in1bis6;
16

17
              //if (SPS_in7bis12 == ((~negiert7bis12) & ~0xC0))
18
          PORTB = SPS_in7bis12;
#765308
Lesenswert?

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
Angehängte Dateien:
Gast #765915
Lesenswert?

@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.
#766201
Lesenswert?

@ 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
Persönliche Seite #766210
Lesenswert?

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.
OP #766679
Lesenswert?

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
2
    {
3
     
4
       TCNT0  = 178;            // Timer Vorladen  
5
      
6
      //Einlesen
7
      tx_data = ~PINC;
8
      
9
      SPS_out_1bis4 = tx_data & 0x0F;        //löscht höchsten 4 Bits
10

11
      SPS_out_5bis8 = tx_data >> 4;             //schiebt die höchsten 4 Bits an niedrigsten 4 Stellen in SPS_out_1bis4
12
      
13
      SPS_out_1bis4_negiert = ~SPS_out_1bis4;
14
      SPS_out_5bis8_negiert = ~SPS_out_5bis8;
15

16
      //Aufbereiten
17
      SPS_out_1bis4 &= ~0xC0;          // Bits 6,7 loeschen 00 am höchstwertigem Bit
18

19
      SPS_out_1bis4_negiert &= ~0xC0;    // Bit 6,7 löschen 00
20
            SPS_out_1bis4_negiert |= 0x40;    // Bit 6  setzen   01
21
        
22
      SPS_out_5bis8 &= ~0xC0;        // Bit 6,7 löschen 00
23
            SPS_out_5bis8 |= 0x80;        // Bit 7  setzen   10
24

25
      SPS_out_5bis8_negiert |= 0xC0;      // Bits 6 & 7 setzen   11 am höchstwertigem Bit
26

27

28
      //Senden
29
         while (!(UCSRA & (1<<UDRE)));       // warten bis Senden moeglich (bis Sendepuffer frei ist)
30
         
31
           UDR = SPS_out_1bis4;      //Daten in den Puffer schreiben und damit senden  00
32
        
33
        while (!(UCSRA & (1<<UDRE)));
34

35
          UDR = SPS_out_1bis4_negiert;        
36
         
37
        while (!(UCSRA & (1<<UDRE)));
38

39
          UDR = SPS_out_5bis8;             
40

41
        while (!(UCSRA & (1<<UDRE)));
42

43
          UDR = SPS_out_5bis8_negiert;          
44

45
    }

empfänger:
1
ISR(USART_RXC_vect)   //Empfangsinteruppt wird ausgelößt sobald ein Byte empfangen wurde
2
    {          //das empfangene byte wird im UDR gespeichert
3
                // Empfangsregister auslesen und zu register A geben
4
           rx_data = UDR;
5
          code = rx_data >> 6;   //schreibt die  Prüfbits in code
6
          //rx_data &= ~0xC0;
7

8
        switch (code) 
9
        {
10
            case 0: Aktor_1bis4      = rx_data;  break;     //00? ja-->schreibe niedrigsten 6 Bits 
11
            case 1: Aktor_1bis4_negiert = rx_data;   break;    //01
12
            case 2: Aktor_5bis8     = rx_data;  break;     //10
13
            case 3: Aktor_5bis8_negiert = rx_data;          //11
14
        
15

16
                  Aktor_5bis8 = Aktor_5bis8 << 4;                      //schiebt niedrigsten 4 Bits an 4 höchsten stellen
17

18
          Aktor_1bis8 = (Aktor_1bis4 | Aktor_5bis8);
19

20
          //PORTA = Aktor_1bis8;
21

22
          Aktor_5bis8_negiert = Aktor_5bis8_negiert << 4;
23

24
          Aktor_1bis8_negiert = (Aktor_1bis4_negiert | Aktor_5bis8_negiert);
25
          PORTA = Aktor_1bis8_negiert;
26
            //if (Aktor_1bis8 == ~Aktor_1bis8_negiert)
27
                  //PORTA = Aktor_1bis8;
28
              
29
        
30
          break; 
31
          }
32

33
      
34
      
35
    }



SPS_Out beim sender entspricht Aktor beim Empfänger
#766690
Lesenswert?

@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.
#766844
Lesenswert?

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
3
Das empfangene Byte wird im UDR gespeichert
4
Empfangsregister auslesen und an PORTA ausgeben
5
*/
6
ISR(USART_RXC_vect) {
7
    uint8_t rx_data, code;
8
    static uint8_t Aktor_1bis4, Aktor_1bis4_negiert, Aktor_5bis8, Aktor_5bis8_negiert;
9

10
    rx_data = UDR;
11
    code = rx_data >> 6;   //schreibt die  Prüfbits in code
12
    rx_data &= 0x0F;
13

14
    switch (code) {
15
        case 0: Aktor_1bis4         = rx_data;  break;     //00? ja-->schreibe niedrigsten 6 Bits 
16
        case 1: Aktor_1bis4_negiert = rx_data;  break;     //01
17
        case 2: Aktor_5bis8         = rx_data;  break;     //10
18
        case 3: Aktor_5bis8_negiert = rx_data;             //11   
19
 
20
                Aktor_1bis4 |= (Aktor_5bis8 << 4);
21
                Aktor_1bis4_negiert |= (Aktor_5bis8_negiert << 4);
22
                if (Aktor_1bis4 == ~Aktor_1bis4_negiert)
23
                  PORTA = Aktor_1bis4;
24
                break; 
25
    }

MFG
Falk
OP #767402
Lesenswert?

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
#767433
Lesenswert?

@  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
3
Das empfangene Byte wird im UDR gespeichert
4
Empfangsregister auslesen und an PORTA ausgeben
5
*/
6
ISR(USART_RXC_vect) {
7
    uint8_t rx_data, code;
8
    static uint8_t Aktor_1bis4, Aktor_1bis4_negiert, Aktor_5bis8, Aktor_5bis8_negiert;
9

10
    rx_data = UDR;
11
    code = rx_data >> 6;   //schreibt die  Prüfbits in code
12
    rx_data &= 0x0F;
13

14
    switch (code) {
15
        case 0: Aktor_1bis4         = rx_data;  break;     //00? ja-->schreibe niedrigsten 6 Bits 
16
        case 1: Aktor_1bis4_negiert = rx_data;  break;     //01
17
        case 2: Aktor_5bis8         = rx_data;  break;     //10
18
        case 3: Aktor_5bis8_negiert = rx_data;             //11   
19
 
20
                Aktor_1bis4 |= (Aktor_5bis8 << 4);
21
                Aktor_1bis4_negiert |= (Aktor_5bis8_negiert << 4);
22
                if ((uint8_t)Aktor_1bis4 == (uint8_t)~Aktor_1bis4_negiert)
23
                  PORTA = Aktor_1bis4;
24
                break; 
25
    }

Mfg
Falk
OP #767894
Lesenswert?

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
OP #768608
Lesenswert?

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..?
#768617
Lesenswert?

@ 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
OP #776166
Lesenswert?

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?
#776199
Lesenswert?

@ 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
OP #776220
Lesenswert?

>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
#777013
Lesenswert?

@ 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
#777361
Lesenswert?

@  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
OP #785902
Lesenswert?

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
Angehängte Dateien:
Gast #786041
Lesenswert?

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
}
OP #788512
Lesenswert?

mmmhhhhh?

irgendwie wird der timerinterrupt einfach nicht ausgelöst seit ich den 
Atmega164P draufhabe.

hier mal der code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4

5
#define F_CPU 4000000UL
6

7

8
int a=0;
9

10
    void init_timer(void)
11
  {
12

13
      //Initialisierung des Timers:
14

15
      TCCR0A |= (0<<CS00)|(0<<CS01)|(1<<CS02);      //Quarztakt wird durch 256 geteilt 4MHz/1024=15625Hz
16

17
      TCNT0  = 178;                   // Vorladen  15625Hz/200,Hz(5ms)=78,125  256-78,125=178
18

19
      TIMSK0 |= (1<<TOIE0);                  // Interrupts aktivieren und damit Timer starten  
20

21
  }
22

23

24
  ISR (TIMER0_OVF_vect)  
25
      
26
    {
27
      TCNT0  = 178;
28

29
      a++;
30
      if (a>3000)//30sekunde
31
      {
32
      PORTA |= (1<<PA0); 
33
      }
34
      }
35

36
  int main (void) 
37
  {           
38

39

40
      DDRA = 0xFF;      
41
      
42
      
43

44
          
45

46
      init_timer();       //Aufruf von timerinitialisierung
47

48
        sei();          // globale Interrupts zulassen
49

50
 
51
       while(1) { }                   //endlosschleife um programm nicht zu beenden                   
52
       return 0;                       //Rückgabewert an das Betriebssystem (wird nie erreicht wegen while Schleife)    
53
      
54
  }
OP #789939
Lesenswert?

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
Angehängte Dateien:
OP #793251
Lesenswert?

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?

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