Forum: Mikrocontroller und Digitale Elektronik mehrere AVR synchron laufen lassen


von jar (Gast)


Lesenswert?

hallo,

für ein kleines Projekt sollen 4 AVR syncron laufen

normalerweise nutze ich Quarze mit 22p
es gibt aber auch TTL Generatoren und die Betriebsart Takt in ?

also sollte doch 4 AVR mit einem TTL Taktgeber und einem gemeinsamen 
RESET Controller 7705 genügen um die im Gleichschritt marschieren zu 
lassen, wobei 1 Takt Abweichung nix tut

ist das richtig so ?

von Falk B. (falk)


Lesenswert?

@  jar (Gast)

>normalerweise nutze ich Quarze mit 22p
>es gibt aber auch TTL Generatoren und die Betriebsart Takt in ?

Externer Takt heißt das beim AVR.

>also sollte doch 4 AVR mit einem TTL Taktgeber und einem gemeinsamen
>RESET Controller 7705 genügen um die im Gleichschritt marschieren zu
>lassen, wobei 1 Takt Abweichung nix tut

Könnte klappen. Muss man die Fuses passend einstellen, damit keine 
Resetverzögerung aktiv ist. Aber warum willst du das machen?

von UR-Schmitt (Gast)


Lesenswert?

Wenn ich das richtig im Kopf habe wird nach einem Reset immer ein 
Bereich von bis XX Takte angegeben bis der Controller anfängt zu 
arbeiten. Dann würde das so nicht gehen.
Die Frage ist wie immer WAS willst du erreichen? Warum sollen die 
Taktsynchron sein?
Meistens findet sich dann das die angedachte Lösung gar nicht notwendig 
oder suboptimal ist.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

UR-Schmitt schrieb:
> wird nach einem Reset immer ein
> Bereich von bis XX Takte angegeben bis der Controller anfängt zu
> arbeiten.

Wobei diese Takte vom internen Watchdog-Oszillator gezählt werden,
da es ja das Ansinnen ist zu warten, bis der Hauptoszillator stabil
läuft.

von spess53 (Gast)


Lesenswert?

Hi

>also sollte doch 4 AVR mit einem TTL Taktgeber und einem gemeinsamen
>RESET Controller 7705 genügen um die im Gleichschritt marschieren zu
>lassen, wobei 1 Takt Abweichung nix tut

Nicht unbedingt. Das Start-Up-delay nach dem Reset ist vom der der 
Frequenz des Watchdogoszillators abhängig. Müsste man mal überprüfen wie 
genau der ist.

MfG Spess

von Falk B. (falk)


Lesenswert?

@  spess53 (Gast)

>Nicht unbedingt. Das Start-Up-delay nach dem Reset ist vom der der
>Frequenz des Watchdogoszillators abhängig.

Das kann man per Fuses abschalten.

von spess53 (Gast)


Lesenswert?

Hi

>Das kann man per Fuses abschalten.

Das ist unabhängig ob der Watchdog eingeschaltet ist. Das Delay wird von 
Watchdogoszillator abgeleitet.

MfG Spess

von Falk B. (falk)


Lesenswert?

Man kann den Delay nach dem Reset abschalten!

von spess53 (Gast)


Lesenswert?

Hi

>Man kann den Delay nach dem Reset abschalten!

Aber nur sinnvoll, wenn der externe Takt zu dem Zeitpunkt wirklich 
stabil ist.

Es ging mir eigentlich darum, dem TO zu sagen, das da noch andere 
Aspekte zu beachten sind.

MfG Spess

von Falk B. (falk)


Lesenswert?

@  spess53 (Gast)

>>Man kann den Delay nach dem Reset abschalten!

>Aber nur sinnvoll, wenn der externe Takt zu dem Zeitpunkt wirklich
>stabil ist.

Er will alle vier AVRs mit einem Oszillator speisen, der ist dann 
stabil.

von spess53 (Gast)


Lesenswert?

Hi

>Er will alle vier AVRs mit einem Oszillator speisen, der ist dann
>stabil.

Der muss auch irgend wann mal einschwingen.

MfG Spess

von Falk B. (falk)


Lesenswert?

@  spess53 (Gast)

>>Er will alle vier AVRs mit einem Oszillator speisen, der ist dann
>>stabil.

>Der muss auch irgend wann mal einschwingen.

Man kann auch einfach mal aufhören, "Argumente" aus der Nase zu ziehen 
und einfach OK sagen. Lies mal den OP.

von dfgh (Gast)


Lesenswert?

Man kann ja auch einfach die µC auf einander warten lassen, dann macht 
das delay nix aus...

von Joachim B. (jar)


Lesenswert?

danke falk,

spess53 schrieb:
> Der muss auch irgend wann mal einschwingen.

ja und ? ich kann den 7705 Resetcontroller auf 100ms oder 500ms 
programmieren, wenn da nix eingeschwungen ist weiss ich auch nicht......
wie gesagt 1-2 Takte Abweichung bei 18,xxx MHz (wegen Baudrate 115k) = 
ca. 100 ns macht gar nix ! es geht nur um die zeitlich nahe AD Wandlung 
von Signalen und da die Wandlung eher in den ms Bereich geht sind 100ns 
Taktverschiebung der einzelnen egal

also kann das klappen wie ich mir das denke ?

warum das so sein soll ( 4x synchron) hat mir mein Vorreiter noch nicht 
veraten :-)

von Joachim B. (jar)


Lesenswert?

dfgh schrieb:
> Man kann ja auch einfach die µC auf einander warten lassen, dann macht
> das delay nix aus...

nun ja gute Idee, aber das ruft mit Sicherheit eine vermutlich größere 
Taktabweichung hervor, zusätzliche  Sync Befehle die pollen ?

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>ca. 100 ns macht gar nix ! es geht nur um die zeitlich nahe AD Wandlung
>von Signalen und da die Wandlung eher in den ms Bereich geht sind 100ns
>Taktverschiebung der einzelnen egal

Dann braucht man auch keine vier AVRs.

>also kann das klappen wie ich mir das denke ?

Ja.

>warum das so sein soll ( 4x synchron) hat mir mein Vorreiter noch nicht
>veraten :-)

Wahrscheinlich ist er auf dem Holzweg. Ehe ich vier AVRs so "parallel" 
laufen lassen würde, würde ich was ganz anderes machen. Größerer uC, 
Hardware, etc. Denn was glaubst du, wie lange die exakt gleich laufen? 
Selbst wenn das identische Programm drin läuft, was soll das bringen?

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Externer Takt heißt das beim AVR.

schon richtig, ich wollte nur unterscheiden zwischen Quarz am XTAL1 und 
XTAL2 gegen TTL In an einem Eingang, die Betriebsarten scheinen mir doch 
verschieden ;-)

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Wahrscheinlich ist er auf dem Holzweg. Ehe ich vier AVRs so "parallel"
> laufen lassen würde, würde ich was ganz anderes machen. Größerer uC,
> Hardware, etc. Denn was glaubst du, wie lange die exakt gleich laufen?
> Selbst wenn das identische Programm drin läuft, was soll das bringen?

das mit dem Holzweg befürchte ich auch, nur warum die voneinander 
wegdriften sollen bei einem Taktgenerator ist mir nicht klar, was mir 
klar ist, die AD Wandlung wird getriggert an einem AVR Pin und nach 
definierter Zeit (delay) beginnt die Wandlung

4 AVR 4 Triggereingänge 4 AD Wandlungen 4 RS232 out

durch die Eingangstriggerung ist eigendlich für mein Verständnis kein 
syncroner Betrieb nötig, aber ich kenne ja nicht das Gesamtkonzept, ich 
weiss nur das der "Planer" mächtig schwimmt upps

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>das mit dem Holzweg befürchte ich auch, nur warum die voneinander
>wegdriften sollen bei einem Taktgenerator ist mir nicht klar,

Per Software. Wenn IDENTISCHE Programme laufen und alle Eingänge 
parallel angeklemmt sind, geht es. Aber der Sinn ist begrenzt.

> was mir
>klar ist, die AD Wandlung wird getriggert an einem AVR Pin und nach
>definierter Zeit (delay) beginnt die Wandlung

>4 AVR 4 Triggereingänge 4 AD Wandlungen 4 RS232 out

Das kann EIN AVR einfacher und besser, wenn es sein muss per externem 
ADC.

>durch die Eingangstriggerung ist eigendlich für mein Verständnis kein
>syncroner Betrieb nötig,

Eben. Nomen est Omen.

> aber ich kenne ja nicht das Gesamtkonzept, ich
> weiss nur das der "Planer" mächtig schwimmt upps

Na dann mal viel Spaß beim Umsetzen dieses "Konzepts".

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> durch die Eingangstriggerung ist eigendlich für mein Verständnis kein
> syncroner Betrieb nötig, [...]

Eben. Also ist das vollkommener Blödsinn, die 4 AVR's synchron laufen zu 
lassen.

von Peter D. (peda)


Lesenswert?

Ich würde einen als Master laufen lassen mit einem PWM-Ausgang.
Und die anderen lesen den mit Input-Capture ein.
Damit kriegt man ein Abweichung von max einem CPU-Zyklus auf allen AVRs 
hin.


Peter

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> Per Software. Wenn IDENTISCHE Programme laufen und alle Eingänge
> parallel angeklemmt sind, geht es.
Nein. Das geht GARANTIERT niemals.
Denn wenn z.B. 1 Eingang parallel auf alle 4 uC gelegt wurde, und sich 
dieser eine Eingang genau bei einer steigenden Flanke ändert, dann sehen 
evtl. 3 uC schon den "neuen" Pegel und 1 uC sieht noch den alten Pegel. 
Und schon laufen die Programme nicht mehr synchron...  :-o

Es geht bestenfalls dann, wenn alle beteiligten Rechner zum selben 
Zeitpunkt das selbe Prozessabbild bekommen. Das ist ein uraltes 
Problem, bei FPGAs bekannt als "Einsynchronisieren".

Der Effekt ist dort beschrieben:
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html
Im hierher übertragenen Sinne wären A und B die beiden uC...

von Falk B. (falk)


Lesenswert?

@  Lothar Miller (lkmiller) (Moderator) Benutzerseite

>> Per Software. Wenn IDENTISCHE Programme laufen und alle Eingänge
>> parallel angeklemmt sind, geht es.
>Nein. Das geht GARANTIERT niemals.
>Denn wenn z.B. 1 Eingang parallel auf alle 4 uC gelegt wurde, und sich
>dieser eine Eingang genau bei einer steigenden Flanke ändert, dann sehen
>evtl. 3 uC schon den "neuen" Pegel und 1 uC sieht noch den alten Pegel.
>Und schon laufen die Programme nicht mehr synchron...  :-o

Du alter Sychronisator, hast natürlich Recht ;-)

von UR-Schmitt (Gast)


Lesenswert?

Womit wir immer noch am Anfang sind:
Was soll erreicht werden? Wie auch immer es ist zu 95% so nicht die 
beste Lösung.

von Joachim B. (jar)


Lesenswert?

Peter Dannegger schrieb:
> Ich würde einen als Master laufen lassen mit einem PWM-Ausgang.
> Und die anderen lesen den mit Input-Capture ein.
> Damit kriegt man ein Abweichung von max einem CPU-Zyklus auf allen AVRs
> hin.

puh ja, aber Mittelknappheit, Fertigung für mehrere gleichartige 
Baugruppen, spricht schon für 4- n gleichartige BG

größerer Controller ? alle AVR enden bei 20 MHz
der Trigger kommt alle 10ms, ich habe momentan reine 
Interruptprgrammierung gemacht, nach dem Trigger läuft alles in der ISR 
linear ab, die main loop ist leer, das letzte RS232 bit ist 5ms nach dem 
Trigger raus, also genug Sicherheitsabstand zum nächsten Trigger, alles 
in C, in Assembler dauert mir die Entwicklung zu lange, meine 
Assemblerzeiten liegen fast 30 Jahre zurück, da müsste ich praktisch von 
vorne anfangen

also 4 Wandlungen innerhalb dieser Zeitvorgaben schaffe ich nicht mit 
einem AVR, deswegen ja 4x, das bissl HW kostet vermutlich weniger als 
noch ewig zu planen, ARM, andere Umgebung, Progger, ASM usw. zumal die 
Zeit knapp ist, das sollte schon seit einer Woche laufen, hatte nur 
Urlaub und dann muss ich ja noch eagle, LP Fertigung, 
Frontplattenfertigung unter einen Hut bringen

übrigens, @peter, wir hatten schon mal telefoniert, aber du hast dich 
unsichtbar gemacht, wurde vermutlich zuviel mit den Anrufen, ich 
versuche immer noch deine "genialen" Programme zu durchschauen 
(Entprellung) (DCF77) 1wire, das schluckt für mich auch viel Zeit, so 
gut bin ich halt nicht.....

deine 1wire quält mich gerade, 1-8 DS18B20 bus powered kurz angebunden 
klappen, an einer Tel Leitung 10-30m schon mit 2en nur noch Short ERRORs 
wobei ich das Zusammenspiel mit I/O noch verstehen muss, wo genau da die 
Wartezeiten oder längeren Pausen, bedingt durch die Kabelkapzität, rein 
gehören

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>größerer Controller ? alle AVR enden bei 20 MHz

Reicht das nicht?

>der Trigger kommt alle 10ms,

Und da sollen vier ADC-Kanäle gemessen werden? Was macht der AVR die 
restlichen 9ms?

> ich habe momentan reine
>Interruptprgrammierung gemacht, nach dem Trigger läuft alles in der ISR
>linear ab, die main loop ist leer, das letzte RS232 bit ist 5ms nach dem
>Trigger raus, also genug Sicherheitsabstand zum nächsten Trigger, alles
>in C,

Was kein Problem ist.

> in Assembler dauert mir die Entwicklung zu lange, meine
>Assemblerzeiten liegen fast 30 Jahre zurück, da müsste ich praktisch von
>vorne anfangen

Wäre auch vollkommen unsinnig.

>also 4 Wandlungen innerhalb dieser Zeitvorgaben schaffe ich nicht mit
>einem AVR,

Dann machst du was falsch. Der AVR gähnt dabei nur. GÄÄÄÄÄÄHN

> deswegen ja 4x, das bissl HW kostet vermutlich weniger als
>noch ewig zu planen,

Oder mal das kleine 1x1 der Programmierung zu lernen Augenroll

>(Entprellung) (DCF77) 1wire, das schluckt für mich auch viel Zeit, so
>gut bin ich halt nicht.....

Dann musst du weiter lernen und besser werden.

Zu deinem "Problem". Der AVR-ADC kann bei voller 10 Bit Auflösung mit 
bis zu 200kHz/13~15kHz sampeln, macht bei vier Messwerten um die 270µs 
Messdauer. Wenn man die dann mit 115k2 Baud rausschickt, braucht man 
nochmal schlappe 700µs (16 Bit/Messwert), macht in Summe knapp 1ms. 
Naja, nicht schlecht geschätzt. Das kann man alles einfach linear so in 
die ISR schreiben.

Poste deinen Code als Anhang und lass dich beraten. Dein Fett kriegst du 
dabei auch weg ;-)

von Pako (Gast)


Lesenswert?

Warum müssen denn die AVRs überhaupt taktsynchron laufen?
Reicht es nicht, wenn man ein gemeinsames "jetzt samplen"-Signal an alle 
vier legt, damit sie interruptgetriggert die ADC-Wandlung starten?
Einer könnte als "Master" das Signal erzeugen, aber seine eigene 
Wandlung auf die gleiche Weise triggern lassen wie die anderen auch.

von UR-Schmitt (Gast)


Lesenswert?

Alles im Interrupt? Du wartest dort hoffentlich nicht bis der UART ein 
Zeichen gesendet hat oder so ähnlich?
Junge, wenn du 400 Messwerte messen und übertragn nicht schaffst, dann 
wird das synchronisieren von 4 µCs für dich das totals Fiasko.
Allein der Ansatz
WENN wohlgemerkt wenn das nicht reichen würde,
dann würe es doch viel einfacher wenn die 4 µCs auf einem Post auf jeden 
Triggerimpuls warten würden und sich so jedes mal neu synchronisieren, 
statt diese seltsame Lösung sie synchron starten zu lassen.
Aber das geht in einem µC, zumindest wenn die Messwerte um 50 - 100µs 
versetzt gesampelt werden dürfen.

von Karl H. (kbuchegg)


Lesenswert?

Pako schrieb:
> Warum müssen denn die AVRs überhaupt taktsynchron laufen?

Weil derjenige, der das designed hat, wieder mal geglaubt hat wahnsinnig 
clever zu sein und 4 µC zu verbauen, wo es einer alleine auch tut.

Das mit mehreren µC (ohne Not eingesetzt) alles noch komplizierter wird, 
wusste er nicht. Er hat halt irgendwo das Schlagwort 'Multiprozessor' 
oder vielleicht sogar 'mehrere Rechenkerne' gehört und dachte sich: 
Geeeiiiiil, will haben.
Was er sich damit eingebrockt hat, konnte er allerdings mangels Wissen 
nicht abschätzen.

von UR-Schmitt (Gast)


Lesenswert?

Sorry für die Rechtschreibfehler, habe anscheinend gerade einen Knoten 
im Finger.

von Karl H. (kbuchegg)


Lesenswert?

Nur mal interesse halber.
Was hat sich dein Vorgänger eigentlich ausgedacht, um die 4 einzelnen 
RS232 wieder zusammenzuführen?

von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

OK, die Mittelwertbildung hat sich als genügend brauchbar 
herausgestellt, ob das nötig ist kann ich nicht testen, ich bin auch 
weit weg vom Einsatzort und mir fehlen die Messmittel, dieses hier läuft 
eben lt. Aussagen genügend genau, die Wartezeiten sind ebenfalls 
vorgaben

im ersten Anlauf sollte der AVR kürzest möglich mit einer fallenden 
Flanke auf den Trigger reagieren, das dauerte schon SW zu lang, wurde 
also als AHCT FF ausgeführt, dann wurde die galvanische Trennung zum 
Trigger nötig was die Zeit auf 40ns wieder verlängerte, aber immer noch 
OK ist.
1
#include <math.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
//#include <avr/eeprom.h>
6
#include <avr/interrupt.h>
7
#include <avr/io.h>
8
//#include <avr/sleep.h>
9
//#include <avr/wdt.h>
10
#include <util/delay.h>
11
12
#include "bits.h"
13
#include "config.h"
14
#include "my_types.h"
15
#include "s_tools.h"
16
#include "usart.h"
17
18
//AVR-Typenabhänggikeit
19
#if defined(__AVR_ATmega48__)
20
  #define MCU_STATUS_REG MCUCR
21
#elif defined(__AVR_ATmega88__)
22
  #define MCU_STATUS_REG MCUCR
23
  #define UseM8
24
#elif defined(__AVR_ATmega168__)
25
  #define MCU_STATUS_REG MCUCR
26
  #define UseM8
27
#else
28
  #define MCU_STATUS_REG MCUCSR
29
  #define UseM8
30
#endif
31
32
//Baudrate der seriellen Schnittstelle
33
#define BAUDRATE 115200UL
34
35
volatile UWORD result=0;
36
37
ISR(SIG_INTERRUPT1)
38
{
39
  register UBYTE i=0;
40
  cli();        // disable INTERRUPT
41
  ROT();        // disable E1
42
43
// alles im interrupt abarbeiten
44
  _delay_us(48);
45
  setA2();        // t1 = 50 -> A2 nach 50µs auf high
46
  _delay_us(ADC_DELAY-50);    // t2 = 100(250) -> beginn der AD Wandlung
47
48
// adc
49
  BLUE_ON();        
50
  result=0;
51
  // Den ADC aktivieren
52
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Teilungsfaktor auf 256 = 144kSAMPLE/s
53
54
  // Kanal des Multiplexers waehlen
55
  // Interne Referenzspannung verwenden (also mega88 1,1 V)
56
  ADMUX = ADCchannel | (1<<REFS1) | (1<<REFS0);
57
58
  // Den ADC initialisieren und einen sog. Dummyreadout machen
59
  ADCSRA |= (1<<ADSC);
60
  while(ADCSRA & (1<<ADSC));  // bis fertig
61
62
  // Jetzt READS die analoge Spannung and Kanal channel auslesen
63
  // und dann Durchschnittswert ausrechnen.
64
  for(i=0; i<READS; i++) 
65
  {  // Eine Wandlung
66
    ADCSRA |= (1<<ADSC);
67
    // Auf Ergebnis warten...
68
    while(ADCSRA & (1<<ADSC));
69
    
70
    result += ADCW;  // aufsummieren
71
  }
72
  
73
  // ADC wieder deaktivieren
74
  ADCSRA &= ~(1<<ADEN);
75
  
76
  result /= READS;    // Mittelwertbildung
77
  
78
  if(!result)
79
    result=1;
80
  BLUE_OFF();        
81
  resFF();          // A1 rücksetzen
82
  resA2();          // A2 rücksetzen
83
84
  sei();          // enable INTERRUPT und RTI
85
}
86
87
//Programmbeginn
88
int main(void) 
89
{  
90
  UBYTE i;
91
  char u_buff[13];
92
  //char d_buff[8];
93
94
  cli();
95
  
96
  // Init DDR / Ports
97
  BLUE_LED_DDR   |= (1<<_blueLED);
98
  RT_GN_LEDK_DDR |= (1<<_rtgnLED_K);
99
  RT_GN_LEDA_DDR |= (1<<_rtgnLED_A);
100
  A1_DDR       |= 1<<A1_bit;
101
  A2_DDR       |= 1<<A2_bit;
102
  resFF_DDR    |= (1<<_resFF);
103
104
  BLUE_OFF();
105
  GRUEN();
106
  resFF();
107
  resA2();
108
109
  usart_init(BAUDRATE);
110
  usart_write_str("init laeuft \r\n");
111
  usart_write_str("5 x blink \r\n");
112
  for(i=0;i<5;i++)  // Prozzilebenszeichen
113
  {  BLUE_LED_PORT ^= (1<<_blueLED);
114
    BLUE_LED_PORT & (1<<_blueLED) ? usart_write_str("blau ON \r\n") :  usart_write_str("blau OFF \r\n");
115
116
    A2_PORT ^= (1<<A2_bit);
117
118
    _delay_ms(500);
119
    ROT();
120
    usart_write_str("rot \r\n");
121
    _delay_ms(250);
122
    GRUEN();
123
    usart_write_str("gruen \r\n");
124
    _delay_ms(250);
125
  }
126
127
  BLUE_OFF();
128
  A1_DDR &= ~(1<<A1_bit);
129
  A2_DDR &= ~(1<<A2_bit);
130
  _delay_ms(5000);
131
132
  A1_DDR |= (1<<A1_bit);
133
  A2_DDR |= (1<<A2_bit);
134
135
  resFF();
136
  resA2();
137
138
  EICRA = (1<<ISC11);      // nach Invertierung auf negative Flanke
139
    EIMSK = (1<<INT1);        // Enable INT1
140
  
141
  for(i=0;i<5;i++)  // Prozzilebenszeichen
142
    usart_write_str("\r\n");
143
  sei();
144
145
  while(1)
146
  {
147
    if(result)
148
    {
149
      //BLUE_ON();
150
      if(result>=1020)
151
        usart_write_str("overflow \r\n");
152
      else
153
      {
154
        //itoa(10*result, u_buff, 10);
155
        //trimm_string(' ', itoa(10*result, u_buff, 10), 5);
156
        strcpy(u_buff, insert_char(trimm_string(' ', itoa(((_m*result)+_b), u_buff, 10), 5), ',', 2));
157
        //strcpy(d_buff, itoa(result, d_buff, 10));
158
        u_buff[5]=0;
159
        strcat(u_buff, "V ");
160
        if(u_buff[1]==' ')
161
          u_buff[1]='0';
162
        if(u_buff[3]==' ')
163
          u_buff[3]='0';
164
        if(u_buff[4]==' ')
165
          u_buff[4]='0';
166
        //strcat(u_buff, d_buff);
167
        //strcat(u_buff, "d");
168
        usart_write_str(u_buff);
169
        usart_write_char(13);
170
        usart_write_char(10);
171
        //_delay_ms(2000);
172
      }
173
      result=0;
174
      //BLUE_OFF();        
175
    }
176
    GRUEN();
177
  }
178
  return 0;
179
}

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>im ersten Anlauf sollte der AVR kürzest möglich mit einer fallenden
>Flanke auf den Trigger reagieren, das dauerte schon SW zu lang,

SW?

> wurde
>also als AHCT FF ausgeführt, dann wurde die galvanische Trennung zum
>Trigger nötig was die Zeit auf 40ns wieder verlängerte, aber immer noch
>OK ist.

Du redest wirr. Lies mal was über Netiquette.

Beschreibe die Aufgabe mal prinzipiell und mit ZAHLEN!

Ich rate mal. Vier Signale absolut synchron abtasten? Dazu braucht man 
vier exteren Sample&Hold ICs. Der Rest wie beschrieben.

von Joachim B. (jar)


Lesenswert?

zu den Fragen

>Warum müssen denn die AVRs überhaupt taktsynchron laufen?

keine Infos

>Du wartest dort hoffentlich nicht bis der UART ein
>Zeichen gesendet hat oder so ähnlich?

nein das überlasse ich der usart.c

>Aber das geht in einem µC, zumindest wenn die Messwerte um 50 - 100µs
>versetzt gesampelt werden dürfen.

nein darf nicht !

>Das mit mehreren µC (ohne Not eingesetzt) alles noch komplizierter wird,
>wusste er nicht. Er hat halt irgendwo das Schlagwort 'Multiprozessor'
>oder vielleicht sogar 'mehrere Rechenkerne' gehört und dachte sich:
>Geeeiiiiil, will haben.
>Was er sich damit eingebrockt hat, konnte er allerdings mangels Wissen
>nicht abschätzen.

diese Denke führt vermutlich in die falsche Richtung, das Muster 
funktioniert, das 4x bauen zu lassen ist vermutlich schneller als ewig 
weiter zu optimieren bis es mit einem läuft, klar kann ich mit weniger 
readouts schneller werden, nur ob das dem Auftraggeber hinreichend genau 
ist weiss ich nicht, Testzeit an dem Gerät steht wohl nicht immer genug 
zur Verfügung.

>Was hat sich dein Vorgänger eigentlich ausgedacht, um die 4 einzelnen
>RS232 wieder zusammenzuführen?

kann ich nicht sagen, macht ein externer Programmierer

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> ISR(SIG_INTERRUPT1)
> {
>   register UBYTE i=0;
>   cli();        // disable INTERRUPT
>   ...
>   sei();          // enable INTERRUPT und RTI
> }

cli() und sei() haben nichts in der ISR zu suchen. Das macht das 
Runtime-System schon selbst. So bringst Du das ganze lediglich 
durcheinander.

Gruß,

Frank

von Falk B. (falk)


Lesenswert?

Und schrieb ich nicht was von Anhang? 8-0


>//AVR-Typenabhänggikeit
>#if defined(_AVR_ATmega48_)
>  #define MCU_STATUS_REG MCUCR

Alter Käse, das ist in den aktuellen AVR-GCC includes alles drin.

>volatile UWORD result=0;

Nimm uint8_t oder so, UWORD ist undefinierter Käse.


>ISR(SIG_INTERRUPT1)

Ist veraltet, dort kommt ein Vektorname rein.

>{
>  register UBYTE i=0;
>  cli();        // disable INTERRUPT

Unsinn.

>// alles im interrupt abarbeiten
>  _delay_us(48);

So dringend kann die Messung nicht sein, wenn erst mal 48µs gewartet 
wird.

>  // Den ADC aktivieren
>  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // >Teilungsfaktor 
auf 256 = 144kSAMPLE/s

Ist Käse, das macht man EINMAL beim Einschalten und nicht jedes mal beim 
NUTZEN.

>  // Kanal des Multiplexers waehlen
>  // Interne Referenzspannung verwenden (also mega88 1,1 V)

Die Referenzsopannung schaltet man auch nur EINMAL ein.

>  ADMUX = ADCchannel | (1<<REFS1) | (1<<REFS0);

Den Kanal kann man wählen.

>  // Den ADC initialisieren und einen sog. Dummyreadout machen
>  ADCSRA |= (1<<ADSC);
>  while(ADCSRA & (1<<ADSC));  // bis fertig

Müll, siehe oben.


>  // Jetzt READS die analoge Spannung and Kanal channel auslesen
>  // und dann Durchschnittswert ausrechnen.
>  for(i=0; i<READS; i++)
>  {  // Eine Wandlung
>    ADCSRA |= (1<<ADSC);
>    // Auf Ergebnis warten...
>    while(ADCSRA & (1<<ADSC));

>    result += ADCW;  // aufsummieren
>  }

Kann alles nciht wirklich zeitkritisch sein, wenn du N-mal den 
ADC-auslesen kannst.

>  // ADC wieder deaktivieren
>  ADCSRA &= ~(1<<ADEN);

Warum? Die paar µA tun dir nicht weh.

>  result /= READS;    // Mittelwertbildung

Divisionen kosten Rechenzeit.


>  if(!result)
>    result=1;
>  BLUE_OFF();
>  resFF();          // A1 rücksetzen
>  resA2();          // A2 rücksetzen

>  sei();          // enable INTERRUPT und RTI

Käse, das macht die ISR allein!

>//Programmbeginn
>int main(void)
>{
>  UBYTE i;
>  char u_buff[13];
>  //char d_buff[8];

>  cli();

Wozu? Hier ist SICHER kein Interrupt aktiv.

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>>Aber das geht in einem µC, zumindest wenn die Messwerte um 50 - 100µs
>>versetzt gesampelt werden dürfen.

>nein darf nicht !

Aber sicher, dein aktueller COde lässt sich durch die Mittelwertbildung 
noch viel mehr Zeit.

>diese Denke führt vermutlich in die falsche Richtung,

Ja, Deine.

> das Muster
>funktioniert, das 4x bauen zu lassen ist vermutlich schneller als ewig
>weiter zu optimieren bis es mit einem läuft,

Irrtum. Wer nicht mal EINEN Prozessor gut beherrscht, beherrscht VIER 
davon gleichzeit erst recht nicht.

> klar kann ich mit weniger
>readouts schneller werden, nur ob das dem Auftraggeber hinreichend genau
>ist weiss ich nicht, Testzeit an dem Gerät steht wohl nicht immer genug
>zur Verfügung.

Mit dem passenden Konzept geht das einfacher als man denkt.

>>Was hat sich dein Vorgänger eigentlich ausgedacht, um die 4 einzelnen
>>RS232 wieder zusammenzuführen?

>kann ich nicht sagen, macht ein externer Programmierer

Also Plan- und Konzeptlosigkeit überall. Naja . . .

von Falk B. (falk)


Lesenswert?

Ach ja, es ist noch ein fieser Zugriffsfehler auf "result" drin, denn 
der ist nicht atomar, siehe Interrupt. Jaja, der tritt nur sehr 
selten auf, aber genau DAS ist die Gefahr!

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> cli() und sei() haben nichts in der ISR zu suchen

nun bringst du mich durcheinander, kann in einem Interrupt kein 
Interrupt auftreten ?

ich hatte das mal anders gelesen

derlei lese ich doch immer wieder in ISR Routinen, erst mal weitere IR 
sperren


zu den Fragen:

>SW?

software, hier eine Pinantwort vom AVR auf den Interrupt gemeint, 
dauerte dem Auftraggeber zu lange (warum auch immer)

>Du redest wirr. Lies mal was über Netiquette.

OK Klartext:
weil die Pinantwort am Portpin des AVR auf den einlaufenden Trigger dem 
Auftraggeber zu lang war wurde der Trigger Impuls mit einem 74AHCT00 als 
SR-FF (SR set/reset, FF flipflop) beschaltet zurückgegeben

Triggersignal und Meßsignal bildeten Interferenzen, oder Störungen oder 
es kam halt nicht das gewünschte raus, was vermutlich auf mangelnde 
Masse/Erdung zurückzuführen war, deswegen wurde eine galvanische 
Trennung für das Triggersignal eingebaut was die Zeit auf 40ns wieder 
verlängerte, aber immer noch lt. Auftraggeber OK ist. Als AVR Antwort in 
Software war schon der Eintritt in die ISR mit einigen 55ns Takten 
behaftet bevor der Pin gesetzt war

>Beschreibe die Aufgabe mal prinzipiell und mit ZAHLEN!

sind die Bilder nicht Aussage genug ?

>Ich rate mal. Vier Signale absolut synchron abtasten? Dazu braucht man
>vier exteren Sample&Hold ICs. Der Rest wie beschrieben.

wieso ?
aus der doc2545.pdf AVR Seite 244
The ADC contains a Sample and Hold circuit, wozu 4 externe SH ?

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:
> Frank M. schrieb:
>> cli() und sei() haben nichts in der ISR zu suchen
>
> nun bringst du mich durcheinander, kann in einem Interrupt kein
> Interrupt auftreten ?
>
> ich hatte das mal anders gelesen

Autsch. Das tut weh.,
Sonderlich viel hast du mit AVR noch nicht gemacht.

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:

> The ADC contains a Sample and Hold circuit, wozu 4 externe SH ?


Wenn du endlich mal mit den Spec rausrücken würdest, wie synchron das 
ganze denn wirklich sein muss.

Einmal tust du so, als ob das alles kein Problem ist. Dann sind ein paar 
µs nacheinenander schon ein Problem. Dann sehen wir ein Programm, in dem 
an allen Ecken und Ende ein _delay sitzt.
Ja was den nun?

Mit 4 externen ADC kannst du tatsächlich alle gleichzeitig starten und 
wandeln lassen. Mit dem internen geht es nur mit etwas Zeitversatz. Die 
Frage ist, ob dieser Zeitversatz akzeptabel ist oder nicht.

von Joachim B. (jar)


Lesenswert?

>Aber das geht in einem µC, zumindest wenn die Messwerte um 50 - 100µs
>versetzt gesampelt werden dürfen.

>Aber sicher, dein aktueller COde lässt sich durch die Mittelwertbildung
>noch viel mehr Zeit.

aber an der richtigen Stelle 100µs nach Trigger, 4 AVR können das 
parallel, einer nur seriell und damit sicher nicht an der richtigen 
Stelle (wobei mir diese völlig unbekannt ist)

>Ja, Deine.

mag sein ich halte mich an den Vorgaben des Auftragsgeber, über Sinn 
diskutiere ich doch nicht mit so wenig Infos wie ich bekomme, ich 
erwarte nur die Rückmeldung läuft wie gewünscht.

>Irrtum. Wer nicht mal EINEN Prozessor gut beherrscht, beherrscht VIER
>davon gleichzeit erst recht nicht.

schlauer Satz, nur widerspricht sich das nicht mit deiner Forderung

>Dazu braucht man vier exteren Sample&Hold ICs.

die sind im mega88 doch eingebaut und wie soll ein mega88 auf 4 
Triggersignale zeitgenau reagieren, durch pollen und verschachtelter 
Programmierung ? peda hatte da mal einen Scheduler, aber ob der das 
packt ? der Scheduler, nicht PeDa

>Also Plan- und Konzeptlosigkeit überall. Naja . . .

ja kommt mir auch so vor, ich reagiere nur auf die Wünsche, agiere eben 
weniger, weil mir die Vorgaben sowas von unbekannt aussehen

>Ach ja, es ist noch ein fieser Zugriffsfehler auf "result" drin, denn
>der ist nicht atomar, siehe Interrupt. Jaja, der tritt nur sehr
>selten auf, aber genau DAS ist die Gefahr!

OK muss ich mir noch mal ansehen

>>  // ADC wieder deaktivieren
>>  ADCSRA &= ~(1<<ADEN);
>Warum? Die paar µA tun dir nicht weh.

nö der Strom tut nicht weh, Rauschen Störungen ? mir fehlt noch zu viel 
Langzeiterfahrung ob der ADC wirklich immer on sein darf oder was das 
für Nebeneffekte hat, wäre der immer ON sparte man den Dummy readout, 
die Wandlungszeit verkürzte sich auch, aber wie gesagt ob die Ergebnisse 
dann noch passen weiss ich nicht, ich weiss ja nicht mal ob sie an der 
Maschine wirklich stimmen, für den Bau dieser Schaltung habe ich vorher 
einen Simulator gebaut, der den 1µs Trigger alle 10ms erzeugt (Dual 
Timer 556) und eine angezapfte AC Wicklung vom Netztrafo für das 
Analogsignal zur Wandlung

>Und schrieb ich nicht was von Anhang? 8-0
??? weiss nicht was du meinst


>Alter Käse, das ist in den aktuellen AVR-GCC includes alles drin.

OK ist meine denn aktuell ? manno um sowas streite ich doch nicht

>Nimm uint8_t oder so, UWORD ist undefinierter Käse.

man kann den Käse auch definieren, mir gefällt UWORD, was ändert uint8_t 
?
wird der Code schneller ?, spare ich Takte ?, spare ich RAM ?


>ISR(SIG_INTERRUPT1)
>Ist veraltet, dort kommt ein Vektorname rein.

ändert aber nix am Programm

>>  cli();        // disable INTERRUPT
>Unsinn.

danke ein nützlicher Hinweis

>>// alles im interrupt abarbeiten
>>  _delay_us(48);
>So dringend kann die Messung nicht sein, wenn erst mal 48µs gewartet
>wird.

das war die Vorgabe genau an dieser Stelle die Messung zu machen

>>  // Den ADC aktivieren
>>  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // >
>> Teilungsfaktor auf 256 = 144kSAMPLE/s

>Ist Käse, das macht man EINMAL beim Einschalten und nicht jedes mal beim
>NUTZEN.

danke ein nützlicher Hinweis

>>  // Kanal des Multiplexers waehlen
>>  // Interne Referenzspannung verwenden (also mega88 1,1 V)
>Die Referenzsopannung schaltet man auch nur EINMAL ein.

danke ein nützlicher Hinweis

>>  ADMUX = ADCchannel | (1<<REFS1) | (1<<REFS0);
>Den Kanal kann man wählen.

danke ein nützlicher Hinweis, war aber hier nur ein Schönheitsfehler, 
kein logischer

>>  result /= READS;    // Mittelwertbildung
>Divisionen kosten Rechenzeit.

stimmt, nur hier stört sie nicht, Alternative wäre 2 4 8 16 32 readouts 
und shiften, ist zwar schneller bringt hier aber nix mehr

>>  sei();          // enable INTERRUPT und RTI
>Käse, das macht die ISR allein!

danke und ich grübel die ganze Zeit wie das nun mit Interrupts in ISR 
Routinen ist, also in der ISR kann kein weiterer Interrupt einlaufen ? 
oder doch ?

>>cli();
>Wozu? Hier ist SICHER kein Interrupt aktiv.

OK schaden tuts aber hier auch nicht, OK ich hab ein paar flashzellen 
sinnlos belegt immerhin kann ich das nun auch löschen, ich lerne ja 
täglich dazu

von spess53 (Gast)


Lesenswert?

Hi

>>Dazu braucht man vier exteren Sample&Hold ICs.

>die sind im mega88 doch eingebaut

Nein. Dort ist eine S&H-Stufe und ein ADC eingebaut. Gesampled wird 
nur der durch den Multiplexer gewählte Kanal beim Start einer Wandlung. 
Wenn du 4 Signale gleichzeitig Samplen brauchst du vier externe S&H.

MfG Spess

von Joachim B. (jar)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wenn du endlich mal mit den Spec rausrücken würdest, wie synchron das
> ganze denn wirklich sein muss.

wenn ich das wüsste ? sagt mir doch keiner, auch auf Nachfrage nicht

> Einmal tust du so, als ob das alles kein Problem ist. Dann sind ein paar
> µs nacheinenander schon ein Problem. Dann sehen wir ein Programm, in dem
> an allen Ecken und Ende ein _delay sitzt.
> Ja was den nun?

das delay ist genau an den Stellen an denen es der Auftraggeber 
gewünscht hat

> Mit 4 externen ADC kannst du tatsächlich alle gleichzeitig starten und
> wandeln lassen. Mit dem internen geht es nur mit etwas Zeitversatz. Die
> Frage ist, ob dieser Zeitversatz akzeptabel ist oder nich

nee falsch verstanden, es kommen 4 Triggersignale 1µs lang alle 10ms

ob die 4 zeitlich im Zusammenhang stehen weiss ich nicht !

auf ein Triggersignal soll ein Port seine Polarität wechseln, 
schnellstmöglich, ein weiterer 50µs nach Trigger, die ADC Wandlung soll 
100µs nach Trigger erfolgen, dann seriell ausgegeben werden, Ports 
rücksetzen, Zyklus Ende

das 4x wobei ich eben nicht weiss ob die 4 in einem zeitlichen 
Zusammenhang stehen oder beliebig kommen können !

die Forderung synchron laufen der AVR ist mir unklar weil es auch 4 
Triggereingänge gibt und es schon da kein synchron mehr gibt !

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Also im schlimmsten Fall müsste man vor 4 ADC Kanäle eine simple S&H 
Schaltung mit Analogschalter und kleinem Speicher-C bauen. Ein freier 
Portpin schaltet die Analogschalter von Sample auf Hold und dann kann 
man in Ruhe alle 4 Kanäle mit dem zur Samplezeit gültigen AD Wert 
auslesen.

Das schafft jeder Mega8/48/88/168 locker alleine ohne Klimmzüge. Die 
o.a. ISR für den AD Wandler sieht mir nach gewollt und nicht gekonnt 
aus.

von Joachim B. (jar)


Lesenswert?

Matthias Sch. schrieb:
> Also im schlimmsten Fall müsste man vor 4 ADC Kanäle eine simple S&H
> Schaltung mit Analogschalter und kleinem Speicher-C bauen. Ein freier
> Portpin schaltet die Analogschalter von Sample auf Hold und dann kann
> man in Ruhe alle 4 Kanäle mit dem zur Samplezeit gültigen AD Wert
> auslesen.

OK, da gehe ich für diese Schaltung mit dir !

4 S&H + 1 AVR !

> Das schafft jeder Mega8/48/88/168 locker alleine ohne Klimmzüge.

aber es stand auch im Raum, das wird mehrfach gebraucht, ob immer als 
4-fach Block oder als single Block weiss ich nicht, die Angaben sind zu 
diffus als das ich nun alles als 4-fach auf einer BG umplane !

> Die o.a. ISR für den AD Wandler sieht mir nach gewollt und nicht gekonnt
> aus.

stimmt ist C&P aus Beispielcode und funktioniert, elegant oder nicht ist 
erst mal egal, einiges habe ich ja heute schon gelernt und werde es 
umsetzen ;-)

ich glaube PeDa hat hier auch schon sehr lange sehr alten Code 
eingestellt wobei sich niemand dran stört das die Routinen oder defines 
heute anders heissen, aus signal.h wurde interrupt.h z.B. Registernamen 
ändern sich je nach Controller, AStudio ändert sich mit avr_gcc, musste 
früher noch der Link zu include avr/io gesetzt werden so scheint das in 
neueren Versionen nicht mehr nötig zu sein, da ich an 4 Rechner arbeite 
ist es manchmal nicht leicht alle auf den Stand gleich zu halten, mein 
Desk ist gerade abgeraucht, also mal eben zum Notbook gewechselt und 
ältere avr_gcc vorgefunden, so ähnlich gehts mir mit code Schnipsel, 
fast jeder hat eine eigene UART oder USART Routine, wobei die eine oder 
andere mal besser mal schlechter zu arbeiten scheint, klar kann ich nun 
anfangen eigene USART/UART Routinen dazuzuschreiben, aber ist das 
wirklich das Ziel ?

ich danke allen die mich etwas erhellt haben und auch jeder kritischen 
Anmerkung (ihr merkt schon, glücklich kann ich weder über meinen 
Wissenstand in der AVR Programmierung sein noch über die dürftigen 
Angaben meiner Auftragsgeber, aber thats live, machen wir das beste 
draus.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Du solltest mal ein Pflichtenheft anfordern mit Timing Diagrammen und 
den Zeitanforderungen. Es wäre ja auch schön zu erfahren,was du da 
erfassen sollst. Für Interuptroutinen gilt eigentlich immer, das du das 
machst, was nötig ist und nichts mit delays retten musst, dafür gibt es 
Timer und State Machines.
Ein ADC Interrupt sollte z.B. :
* ADC Wert lesen und abspeichern
* Zum nächsten Kanal schalten
* ADC starten
* Ende
Während der ADC wandelt, hast du Zeit für was anderes. Genauso beim 
UART. Gib ihm das Byte zum Senden und hau ab. Der UART meldet sich mit 
TXComplete, wenn er wieder so weit ist. Das erfordert eine kleine aber 
undramatische Bufferverwaltung, gibt dir aber jede Menge Zeit, andere 
Sachen zu tun.

von Joachim B. (jar)


Lesenswert?

Matthias Sch. schrieb:
> Du solltest mal ein Pflichtenheft anfordern mit Timing Diagrammen und
> den Zeitanforderungen.

habe ich doch angefordert, was ich bekommen habe war ein Textfile
scroll etwas hoch und du siehst die geforderten Timings die auf der 
Muster BG funktionieren

> Es wäre ja auch schön zu erfahren,was du da
> erfassen sollst. Für Interuptroutinen gilt eigentlich immer, das du das
> machst, was nötig ist und nichts mit delays retten musst,

ich muss nix mit delays retten ! ich muss die nur abwarten bis zum 
nächsten Schritt und da ich gerade in der ISR bin, warum verlassen ? 
weiter tut der AVR (noch) nix, wobei ich schon am Grübeln bin ob ich 
nicht die 4-fach Forderung in einen AVR bringe, ich kann durchaus 
das/die langsamen analogen Eingangssignal(e) ohne mehrere readouts 
filtern, sondern mit Tiefpass, oder die readout Schleife zugleich 
verkleinern und alle Signale verschachtelt auslesen, statt 30-40 ADC 
Loops pro Kanal, ordentlich filtern, 8-10 Loops und 4 Kanäle bedienen 
(der Gedanke der hier aufkam gefällt mir)

> dafür gibt es
> Timer und State Machines.
> Ein ADC Interrupt sollte z.B. :
> * ADC Wert lesen und abspeichern

war aber hier nicht das Anforderprofil, sonden nach Trigger genau 100µs 
später wandeln und da ich nicht weiss wann der/die Trigger kommen....

in einer Timer ISR einen count hochzählen und für jeden Trigger die Zeit 
nehmen funktioniert ja, hab ich schon gemacht, aber im ms Bereich, eben 
nicht im µs Bereich und da mich der AVR schon bei den Eintritt in die 
ISR "enttäuscht" hatte, falsche Abschätzung meinerseits, werde ich 
vorsichtig.

Ich übersetzte RISC mit 1 Befehl 1 Takt, bei 18,xx Mhz also 55ns dachte 
ich nicht im Traum das schon der Eintritt in die ISR in die µs geht

polle ich nun die 4 Trigger ? oder vergebe ich 4 Interrupts, was ist 
wenn der eine Interrupt aktiv ist und der nächste kommt ?

wenn ich polle, in welchem Zeitraster können 4 Ports für Trigger 
überwacht werden  bei 18,xx MHz ?

> Während der ADC wandelt, hast du Zeit für was anderes.
> Genauso beim UART. Gib ihm das Byte zum Senden und hau ab. Der UART
> meldet sich mit TXComplete, wenn er wieder so weit ist. Das erfordert
> eine kleine aber undramatische Bufferverwaltung, gibt dir aber jede
> Menge Zeit, andere Sachen zu tun.

ist doch in USART.C drin, ich übergebe das und hau ab
1
/*----------------------------------------------------------------------------
2
 Copyright:      Radig Ulrich  mailto: mail@ulrichradig.de
3
 Author:         Radig Ulrich
4
 Remarks:        
5
 known Problems: none
6
 Version:        24.10.2007
7
 Description:    RS232 Routinen
8
9
 Dieses Programm ist freie Software. Sie können es unter den Bedingungen der 
10
 GNU General Public License, wie von der Free Software Foundation veröffentlicht, 
11
 weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder 
12
 (nach Ihrer Option) jeder späteren Version. 
13
14
 Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, 
15
 daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, 
16
 sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT 
17
 FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. 
18
19
 Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 
20
 Programm erhalten haben. 
21
 Falls nicht, schreiben Sie an die Free Software Foundation, 
22
 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
23
------------------------------------------------------------------------------*/
24
#include "usart.h"
25
26
volatile unsigned int buffercounter = 0;
27
28
char usart_rx_buffer[BUFFER_SIZE];
29
char *rx_buffer_pointer_in  = &usart_rx_buffer[0];
30
char *rx_buffer_pointer_out  = &usart_rx_buffer[0];
31
  
32
//----------------------------------------------------------------------------
33
//Init serielle Schnittstelle
34
void usart_init(unsigned long baudrate) 
35
{ 
36
  //Serielle Schnittstelle 1
37
    //Enable TXEN im Register UCR TX-Data Enable
38
  UCR =(1 << TXEN | 1 << RXEN | 1<< RXCIE);
39
  // 0 = Parity Mode Disabled
40
  // 1 = Parity Mode Enabled, Even Parity
41
  // 2 = Parity Mode Enabled, Odd Parity
42
  //UCSRC = 0x06 + ((parity+1)<<4);
43
  //UCSRC |= (1<<USBS);
44
  //Teiler wird gesetzt 
45
  UBRR=(F_CPU / (baudrate * 16L) - 1);
46
  usart_status.usart_disable = 0;
47
}
48
49
//----------------------------------------------------------------------------
50
//Routine für die Serielle Ausgabe eines Zeichens (Schnittstelle0)
51
void usart_write_char(char c)
52
{
53
        if(!usart_status.usart_disable)
54
        {
55
            //Warten solange bis Zeichen gesendet wurde
56
            while(!(USR & (1<<UDRE)));
57
            //Ausgabe des Zeichens
58
            UDR = c;
59
        }
60
        return;
61
}
62
63
//------------------------------------------------------------------------------
64
void usart_write_P (const char *Buffer,...)
65
{
66
  va_list ap;
67
  va_start (ap, Buffer);  
68
  
69
  int format_flag;
70
  char str_buffer[10];
71
  char str_null_buffer[10];
72
  char move = 0;
73
  char Base = 0;
74
  int tmp = 0;
75
  char by;
76
  char *ptr;
77
    
78
  //Ausgabe der Zeichen
79
    for(;;)
80
  {
81
    by = pgm_read_byte(Buffer++);
82
    if(by==0) break; // end of format string
83
            
84
    if (by == '%')
85
    {
86
            by = pgm_read_byte(Buffer++);
87
      if (isdigit(by)>0)
88
        {
89
                                 
90
         str_null_buffer[0] = by;
91
        str_null_buffer[1] = '\0';
92
        move = atoi(str_null_buffer);
93
                by = pgm_read_byte(Buffer++);
94
        }
95
96
      switch (by)
97
        {
98
                case 's':
99
                    ptr = va_arg(ap,char *);
100
                    while(*ptr) { usart_write_char(*ptr++); }
101
                    break;
102
        case 'b':
103
          Base = 2;
104
          goto ConversionLoop;
105
        case 'c':
106
          //Int to char
107
          format_flag = va_arg(ap,int);
108
          usart_write_char (format_flag++);
109
          break;
110
        case 'i':
111
          Base = 10;
112
          goto ConversionLoop;
113
        case 'o':
114
          Base = 8;
115
          goto ConversionLoop;
116
        case 'x':
117
          Base = 16;
118
          //****************************
119
          ConversionLoop:
120
          //****************************
121
          itoa(va_arg(ap,int),str_buffer,Base);
122
          int b=0;
123
          while (str_buffer[b++] != 0){};
124
          b--;
125
          if (b<move)
126
            {
127
            move -=b;
128
            for (tmp = 0;tmp<move;tmp++)
129
              {
130
              str_null_buffer[tmp] = '0';
131
              }
132
            //tmp ++;
133
            str_null_buffer[tmp] = '\0';
134
            strcat(str_null_buffer,str_buffer);
135
            strcpy(str_buffer,str_null_buffer);
136
            }
137
          usart_write_str (str_buffer);
138
          move =0;
139
          break;
140
        }
141
      
142
      }  
143
    else
144
    {
145
      usart_write_char ( by );  
146
    }
147
  }
148
  va_end(ap);
149
}
150
151
//----------------------------------------------------------------------------
152
//Ausgabe eines Strings
153
void usart_write_str(char *str)
154
{
155
  while (*str)
156
  {
157
    usart_write_char(*str++);
158
  }
159
}
160
161
//----------------------------------------------------------------------------
162
//Empfang eines Zeichens
163
ISR (USART_RX)
164
{
165
  if(!usart_status.usart_disable)
166
  {
167
    unsigned char receive_char;
168
    receive_char = (UDR);
169
    
170
    #if USART_ECHO
171
    usart_write_char(receive_char);
172
    #endif
173
  
174
    if (usart_status.usart_ready)
175
    {
176
      usart_status.usart_rx_ovl = 1;
177
      return; 
178
    }
179
        
180
        if (receive_char == 0x08)
181
        {
182
            if (buffercounter) buffercounter--;
183
            return;
184
        }
185
    
186
    if (receive_char == '\r' && (!(usart_rx_buffer[buffercounter-1] == '\\')))
187
    {
188
      usart_rx_buffer[buffercounter] = 0;
189
      buffercounter = 0;
190
      usart_status.usart_ready = 1;
191
      return;    
192
    }
193
  
194
    if (buffercounter < BUFFER_SIZE - 1)
195
    {
196
      usart_rx_buffer[buffercounter++] = receive_char;    
197
    }
198
  }
199
  else
200
  {
201
    if(rx_buffer_pointer_in == (rx_buffer_pointer_out - 1))
202
    {
203
      //Datenverlust
204
      return;
205
    }
206
  
207
    *rx_buffer_pointer_in++ = UDR;
208
  
209
    if (rx_buffer_pointer_in == &usart_rx_buffer[BUFFER_SIZE-1])
210
    {
211
      rx_buffer_pointer_in = &usart_rx_buffer[0];
212
    }
213
  }
214
  return;
215
}

von spess53 (Gast)


Lesenswert?

Hi

>Ich übersetzte RISC mit 1 Befehl 1 Takt, bei 18,xx Mhz also 55ns dachte
>ich nicht im Traum das schon der Eintritt in die ISR in die µs geht

Wie kommst du auf die µs?  Hast du eigentlich schon mal ein Datenblatt 
von innen gesehen? Oder woher kommt diese geballte Inkompetenz?

MfG Spess

von Joachim B. (jar)


Lesenswert?

spess53 schrieb:
> Wie kommst du auf die µs?

Krümelzähler ? ob nun 550ns (gemessen, Aufruf der ISR auf Trigger bis 
Port gesetzt in der ISR) oder fast eine µs ist auf jeden Fall zu lang 
für die verlangte Ausführung !

> Hast du eigentlich schon mal ein Datenblatt
> von innen gesehen?

nö noch nie, wieso muss man das ?

>Oder woher kommt diese geballte Inkompetenz?

ach was, und woher kommt diese geballte Freundlichkeit deinerseits ? 
Hormonstau ? oder einsam ? hier gibt es einige die auch vernünftig 
antworten können ? mal wird mir die Nettiqutte um die Ohren gehauen weil 
ich SW und FF schrieb, durchaus gängige Abkürzungen und nun schau ich in 
doch in einen recht merkwürdigen Kommentar ?

Mal ehrlich kannst du das nicht besser ? dann ärger dich doch hier nicht 
rum ;-)

von spess53 (Gast)


Lesenswert?

Hi

>ach was, und woher kommt diese geballte Freundlichkeit deinerseits ?

Vielleicht, weil ich mir keinen professionellen Programmierer vorstellen 
kann, der hier solche Fragen stellt?

MfG Spess

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>nun bringst du mich durcheinander, kann in einem Interrupt kein
>Interrupt auftreten ?

Lies etwas über das Thema Interrupt, speziell beim AVR.

>software, hier eine Pinantwort vom AVR auf den Interrupt gemeint,
>dauerte dem Auftraggeber zu lange (warum auch immer)

Solche Aussagen liebe ich . . .

>weil die Pinantwort am Portpin des AVR auf den einlaufenden Trigger dem
>Auftraggeber zu lang war wurde der Trigger Impuls mit einem 74AHCT00 als
>SR-FF (SR set/reset, FF flipflop) beschaltet zurückgegeben

Schön, aber . . .

>Triggersignal und Meßsignal bildeten Interferenzen, oder Störungen oder
>es kam halt nicht das gewünschte raus, was vermutlich auf mangelnde
>Masse/Erdung zurückzuführen war,

Oder auf Planlosigkeit . . .

> deswegen wurde eine galvanische
>Trennung für das Triggersignal eingebaut was die Zeit auf 40ns wieder
>verlängerte, aber immer noch lt. Auftraggeber OK ist.

Muss ja ein tierisch schnelles Signal sein, das nicht mal 100ns warten 
kann. Mensch, in deinem Programm wird 48 MIKROSEKUNDEN gewartet, ehe 
überhaupt was losgeht!

> Als AVR Antwort in
>Software war schon der Eintritt in die ISR mit einigen 55ns Takten
>behaftet bevor der Pin gesetzt war

Logisch, mindestens 4 Takte in reinem Assembler, in C eher 20 oder mehr.

>>Beschreibe die Aufgabe mal prinzipiell und mit ZAHLEN!

>sind die Bilder nicht Aussage genug ?

NEIN!

>aus der doc2545.pdf AVR Seite 244
>The ADC contains a Sample and Hold circuit, wozu 4 externe SH ?

Wurde schon diskutiert (Scheißdreck, meine i-Taste ist kaputt, nie mehr 
i-pad!).

>aber an der richtigen Stelle 100µs nach Trigger, 4 AVR können das
>parallel, einer nur seriell und damit sicher nicht an der richtigen
>Stelle (wobei mir diese völlig unbekannt ist)

Was die Begründunung für vier parallele AVR vollkommen aushebelt.

>mag sein ich halte mich an den Vorgaben des Auftragsgeber, über Sinn
>diskutiere ich doch nicht mit so wenig Infos wie ich bekomme, ich
>erwarte nur die Rückmeldung läuft wie gewünscht.

Chinesenmethode. Kopf runter, Hirn aus, Chef wirds schon wissen. 
Funktioniert selten bis nie.

>>Dazu braucht man vier exteren Sample&Hold ICs.

>die sind im mega88 doch eingebaut

NEIN! Eine!

> und wie soll ein mega88 auf 4
>Triggersignale zeitgenau reagieren, durch pollen und verschachtelter
>Programmierung ?

Er sampelt sie zeitversetzt, ganz einfach.

>peda hatte da mal einen Scheduler, aber ob der das
>packt ? der Scheduler, nicht PeDa

Nein.

>ja kommt mir auch so vor, ich reagiere nur auf die Wünsche, agiere eben
>weniger, weil mir die Vorgaben sowas von unbekannt aussehen

Siehe oben.

>>Warum? Die paar µA tun dir nicht weh.

>nö der Strom tut nicht weh, Rauschen Störungen ? mir fehlt noch zu viel
>Langzeiterfahrung ob der ADC wirklich immer on sein darf

Darf er.

>für Nebeneffekte hat, wäre der immer ON sparte man den Dummy readout,

Was mal massig Zeit spart.

>die Wandlungszeit verkürzte sich auch, aber wie gesagt ob die Ergebnisse
>dann noch passen weiss ich nicht,

Ich schon. Andee auch. Sie passen.

>>Und schrieb ich nicht was von Anhang? 8-0
>??? weiss nicht was du meinst

Das du lange Quelltexte als Anhang posten sollst, nicht als Text im der 
Meldung. Siehe Netiquette.

>>Alter Käse, das ist in den aktuellen AVR-GCC includes alles drin.
>OK ist meine denn aktuell ? manno um sowas streite ich doch nicht

Alles was jünger als 5 Jahre ist, eher mehr.

>>Nimm uint8_t oder so, UWORD ist undefinierter Käse.

>man kann den Käse auch definieren, mir gefällt UWORD, was ändert uint8_t
>?

Es ist allgemeinverständlich und standardkonform.

>wird der Code schneller ?, spare ich Takte ?, spare ich RAM ?

Ggf. ja.

>>ISR(SIG_INTERRUPT1)
>>Ist veraltet, dort kommt ein Vektorname rein.

>ändert aber nix am Programm

nein.

>>>  _delay_us(48);
>>So dringend kann die Messung nicht sein, wenn erst mal 48µs gewartet
>>wird.

>das war die Vorgabe genau an dieser Stelle die Messung zu machen

Chinesenmethode.

>danke und ich grübel die ganze Zeit wie das nun mit Interrupts in ISR
>Routinen ist, also in der ISR kann kein weiterer Interrupt einlaufen ?
>oder doch ?

Siehe Interrupt.

>sinnlos belegt immerhin kann ich das nun auch löschen, ich lerne ja
>täglich dazu

Gut.

>auf ein Triggersignal soll ein Port seine Polarität wechseln,
>schnellstmöglich,

Das macht ein Toggle FlipFlop, 74HC74, ganz ohne Programmierung.

> ein weiterer 50µs nach Trigger, die ADC Wandlung soll
>100µs nach Trigger erfolgen, dann seriell ausgegeben werden, Ports
>rücksetzen, Zyklus Ende

Einfach.

>das 4x wobei ich eben nicht weiss ob die 4 in einem zeitlichen
>Zusammenhang stehen oder beliebig kommen können !

Schlecht.

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Lies etwas über das Thema Interrupt, speziell beim AVR.

hab ich und weiss nun mehr, also in der ISR sind die Interrupts default 
gesperrt, können aber mit sei() vor RTI enabled werden

> Solche Aussagen liebe ich . . .
ich auch

> Das macht ein Toggle FlipFlop, 74HC74, ganz ohne Programmierung.

ich hätte das IC gerne eingespart, einen Portpin in der ISR toggeln 
lassen, aber die zeitlichen Vorgaben passten eben nicht
ob nun 2 NAND als RS FF beschaltet werden oder 74HC74 ist hier und mir 
egal, als AHCT Type war das 7474 nicht verfügbar aber als 7400

> Oder auf Planlosigkeit . . .

kann ich halt nicht beurteilen, hab den Einsatzort und die Funktion nie 
zu Gesicht bekommen

> Muss ja ein tierisch schnelles Signal sein, das nicht mal 100ns warten
> kann. Mensch, in deinem Programm wird 48 MIKROSEKUNDEN gewartet, ehe
> überhaupt was losgeht!

wir wissen nicht warum genau da gemessen werden soll !

> Logisch, mindestens 4 Takte in reinem Assembler, in C eher 20 oder mehr.

habe ich ja ermittelt, ohne ins Datenblatt zu schauen, per Oszi

>Beschreibe die Aufgabe mal prinzipiell und mit ZAHLEN!

auf ein positives TTL Triggersignal 1µs lang und alle 10ms erscheinend 
soll A1 schnellstmöglich (unter 100ns) nach low gehen, A2 nach 50µs nach 
high, 100µs nach Trigger soll AD gewandelt werden und an der seriellen 
mit maximaler Baudrate ausgegeben werden

> Wurde schon diskutiert (Scheißdreck, meine i-Taste ist kaputt, nie mehr
> i-pad!).

mir ist eben mein Fritzbox Netzteil abgeraucht (vorigen Monat mein 
Desk), ich habe zwar ein passendes mit 12V 1,5A +innen aber in 5,5/2,1mm 
innen passt natürlich nicht
deswegen nun per wifi über Handy LOL

> Was die Begründunung für vier parallele AVR vollkommen aushebelt.

das verstehe ich nicht, ok, das parallele scheint mir nun auch Unfug zu 
sein

> Chinesenmethode. Kopf runter, Hirn aus, Chef wirds schon wissen.
> Funktioniert selten bis nie.

das weiss ich seit Jahren, aber die Chefs noch nicht, noch vor 18 Jahren 
habe ich derlei Aufträge abgelehnt, ich bin einfach zu faul blind 
loszumarschieren ohne zu wissen wohin der Weg führt und ob ich überhaupt 
ankommen kann, aber manchmal liebe ich die Herausforderung und manchmal 
mag ich nicht mehr gegen Windmühlen kämpfen

> NEIN! Eine! S&H

ist nun angekommen, aber wie schon gesagt, die software Filterung durch 
Mittelwertbildung könnte auch durch Tiefpass erfolgen, das würde die ADc 
readouts so verkürzen das sogar zeitnah alle Werte gesampelt werden 
können

> Er sampelt sie zeitversetzt, ganz einfach.

klingt plausibel

> Darf er.

gut ist angekommen

> Das du lange Quelltexte als Anhang posten sollst, nicht als Text im der
> Meldung. Siehe Netiquette.

OK auch kapiert

> uint8 Es ist allgemeinverständlich und standardkonform.
>>wird der Code schneller ?, spare ich Takte ?, spare ich RAM ?
>
> Ggf. ja.

sehe ich nicht, hinter meinem UWORD verbirgt sich doch genau dasselbe 
#define UWORD unsigned int was wohl identisch mit uint16 ist

>>>ISR(SIG_INTERRUPT1)
>>>Ist veraltet, dort kommt ein Vektorname rein.
>>ändert aber nix am Programm

> nein.

meintes du ja, es ändert nix am Programm oder nein es ändert was am 
Programm, wenn nein, was ändert es am Programm

>>>So dringend kann die Messung nicht sein, wenn erst mal 48µs gewartet
>>>wird.
>
>>das war die Vorgabe genau an dieser Stelle die Messung zu machen
> Chinesenmethode.

oder jugend forscht, das ist für mich kein Grund zu streiten, solange 
der Auftraggeber glücklich ist und das Ergebnis nicht nur zufällig mit 
der Erwartung passt

> Siehe Interrupt.

abgehakt

>>das 4x wobei ich eben nicht weiss ob die 4 in einem zeitlichen
>>Zusammenhang stehen oder beliebig kommen können !
> Schlecht.

bekomme ich vielleicht morgen noch raus, dann wird auch die unsinnig 
erscheinede synchronität diskutiert

von Joachim B. (jar)


Lesenswert?

spess53 schrieb:
> Vielleicht, weil ich mir keinen professionellen Programmierer vorstellen
> kann, der hier solche Fragen stellt?

weil ich vielleicht kein Programmier bin, das programmieren nur als 
"Arbeitserleichterung" nebenbei mache statt TTL Gräber zu verbauen?

ich mache hier alles, von Reparaturen bis Neubauten, von 0,1mA bis 100A 
von 10mV bis 100kV, von mHz bis 20MHz, von Röhren bis Microcontroller

sagt dir Steilheit, Durchgriff, Austastbalken was ? aus dieser Welt 
komme ich

zum Programmieren kam ich irgendwie nebenher weil der typische 
Programmierer (sorry Informatiker) eben ganz andere Schwerpunkte hat und 
mit dem drumherum selten was anfangen kann, dafür sind mir atomare 
Zugriffe eben Fremdwörter.

Meine ersten Assemblerprogramme habe ich auf Karopapier entworfen weil 
es keine käuflichen Entwicklungssysteme oder gar LIBs gab die in 
Stückzahlen günstig eingesetzt werden konnten. Meine ersten Programme 
entstanden mit Schaltdraht auf einem Steckbrett 9-bit zu einer Zeit als 
man jedes Bit noch persönlich kannte, ist länger her. Deswegen bin ich 
eben kein Spezialist,
kennst du die Definition von Spezialistentum ?

Es gibt immer mehr Menschen die von immer weniger immer mehr wissen bis 
sie alles von nichts wissen. ;-)

LG
jar

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Nur noch ein Tip: Wenn du wirklich möchtest, das ein Interrupt durch 
einen anderen Interrupt unterbrochen werden kann , dann gibt es dafür 
eine 'offizielle' Syntax, nachzulesen in der Sektion über Interrupts der 
avr-libc:
1
ISR(ADC_vect, ISR_NOBLOCK) {
2
}
Ebenso gibt es die Syntax, bei der du alles alleine im Interrupt 
erledigen muss, z.B. cli() und sei():
1
ISR(ADC_vect, ISR_NAKED) {
2
}
Joachim B. schrieb:
> weil ich vielleicht kein Programmier bin, das programmieren nur als
> "Arbeitserleichterung" nebenbei mache statt TTL Gräber zu verbauen?
>
> ich mache hier alles, von Reparaturen bis Neubauten, von 0,1mA bis 100A
> von 10mV bis 100kV, von mHz bis 20MHz, von Röhren bis Microcontroller
Ja, ja, das alles habe ich auch gemacht, aber wenns nun mal ein 
Mikrocontroller sein soll, dann muss man sich damit eben beschäftigen. 
Du kannst deine Erfassung auch als TTL Grab bauen.

Da du aber recht beratungsresistent erscheinst, klinke ich mich hiermit 
aus. Ich (und viele andere hier) haben schon einige sehr zeitkritische 
Sachen programmiert (und das auf winzigen AVRs), und dir eigentlich ne 
Menge Tipps zukommen lassen wollen. Aber du hast dich da in was 
verrannt, was wir mit guten Worten nicht aus dir rauszukriegen scheinen. 
Schönes Leben noch.

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)


>> Das macht ein Toggle FlipFlop, 74HC74, ganz ohne Programmierung.

>ich hätte das IC gerne eingespart, einen Portpin in der ISR toggeln
>lassen, aber die zeitlichen Vorgaben passten eben nicht

Eben.

>ob nun 2 NAND als RS FF beschaltet werden oder 74HC74 ist hier und mir
>egal,

Mehr oder weniger.

> als AHCT Type war das 7474 nicht verfügbar aber als 7400

Warum AHCT? HCT tut es locker, der schaltet auch in 20ns und weniger. 
SOOOO schnell kann das alles nicht sein, glaub ich zumindest erst dann, 
wenn eindeutig und ausführlich die Anwendung dargestellt wird.

>sehe ich nicht, hinter meinem UWORD verbirgt sich doch genau dasselbe
>#define UWORD unsigned int was wohl identisch mit uint16 ist

Eben das ist doppelt gemoppelt. Ein uint8_t ist SICHER 8 Bit breit und 
mittlerweile lange auf so ziemlich jedem Compiler Standard. Ein int kann 
16 oder 32 Bit breit sein, mein Kollege neben mir behauptet sogar, dass 
auf seinem Compiler für kleine Mikrocontroller int nur 8 Bit ist!
Und warum zum Teufel muss jeder Programmierer elementare Datentypen 
immer wieder neu erfinden?

>>>>ISR(SIG_INTERRUPT1)
>>>>Ist veraltet, dort kommt ein Vektorname rein.
>>>ändert aber nix am Programm

>> nein.

>meintes du ja, es ändert nix am Programm

Ja, es ändert nichts am Programm. ;-)

von Joachim B. (jar)


Lesenswert?

Matthias Sch. schrieb:
> Da du aber recht beratungsresistent erscheinst, klinke ich mich hiermit
> aus. Ich (und viele andere hier) haben schon einige sehr zeitkritische
> Sachen programmiert (und das auf winzigen AVRs), und dir eigentlich ne
> Menge Tipps zukommen lassen wollen. Aber du hast dich da in was
> verrannt, was wir mit guten Worten nicht aus dir rauszukriegen scheinen.
> Schönes Leben noch.

ich sehe mich nicht als beratungsresistent, ich denke wir reden nur 
aneinander vorbei

klaro schmeisse ich die überflüssigen Anweisungen raus, lese mich auch 
in die AVR Interruptabarbeitung ein.

Meiner Meinung nach möchtest du die Vorgaben ignorieren, warum auch 
immer, über die Sinnhaftigkeit der Vorgaben bin ich zur Diskusion 
bereit, aber ignorieren derselben ohne weiteres Hintergrundwissen eben 
nicht.

trotzdem Danke für deine Zeit und Tipps

von Berater (Gast)


Lesenswert?

Hallo Joachim,

Joachim B. schrieb:
> über die Sinnhaftigkeit der Vorgaben bin ich zur Diskusion
> bereit
OK. Ich würde genau diese Diskussion mit den Auftraggebern anstreben 
(hätte ein Projekt, bei dem mir den Einsatzzweck verschwiegen wird und 
scheinbar unsinnige Vorgaben gemacht werden, hier der Hersteller des µC, 
eh' nicht angenommen... Eventuell ist Dein Auftraggeber ja bereit, sich 
von Dir beraten zu lassen.).

Gruß
Berater

von Dietrich L. (dietrichl)


Lesenswert?

Mal zurück zum Anfangsansatz:

jar schrieb:
> ...sollen 4 AVR syncron laufen

Wenn man das tatsächlich mit 4 AVRs lösen will/muss:

Warum sollen die eigentlich synchron laufen?

Wenn ein AVR für die Anwendung schnell genug reagiert, dann tun es 
doch auch 4, wenn sie asynchron laufen!? Lediglich ein Jitter entsteht, 
um den laufenden Befehl zu beenden bis die ISR beginnt. Du sagtest mal 
was von 55ns - das sollte doch für die Asynchronität klein genug sein?

Die Zeit kann natürlich größer sein, wenn es noch andere ISRs gibt - 
aber das Problem gilt ja auch für einen einzelnen AVR.

Nur mal so in den Raum geworfen...

Gruß Dietrich

von Joachim B. (jar)


Lesenswert?

Berater schrieb:
> Eventuell ist Dein Auftraggeber ja bereit, sich
> von Dir beraten zu lassen.

mal sehen, evt. wirds ja was, auch meine Auftraggeber müssen lernen das 
es nie so geht wie sie denken (letztes Beispiel) Netzeil im Rack planen, 
ich sag der Träger kommt um die 200€, zu teuer gibt 19" Racks schon für 
50€, wird bestellt und liegt nun unbrauchbar hier rum, keine 
Trägerplatte, keine Modulschienen, klar kann man alles irgendwo fertigen 
lassen aber nicht günstiger - Konstruktionsunterlagen für die Mechanik 
erstellen - oder nachordern, Kataloge wälzen, aber leichter und 
schneller wäre das bekannte Modulsystem für - Angebot liegt vor - 147€ 
zu nehmen (ich wusste das vorher, aber manchmal muss man derlei Wünsche 
einfach auflaufen lassen, wenn meine Beratung nicht gefragt ist)

von Joachim B. (jar)


Lesenswert?

Dietrich L. schrieb:
> Warum sollen die eigentlich synchron laufen?

das versuche ich heute rauszubekommen, jetzt nach der Diskusion mit euch 
erscheint mir das auch unsinnig, ich gestehe ich habe mangels Prüftiefe 
nicht darüber nachgedacht und dem Auftraggeber vertraut, wenn der 
Synchronität wünscht sollte er wissen warum !

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Warum AHCT? HCT tut es locker, der schaltet auch in 20ns und weniger.
> SOOOO schnell kann das alles nicht sein, glaub ich zumindest erst dann,
> wenn eindeutig und ausführlich die Anwendung dargestellt wird.

zuerst war schnellstmöglich gefordert und da ist der AHCT ne Winzigkeit 
schneller, dann musste die galvanische Trennung nachträglich integriert 
werden, sauschnelle Optokoppler kosten halt und plötzlich waren 55ns 
kein Problem mehr.......

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Von Sinn und Unsinn mal abgesehen, wenn es eh ein Triggersignal für die 
Wandlung gibt.
Bei einem Mega88 kann man eine ADC Wandlung durch einen externen 
Interupt triggern lassen:
1
Alternatively, a conversion can be triggered automatically by various sources. Auto Triggering is
2
enabled by setting the ADC Auto Trigger Enable bit, ADATE in ADCSRA. The trigger source is
3
selected by setting the ADC Trigger Select bits
Dann könne die AVRs auch asyncron laufen, die Daten können bequem im 
Interrupt abgeholt werden...
1
A conversion
2
will be triggered by the rising edge of the selected Interrupt Flag source
3
- Free running mode
4
- Analog comparator
5
- External interrupt request 0
6
- Timer/counter0 compare match A
7
- Timer/counter0 overflow
8
- Timer/counter1 compare match B
9
- Timer/counter1 overflow
10
- Timer/counter1 capture event

von Joachim B. (jar)


Lesenswert?

wollte allen Helfern eine kleine Rückmeldung geben

es wird ein Trigger genutzt für 4 Wandlungen

am sinnvollsten wäre wirklich eine SH Schaltung und ein AVR, aber das 
ist zeitlich nicht mehr zu schaffen, also bleibt es bei 4x AVR, 
wohlwissend das das auch 4x AD-Wandungsfehler bedeutet.

Der gemeinsame Takt ist auch meiner Meinung nach Unfug weil innerhalb 
der Wartzeit vom Trigger 100µs bis AD Wandlung (die 100µs waren die 
Bedingung bevor die Wandlung beginnt) auch bei 4 Quarze die 4 AVR nicht 
unendlich von einander wegrennen.

Die Wandlung, wie auch immer versetzt, mit einem AVR durchzuführen wurde 
unter allen Umständen abgelehnt

Danke an alle Helfer

gruss
jar

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> Die Wandlung, wie auch immer versetzt, mit einem AVR durchzuführen wurde
> unter allen Umständen abgelehnt
Welcher "Versatz" ist denn (in Zahlen mit Einheit) überhaupt erlaubt?

> aber das ist zeitlich nicht mehr zu schaffen
Und hier? Gibt es hier auch definierte Zeitangaben?
Ich könnte mir hier z.B. auch einfach 4 solche kleine SPI-AD-Wandler 
vorstellen, die mit 1 Takt, 1 Slave-Select und 1 MOSI angesteuert 
werden, aber zusammen parallel 4 MISO zurückgeben. Das kostet gerade mal 
1 Tag und alles ist exakt synchron, parallel und locker auf 12-14 Bit 
genau...

Und zudem wären dann die Daten schon in 1 uC gesammelt. Denn schon der 
Aufwand, hinterher den 4 uCs die Daten rauszubetteln, ist sicher nicht 
unerheblich...

von Berater (Gast)


Lesenswert?

> auch bei 4 Quarze
Denke auch an die Möglichkeit, die Dir die Clock-Out Option bei einigen 
der AVRs bietet: so reicht oft ein Quarz für mehrere µCs.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Joachim B. schrieb:
> es wird ein Trigger genutzt für 4 Wandlungen
>
> am sinnvollsten wäre wirklich eine SH Schaltung und ein AVR, aber das
> ist zeitlich nicht mehr zu schaffen,

Du meinst im Timing oder in der Vorgabe, wann du mit dem Projekt fertig 
sein musst? Der Trigger könnte ja easy direkt die Hardware S&H auslösen 
und dann kommt der AVR und liest die 4 Werte aus. Das ganze ist ein 
Qualitätsanalogschalter, 4 Speicher-Cs und evtl. ein Monoflop zur 
Triggeraufbereitung. Spart das ganze Synchronbrimborium und das 
Clockmanagement.
Denn entweder verteilst du eine Clock über die Platine (EMV lässt 
grüssen) oder du hoffst, das die Quarze im Laufe der Zeit nicht 
auseinander wandern, abgesehen davon, 4 AVRs zu verbraten.

Joachim B. schrieb:
> Die Wandlung, wie auch immer versetzt, mit einem AVR durchzuführen wurde
> unter allen Umständen abgelehnt

Das klingt immer noch nach Unsinn. Wenn sie so genau wissen, was sie 
nicht wollen, ist ja eine vernünftige Projektplanung gar nicht möglich. 
Mein Rat: Klink dich da aus, solange es geht. Die werden immmer wieder 
ankommen und noch ein Haar in der Suppe, die du gekocht hast, finden. 
Das wird die paar Mäuse nicht wert sein, die du da verdienen kannst.

von Joachim B. (jar)


Lesenswert?

Lothar Miller schrieb:
>> Die Wandlung, wie auch immer versetzt, mit einem AVR durchzuführen wurde
>> unter allen Umständen abgelehnt
> Welcher "Versatz" ist denn (in Zahlen mit Einheit) überhaupt erlaubt?

von den Vorgaben ist praktisch kein Versatz erlaubt ! ( die x ns die 
mehrere AVR abweichen können wird / muss geduldet werden )

>> aber das ist zeitlich nicht mehr zu schaffen
>Das kostet gerade mal
> 1 Tag und alles ist exakt synchron, parallel und locker auf 12-14 Bit
> genau...

nicht mit Layout, Musterbau, SW und Probe, das sollte schon vor 2 Wochen 
fertig sein
was geht und getestet wurde, der Prototyp mit einem AVR, 4 werden es 
auch hinreichend bringen

> Aufwand, hinterher den 4 uCs die Daten rauszubetteln, ist sicher nicht
> unerheblich...

geht von 4 AVR mit ihren 4 RS232 Ports mit je 115k Bd raus, ob da eine 
Workstation gebraucht wird oder ein low cost PC, macht ein externer 
Programmierer, mach ich mir keinen Kopf mehr !


Berater schrieb:
>> auch bei 4 Quarze
> Denke auch an die Möglichkeit, die Dir die Clock-Out Option bei einigen
> der AVRs bietet: so reicht oft ein Quarz für mehrere µCs.

hab ich auch schon dran gedacht, würde aber genau wie beim zentralen TTL 
Generator Baugruppenstacking bedeuten und dann wären die 4 nicht mal 
eben im BG Träger umzustecken, finde ich serviceunfreundlich.

atthias Sch. schrieb:
> Das klingt immer noch nach Unsinn. Wenn sie so genau wissen, was sie
> nicht wollen, ist ja eine vernünftige Projektplanung gar nicht möglich.
> Mein Rat: Klink dich da aus, solange es geht. Die werden immmer wieder
> ankommen und noch ein Haar in der Suppe, die du gekocht hast, finden.
> Das wird die paar Mäuse nicht wert sein, die du da verdienen kannst.

ich kann mich da nicht (oder nur bedingt) ausklinken, bin ja nicht 
(ganz) selbstständig

ganz ausklinken ginge nur wenn irgendwas gegen höheres Recht verstößt 
;-) was hier wohl nicht anwendbar ist

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>> Welcher "Versatz" ist denn (in Zahlen mit Einheit) überhaupt erlaubt?

>von den Vorgaben ist praktisch kein Versatz erlaubt !

Das ist praktisch Unsinn, erst recht mit mehreren AVRs. Allein die 
Unschärfe des Interrupteinsprungs liegt bei 1-2 Takten, je nachdem, 
welcher Befehl gerade abgearbeitet wird.

>( die x ns die
>mehrere AVR abweichen können wird / muss geduldet werden )

Wer nicht willens ist, seine festgefahrene Denkweise zu ändern, muss 
halt damit leben. Gute Vorschläge gibt es zur Genüge.

>geht von 4 AVR mit ihren 4 RS232 Ports mit je 115k Bd raus, ob da eine
>Workstation gebraucht wird oder ein low cost PC, macht ein externer
>Programmierer, mach ich mir keinen Kopf mehr !

;-)
Workstation für vier pissige RS232, weil keiner im Projekt einen Plan, 
geschweige denn Arsch in der Hose hat. Es geht bergab . . .

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> Es geht bergab . . .

Sach ich doch: der Ingenieurmangel ist keine Lüge.  (kein Smiley)

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Falk Brunner schrieb:
> Workstation für vier pissige RS232, weil keiner im Projekt einen Plan,
> geschweige denn Arsch in der Hose hat. Es geht bergab . . .

Also, jetzt kapiers ichs noch weniger :-O Wenn da schon ne Workstation 
dauernd laufen muss, um die 4 RS232s zu vermanschen, wieso steckt man da 
nicht ne anständige A/D Karte mit 4 Flashwandlern und vllt. einem 
Digital I/O für den Trigger in die Kiste? Und wenn kein Steckplatz mehr 
frei ist, zieht man die 4-fach serielle Karte raus :-)

jar schrieb:
> für ein kleines Projekt sollen 4 AVR syncron laufen

Und am Anfang klang das alles so harmlos...

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Workstation für vier pissige RS232, weil keiner im Projekt einen Plan,
> geschweige denn Arsch in der Hose hat. Es geht bergab . . .

Matthias Sch. schrieb:
> Also, jetzt kapiers ichs noch weniger :-O Wenn da schon ne Workstation
> dauernd laufen muss, um die 4 RS232s zu vermanschen,

irgendwie ist meine Ironie mit Sarkasmus wohl nicht angekommen :-)

ich schrieb doch extra, ob da eine Workstation oder ein PET2001 das 
auswertet ist MIR egal weil das ein externer Programmierer macht, mit 
den Infos die ich zum Auftrag bekam konnte nix besseres rauskommen und 
ich fang für diesen Auftrag kein extra Studium an.

Falk Brunner schrieb:
> Wer nicht willens ist, seine festgefahrene Denkweise zu ändern, muss
> halt damit leben. Gute Vorschläge gibt es zur Genüge.

wenn du mich meinst, ich hab alles versucht dem Auftraggeber mehr Infos 
zu entlocken, das einzige was zurückkam, geht nicht, soll wie geplant 
gemacht werden, ist eh spät ! zu spät für Neuentwicklung

zuerst hiess es ja ein Controller, dann 4, dann 4 Signale, dann erst 1 
Trigger, dann erst zeitgleich......

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> zuerst hiess es ja ein Controller, dann 4, dann 4 Signale, dann erst 1
> Trigger, dann erst zeitgleich

Hoffentlich hast du einen Vertrag, mit dem du nach Stunden bezahlt
wirst.

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>> Wer nicht willens ist, seine festgefahrene Denkweise zu ändern, muss
>> halt damit leben. Gute Vorschläge gibt es zur Genüge.

>wenn du mich meinst,

Nur ein bisschen, den meisten Bockmist scheint ja dein starrköpfiger 
Auftraggeber verzapft zu haben.

> ich hab alles versucht dem Auftraggeber mehr Infos
>zu entlocken, das einzige was zurückkam, geht nicht, soll wie geplant
>gemacht werden,

Fünfjahresplan der KPdSU?

von Joachim B. (jar)


Lesenswert?

Jörg Wunsch schrieb:
> Joachim B. schrieb:
>> zuerst hiess es ja ein Controller, dann 4, dann 4 Signale, dann erst 1
>> Trigger, dann erst zeitgleich
>
> Hoffentlich hast du einen Vertrag, mit dem du nach Stunden bezahlt
> wirst.

melde gehorsamst das ja ! ;-)

und nun fangen wir gerade an die 100V Quellenfrage zu diskutieren

1 Netzteil ? Leistungsbedarf geschätzt, Ripple unbekannt
4 Netzteile ?
4 DC/DC Wandler ?

usw. usf.

also verdammt mich nicht, bemitleidet mich eher :D :D

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Ach ja, es ist noch ein fieser Zugriffsfehler auf "result" drin, denn
> der ist nicht atomar, siehe Interrupt. Jaja, der tritt nur sehr
> selten auf, aber genau DAS ist die Gefahr!

bin gerade dabei alles "unsinnige" oder alte rauszuwerfen, (die Platinen 
werden bestellt)

was genau meinst du ? den 16 Bit Zugriff allgemein ? das sich high und 
low Byte während des Zugriffs ändern können ? dem könnte doch vor dem 
result Auslesen mit cli(); und nach dem Auslesen mit sei(); abgeholfen 
werden ?

bzw. könnte man auch in einer Schleife lesen bis sich result nicht 
ändert ?

so genau weiss ich noch nicht was du meinst

von Falk B. (falk)


Lesenswert?

@Joachim B. (jar)

>bin gerade dabei alles "unsinnige" oder alte rauszuwerfen, (die Platinen
>werden bestellt)

Auch die Workstation ? ;-)

>was genau meinst du ? den 16 Bit Zugriff allgemein ? das sich high und
>low Byte während des Zugriffs ändern können ?

Ja, siehe Interrupt.

> dem könnte doch vor dem
>result Auslesen mit cli(); und nach dem Auslesen mit sei(); abgeholfen
>werden ?

Ja, nennt man atomaren Zugriff, siehe Artikel oben. Man greift in MAIN 
EINMAL atomar zu und kopiert es in eine lokale Variable, die kann man 
dann ganz entspannt auswerten.

1
cli();
2
if (result) {
3
  my_result=result;
4
  result=0;
5
} else my_result=0;
6
sei();

>bzw. könnte man auch in einer Schleife lesen bis sich result nicht
>ändert ?

Nein.

von Joachim B. (jar)


Lesenswert?

danke Falk !

Falk Brunner schrieb:
>>>ISR(SIG_INTERRUPT1)
>>>Ist veraltet, dort kommt ein Vektorname rein.

manno,
so funktioniert mit das eben nicht -> ISR(INT1)
so funktioniert mit das -> ISR(SIG_INTERRUPT1)

ich bin eigentlich nicht beratungsresitent aber mir nun einen Wolf 
suchen wie der richtige Vectorname ist erscheint mir auch nicht zwingend 
sinnvoll, wenn jemand helfen mag, nehme ich gerne an

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:
> danke Falk !
>
> Falk Brunner schrieb:
>>>>ISR(SIG_INTERRUPT1)
>>>>Ist veraltet, dort kommt ein Vektorname rein.
>
> manno,
> so funktioniert mit das eben nicht -> ISR(INT1)
> so funktioniert mit das -> ISR(SIG_INTERRUPT1)

ISR( INT1_vect )

(oder so ähnlich. Schau halt ins Header File, wie der Vektorname 
wirklich ist. Die enden alle auf '_vect')

> suchen wie der richtige Vectorname ist erscheint mir auch nicht zwingend
> sinnvoll, wenn jemand helfen mag, nehme ich gerne an

Grundregel 1 in der Programmierung:

Jede, aber auch wirklich jede, Schlamperei fällt die irgendwann auf den 
Kopf! Wenn nicht heute, dann morgen oder übermorgen. Und meistens dann, 
wenn du es am wenigsten gebrauchen kannst.
Frag nicht wie sie dir auf den Kopf fallen wird, denn das kannst du dir 
heute sowieso nicht vorstellen und meistens kommt es dann sowieso noch 
schlimmer.

(Mich würde ja immer noch interessieren, was das alles überhaupt werden 
soll)

von Falk B. (falk)


Lesenswert?

@  Joachim B. (jar)

>suchen wie der richtige Vectorname ist erscheint mir auch nicht zwingend
>sinnvoll, wenn jemand helfen mag, nehme ich gerne an

Die Jungs von AVR-GCC waren so schlau die EXAKT gleichen Namen aus dem 
Datenblatt zu übernehmen. Kann man in den Headerfiles nachlesen, unter

C:\Programme\WinAVR-20080610\avr\include\avr\

INT0_vect

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Die Jungs von AVR-GCC waren so schlau die EXAKT gleichen Namen aus dem
> Datenblatt zu übernehmen. Kann man in den Headerfiles nachlesen, unter

hast du andere Datenblätter ? ich sehe das hier

Vector no. Program address(2) Source Interrupt definition
3 .........0x0004 INT1 External interrupt request 1

wurde aber mit
INT0_vect beantwortet, also hier:

INT1_vect (danke)


für my_result brauche ich also nioch eine 16 Bit Variable
das mit dem 2x auslesen dachte ich mir ja, wurde verneint
wo wird da auf result reagiert ?

cli();
if (result) {
  my_result=result;

// Reaktion hier ? wozu dann nach my_result kopieren ?

  result=0;
} else my_result=0;
sei();

// Reaktion hier ? sieht vernünftig aus, dann aber my_result nutzen, 
wird erst im nächsten Durchlauf null

von Falk B. (falk)


Lesenswert?

@Joachim B. (jar)

>cli();
>if (result) {
>  my_result=result;

>// Reaktion hier ? wozu dann nach my_result kopieren ?

NEIN!

>  result=0;
>} else my_result=0;
>sei();

>// Reaktion hier ? sieht vernünftig aus, dann aber my_result nutzen,
>wird erst im nächsten Durchlauf null

Ja.

von Joachim B. (jar)


Lesenswert?

Falk Brunner schrieb:
> Ja

schon erledigt, DANKE nochmals

ich melde mich wenn die Platinen da sind und die Kiste läuft (wenns 
interessiert?)

für alle die mir geholfen haben eine kleine Rückmeldung soweit ich kann, 
ich habe ja kein Zugriff auf den gesamten Aufbau, nur auf die 
Controllerbüchse ohne Trigger und Spannungslieferanten.

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.