Forum: Mikrocontroller und Digitale Elektronik bidirektionale Datenübertragung zwischen 2 Atmega 8


von Michael D. (michaeld)


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

von Michael D. (michaeld)


Lesenswert?

falls es Beispiele geben sollte wäre es gut wenn die in C wären.

von Falk B. (falk)


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

von Michael D. (michaeld)


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 
.

von Philipp B. (philipp_burch)


Lesenswert?

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

von Michael D. (michaeld)


Lesenswert?

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

von Michael D. (michaeld)


Lesenswert?

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

von 1234 (Gast)


Lesenswert?

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.

von Marvin M. (Gast)


Lesenswert?


von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

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

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

muss ich einen extra quarz mit anschließen oder bekommt ein Atmega8 das 
so hin  mit dem Uart..?

von Falk B. (falk)


Lesenswert?

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

von Markus Berent (Gast)


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

von Michael D. (michaeld)


Lesenswert?

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.

von Manni (Gast)


Lesenswert?

@  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

von David M. (md2k7)


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

von Michael D. (michaeld)


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?

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

gibt es programme mit denen man das simulieren kann um zu sehen ob die 
beiden atmnegas tatsächlich daten austauschen?

von Falk B. (falk)


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

von Michael D. (michaeld)


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?

von Falk B. (falk)


Lesenswert?

@ Michael Dietz (Firma na) (michaeld)

>256*16µS=4,096mS ist das die zeit bis zum ersten overflow?

Ja.

MFG
Falk

von Michael D. (michaeld)


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?

von Falk B. (falk)


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

von Michael D. (michaeld)


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?

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

>15625 Hz / 100 Hz = 156,25.

da muss doch noch was davor oder sonst teilt man den takt ja im TCCR0.

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


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
}

von Michael D. (michaeld)


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.

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

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

von Falk B. (falk)


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

von Michael D. (michaeld)


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;

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

demnach sollte das das gleiche sein und es sollte damit auch klappen?

Variablendeklaration:
1
char Sensor_1bis6;


Einlesen:
1
Sensor_1bis6 = PINC;


Senden:
1
UDR=(char)Sensor_1bis6;

von Falk B. (falk)


Lesenswert?

Ahhhh, das Licht geht auf!

MfG
Falk

P.S. Ein Thread reicht dazu.

von Simon K. (simon) Benutzerseite


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.

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


Lesenswert?

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

von jonny (Gast)


Lesenswert?

Grundlagen!

Tx1<->Rx2
RX1<->TX2

Also eine art Crossover!

von Simon K. (simon) Benutzerseite


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.

von Michael D. (michaeld)


Lesenswert?

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?

von Falk B. (falk)


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

von Michael D. (michaeld)


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
      }

von Falk B. (falk)


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

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

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.

von Markus Diefenbach (Gast)


Lesenswert?

Includiere mal das Headerfile "stdint.h" und nutze statt "char" besser 
uint8_t.

von Michael D. (michaeld)


Lesenswert?

muss man die uint8_t so wie die struct deklarieren?
finde dazu irgendwie nix

von Michael D. (michaeld)


Lesenswert?

irgendwie klappts auch so nicht weiß nicht woran das liegen kann

von Michael D. (michaeld)


Lesenswert?

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

von Falk B. (falk)


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

von Michael D. (michaeld)


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.

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

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

von Michael Wilhelm (Gast)


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

von Falk B. (falk)


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

von Michael Wilhelm (Gast)


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

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


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?

von Falk B. (falk)


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

von Michael D. (michaeld)


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?

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

Keramikschwinger/Oszillator statt Quarz/Oszillator??

welcher ist da genauer was hat der keramikschwinger für vorteile außer 
das er keine kondensatoren braucht?

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

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?

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

am Atmega kommt 4,3 Volt an reicht das aus?

von Falk B. (falk)


Lesenswert?

Ja.

von Hatmut Semken (Gast)


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

von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

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.

von Michael D. (michaeld)


Lesenswert?

yeeeeeeeeeeaaaaaaaaaaaahh it works.....verdammte kalte Lötstelle die hat 
mich bestimmt 20 Stunden aufgehalten

von Michael D. (michaeld)


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?

von Michael D. (michaeld)


Lesenswert?

mmhhh habe meine übertragung die vorher funktioniert hat jetzt mit einem 
kabel probiert was ca 30cm lang ist. macht der uart da schon schlapp?

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

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.

von Michael D. (michaeld)


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?

von Falk B. (falk)


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

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

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.

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

2ter code

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

oh habe grad den code gepostet wo ich mit halbduplex probiert habe hier 
nochmal der in vollduplex

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

2ter

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


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.

von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Michael D. (michaeld)


Lesenswert?

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

von Michael D. (michaeld)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

;-)

von Markus Diefenbach (Gast)


Lesenswert?

ich keine Ahnung von CRC...der Falk kann da bestimmt etwas zu sagen.

von Falk B. (falk)


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.

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

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

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

2ter n8

von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Falk B. (falk)


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

von Michael D. (michaeld)


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?

von Michael D. (michaeld)


Lesenswert?

fehler gefunden fuse bit ckopt war nicht gesetzt was ja ab 8MHz gesetzt 
sein sollte

von Michael D. (michaeld)


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

von Falk B. (falk)


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 ;-)

von Michael D. (michaeld)


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
      }

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

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.

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

2ter Code

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


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.

von Michael D. (michaeld)


Lesenswert?

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?

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

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

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

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?

von Falk B. (falk)


Lesenswert?

@ 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

von Falk B. (falk)


Lesenswert?

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

von Michael D. (michaeld)


Lesenswert?

aber die stimmt hab das jetzt nochmal haarklein durchgerechnet.
wo kann denn da noch der fehler liegen

von Michael D. (michaeld)


Lesenswert?

ja hab das alles überprüft richtiges programm in jeweiligem µC und auch 
die richtigen variablen rausgegeben

von Michael D. (michaeld)


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;

von Falk B. (falk)


Angehängte Dateien:

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

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Hier für den anderen

von Michael D. (michaeld)


Lesenswert?

es klappt nice da wäre ich niemals drauf gekommen

von Michael D. (michaeld)


Lesenswert?

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.

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

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.

von Michael D. (michaeld)


Angehängte Dateien:

Lesenswert?

zwei

von Falk B. (falk)


Lesenswert?

Moin,

das musst du auch mal alleine debuggen können. Der Simulator ist dein 
Freund.

MFG
Falk

von Rainer Milenski (Gast)


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.

von Falk B. (falk)


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

von Simon K. (simon) Benutzerseite


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.

von Michael D. (michaeld)


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

von Tobias P. (hubertus)


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.

von Michael D. (michaeld)


Lesenswert?

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.

von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


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

von Michael D. (michaeld)


Lesenswert?

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.

von Falk B. (falk)


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

von Michael D. (michaeld)


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?

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


Lesenswert?

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.

von Michael D. (michaeld)


Lesenswert?

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?

von Falk B. (falk)


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

von Michael D. (michaeld)


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

von Michael D. (michaeld)


Lesenswert?

kennste nen günstigen shop wo ich direkt den atmega164P und den FTDI232R 
in diskreten bauteilen bestellen kann?

von Michael D. (michaeld)


Lesenswert?

das mit dem com port hat sich erledigt der geht ja direkt auf usb..aber 
der kleine ic kostet 7,99eur :( und habe ihn bisher nur in smd gefunden.

von Michael D. (michaeld)


Lesenswert?

http://elmicro.com/de/ft232r.html

das müsste ich mir quasi selber bauen will ja nicht so viel augeben.

von Michael D. (michaeld)


Lesenswert?

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.

von Falk B. (falk)


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

von Michael D. (michaeld)


Lesenswert?

mmhhh ist es deiner meinung nach denn mit dem ftdi die bessere lösung?

von Falk B. (falk)


Lesenswert?

Ja

von Michael D. (michaeld)


Lesenswert?

habe den FTDI232R nur in smd gefunden und wollte keinen fertigen adapter 
holen gibt es die auch als diskrete bauteile für lochplatinen?

von Falk B. (falk)


Lesenswert?

Nein

von Michael D. (michaeld)


Lesenswert?

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.

von Falk B. (falk)


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

von Michael D. (michaeld)


Angehängte Dateien:

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

von Jankey (Gast)


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
}

von Michael D. (michaeld)


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
  }

von Michael D. (michaeld)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@ 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

von Michael D. (michaeld)


Angehängte Dateien:

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

von Michael D. (michaeld)


Lesenswert?

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

von Michael D. (michaeld)


Lesenswert?

so n8 morgen gehts weiter

von Michael D. (michaeld)


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?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.