Hallo,
ich habe ein hoffentlich kleines Problem:
Eine Anwendung in einem ATMega32 soll zwei 512 Byte große Bereiche im
Datensegment benutzen. Bis Dato kein Problem:
.DSEG
Buffer1: .BYTE 512
Buffer2: .BYTE 512
Über eines der drei "Spezialregister" (X, Y, Z) kann ich auch auf die
Bereiche mit LD bzw ST zugreifen. Dazu initialisiere ich erst mal eines
der Register(hier X)
LDI XH, HIGH(Buffer1)
LDI XL, LOW(Buffer1)
Irgendwann kommt dann der Zugriff bspw. so:
ST X+, temp
Auch das funktioniert.
Jetzt will ich aber nicht mehr als 512 Bytes in einen Buffer schreiben.
If muss also irgendwie überprüfen, dass das X-Register ein Wert von
Buffer1 + 512 enthält, ich weiß bloß noch nicht wie. Der Zugriff auf
16Bit-Register ist ja nunmal gelinde gesagt bescheiden. Sprich, es
greift kein Compare oder irgendetwas in der Richtung.
Das Einzige was mir jetzt einfällt, dass ich ein zweites 16Bit Register
benutze und die Inhalte der jeweilige beiden 8Bit-Register gegeneinander
vergleiche.
Also ich initialisiere
X mit Buffer1
Y mit Buffer2
Nach dem Speichern überprüfe ich ob
XH = YH und XL = YL
Nur kosten solche Vergleiche wirklich Zeit und die habe ich nicht(Ich
meine jetzt nicht das Programmieren sondern die Laufzeit).
Bin dankbar über jeden Tipp.
--
Gruß Scotty
Hi
Überleg mal. 512 ist Hexadezimal $0200. D.h. Wenn XH 2 wird hast du die
512 Bytes überschritten.
ST X+, temp
cpi XH,2
brcs xyz ->springt wenn <512 Bytes
oder
brcc xyz -> springt,wenn >512 Bytes
MfG Spess
Hallo
Überleg doch bitte auch mal:
Ich schrieb das ich das X-Register initialisiere. Wenn Buffer1 am Anfang
des Datensegments steht beinhaltet
X = 0x0060
512 Bytes aufaddiert ergibt
X = 0x0260
Wenn ich also einfach das XH-Register auf 0x02 vergleichen würde, würde
die Routine 0x60 Bytes zu früh abbrechen.
Aber netter Versuch.
--
Gruß Scotty
Hallo,
Scotty schrieb:
> Hallo>> Überleg doch bitte auch mal:>> Ich schrieb das ich das X-Register initialisiere. Wenn Buffer1 am Anfang> des Datensegments steht beinhaltet> X = 0x0060>> 512 Bytes aufaddiert ergibt> X = 0x0260>> Wenn ich also einfach das XH-Register auf 0x02 vergleichen würde, würde> die Routine 0x60 Bytes zu früh abbrechen.>> Aber netter Versuch.
in solchen Fällen macht es dann oft Sinn, die Buffer passend anzulegen:
.DSEG
.ORG 0x0100
Buffer1: .BYTE 512
Buffer2: .BYTE 512
Gruß aus Berlin
Michael
man kann auch einfach einen sauberen vergleich programmieren....
ldi r16, LOW(Buffer1+512)
ldi r17, High(Buffer1+512)
cp XL, r16
cpc XH, r17
breq ...
oder wie du es halt brauchst. Nimm einfach irgendein registerpaar. Das
musst du nur einmal initialisieren. Nach dem Compare kannst du die
Branch-operationen wie gewohnt verwenden.
Ach, und schau dir mal an, was cpc macht.
Sebastian
Hi
Hast Recht. Dann würde ich die Puffer ab $0400 ansiedeln. Die Frage ist
nur, wo du den Stack hinlegst. Wenn du mit 96 Bytes auskommst kann er
immer noch an das Ramende. Ansonsten nach $3FF.
MfG Spess
Scotty schrieb:
> Der Zugriff auf> 16Bit-Register ist ja nunmal gelinde gesagt bescheiden. Sprich, es> greift kein Compare oder irgendetwas in der Richtung.
Das stimmt so nun ja auch nicht. Zu den meisten 8bit Befehlen nennt
Amtel in der AVR Hilfe wie man diese auf 16 bit aufbohren kann.
Wenn ich mich recht erinnere kann man es dann so machen:
1
cp XL, ZL
2
cpc XH, ZH
3
breq viel zu groß....
Scotty schrieb:
> Nur kosten solche Vergleiche wirklich Zeit und die habe ich nicht
Erm... Wie willst du das den ohne Vergleich machen? So ein 16bit
Vergleich benötigt gerade mal einen Takt länger also das ist doch echt
geschenkt.
>> Der Zugriff auf>> 16Bit-Register ist ja nunmal gelinde gesagt bescheiden. Sprich, es>> greift kein Compare oder irgendetwas in der Richtung.> Das stimmt so nun ja auch nicht. Zu den meisten 8bit Befehlen nennt> Amtel in der AVR Hilfe wie man diese auf 16 bit aufbohren kann.> Wenn ich mich recht erinnere kann man es dann so machen:> cp XL, ZL> cpc XH, ZH> breq viel zu groß....
Hallo
Ok, das hatte ich schon erfahren und wirklich ein guter Tipp
>> Nur kosten solche Vergleiche wirklich Zeit und die habe ich nicht> Erm... Wie willst du das den ohne Vergleich machen?
Du brauchst nicht zu stutzen, ist wirklich so.
> So ein 16bit> Vergleich benötigt gerade mal einen Takt länger also das ist doch echt> geschenkt.
Nein, es sind 512 Takte. Es müssen erst 512 Bytes empfangen werden, bis
die zuverarbeitenden Routine den Buffer "anfassen darf". Es wird immer
zwischen den Buffern "umgeschaltet". Während der eine gefüllt wird, wird
der andere abgearbeitet damit das Ganze "flüssig" wird. Deswegen muss
die zufüllenden Routine immer schneller sein als die abarbeitende. Jeder
Takt der beim befüllen entsteht verringert die Zeit zum Abarbeiten und
Füllen. Deswegen ist jeder Takt zu viel wenn er nicht sein müsste.
--
Gruß Scotty
Wenn du am Anfang immer einen lehren Puffer hast den du immer ohne
unterbrechung komplett voll machst kannst du ja einfach mitzählen....
Am einfachsten ne schleife von 256 runter und eine von 2 runter
ausenrumgebaut. Viel schneller dürfts wohl kaum noch möglich sein.
Sebastian
Schleife Zählen und Vergleichen kostet auch Takte. Du könntest einen
Teil der Hardware zum Mitzählen nutzen, nämlich einen 8-Bit-Timer. Lasse
immer, wenn Du Deine Speicherroutine durchlaufen hast, einen Pin den
Pegel wechseln und zwar einen, der hardwareseitig an den Timer
angekoppelt ist, also T0 (PortB0), schließe nichts an diesem Pin an,
stelle ihn aber auf Ausgang. Stelle die Taktquelle für diesen Timer
auf extern, steigende Flanke. Setze den Timer und den Pinpegel vor dem
ersten Einsprung in die Speicherroutine zurück. Wenn der Timer
übergelaufen ist, kannst Du einen Interrupt auslösen, der Dir sagt, daß
der Speicherbereich nun voll ist.
Also wenn es dermaßen knapp ist, sollte man auf einen anderen mC
wechseln oder den Takt erhöhen.
Wo kommen die Daten überhaupt her? Werden die sequentiell eingelesen
oder "ab und zu" z.B. vom ADC Interrupt?
Empfangen hört sich für mich nach RS232 an.... wie synconisierst du den
Buffer Zugriff?
Und hast du wirklich Zeitprobleme in der Verarbeitungsroutine oder
denkst du nur es wäre gut so schnell wie möglich zu arbeiten?
@travelrec
Die Geschichte mit dem Timer hört sich interessant, in diesem Projekt
werde ich das aber wohl nicht einsetzen köönen. Werde ich mir aber auf
jeden Fall merken.
@All
Die Datenquelle ist die RS232 resp. USB-Schnittstelle. Erklärung:
Die beiden "Speicherbänke" brauche ich um einen asynchrone Abarbeitung
zu gewährleisten. Es wird immer eine Bank gefüllt und die andere
abgearbeitet. Ist die 1. Bank gefüllt beginnt der µC diese abzuarbeiten.
Gleichzeitg beginnt er die 2. Bank zu füllen. Ist der µC mit der
Abarbeitung der 1. Bank fertig arbeitet Er die 2. Bank ab. Dabei wird
dann gleichzeitg die 1. Bank wieder befüllt. So geschieht das immer im
Wechsel, eine Bank füllen und die andere abarbeiten.
Dieses Verfahren setzt aber vorraus, dass das Füllen im schneller ist
als das Abarbeiten. Beim Abarbeiten werden immer 2 Bytes aus dem
Speicher betrachtet, also 256 Vörgange, So ein Vorgang sollte ca. 1 ms
dauern. Ergo benötigt die komplette Abarbeitung ca. 250 ms einer
Speicherbank. Unterhalb dieser Zeit nuss dann natürlich die andere Bank
befüllt werden. 250 ms hört sich zwar viel an, doch kann ich mir
durchaus vorstellen, das ich an gewisse Grenzen stoße, also versuche ich
von vornherein möglichst wenig Zeit für das Befüllen in Anspruch zu
nehmen.
Vielleicht bin ich einfach zu vorsichtig, doch nur wenn ich so an das
Problem gehe habe ich Chancen das Vorhaben überhaupt zu realisieren.
--
Gruß Scotty
Scotty schrieb:
> Beim Abarbeiten werden immer 2 Bytes aus dem> Speicher betrachtet, also 256 Vörgange, So ein Vorgang sollte ca. 1 ms> dauern.
Das sind dann bei 20MHz also 20.000 Zyklen und da willst Du mir weiß
machen, daß der zusätzliche eine Zyklus (=0,005% CPU-Last) für nen 16Bit
Vergleich zuviel ist?
Mach Dich doch nicht lächerlich.
Peter
Scotty schrieb:
> Vielleicht bin ich einfach zu vorsichtig, doch nur wenn ich so an das> Problem gehe habe ich Chancen das Vorhaben überhaupt zu realisieren.
Nö, Vorsicht allein nützt garnichts, man muß nachrechnen.
Peter
Scotty schrieb:
> 250 ms hört sich zwar viel an, doch kann ich mir> durchaus vorstellen, das ich an gewisse Grenzen stoße, also versuche ich> von vornherein möglichst wenig Zeit für das Befüllen in Anspruch zu> nehmen.
Falscher Ansatz! Wenn es wirklich am Befüllen scheitern sollt dann
kannst du dir Gedanken machen das zu Beschleunigen. Vorher ist das
verschwendete zeit (deine und unsere nicht die des uC) weil vermutlich
eh die RS232 die Engpassstelle ist oder deine "Abarbeitungsroutine"
@Peter
Ich programmiere seit über 25 Jahren und glaube mir, da ist schon
einiges "gegen die Wand gefahren" nur weil man im Vornherein falsch
gerechnet und Randbedingungen ausser Acht gelassen hat.
Hatte ich an dieser Lösung auch schon weil ich auf den Latency-Timer des
USB reingefallen bin.
Nur mal eine theoretische Rechnung:
115.200 Baud 8,N,1
ergibt theoretisch 11.520 Bytes die pro Sekunde übertragen werden
können.
Kaum zu glauben wenn man dann aber feststellt des nur 1000 gesendete und
1000 empfangene Bytes waren.
Kannst du jeder Zeit prüfen. Schick mal 1000 enzelne Bytes zu Deinem µC,
dieser soll nach jedem Byte ein Byte zurückschicken.
@Läubi
> Falscher Ansatz! Wenn es wirklich am Befüllen scheitern sollt dann> kannst du dir Gedanken machen das zu Beschleunigen. Vorher ist das> verschwendete zeit (deine und unsere nicht die des uC) weil vermutlich> eh die RS232 die Engpassstelle ist oder deine "Abarbeitungsroutine"
Ich habe nie aufgefordert sich über mein Vorhaben Gedanken zu machen
oder Zeit zu verschwenden.
Ich habe eine Frage gestellt, und die betraf wie ich das SRAM vernüftig
adressiere, darauf habe ich auch Anworten bekommen, die mir
weitergeholfen haben, dafür danke ich auch.
Hier wurde aber spekuliert, wo meine Datenpuelle ist, obwohl das
eigentlich nicht zum Thema gehört. Deswegen habe ich versucht Euch
aufzuklären welches diese ist.
@All
Dieses Forum, ist wirklich nicht das man sich wünschen sollte. Hier wird
man nach relativ kurzer Zeit als "Idiot abgestempelt". Relativ wenig
wirklich hilfreiche Beiträge. Es wird eine Frage gestellt und irgend
Jemand antwortet darauf mit "Ich würde so machen...". Das ist nicht
hilfreich, da noch nicht mal der Grund genannt warum dieser Jemand es
anders machen würde.
Ich versuche meine Fragen zu so zu stellen, das es eigentlich keine
Rückfragen geben sollte. Sollte es wirklich der Fall ein werde ich diese
auch beantworten. Doch möchte ich ein Antwort zu meiner Frage. Oder es
fragt jemand direkt nach "Was hast Du denn vor?" und nicht
> Bei zwei mal 512 Byte tippe ich auf Auslesen einer Speicherkarte... ;-)
Der Smilie sagt alleine aus, das man nicht ernst genommen wird. Solche
Kommentare sind nicht hilfreich und kann man sich sparen. Und genau
diese Kommentare sind es die diesen Traffic in diesem Forum ausmachen.
Was aber nochviel schlimmer ist, hier werden immer Kopien von
irgenwelchen Source Code oder Schaltungen als Antort gegeben ohne das
überprüftwurde ob das überhaupt richtig ist. Bestes Beispiel befindet
sich hier auf dieser Site:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART#Hardware_Handshake
Nirgends in diesem Artikel wird beschrieben das die Flusskontrolle
selbst zu programmieren ist. Ganz davon abgesehen, das es Schwachsinn
ist, da ein ATMega gar nicht damit umgehen kann wenn man ihn über einen
virtuellen Comport ala USB mit Daten versorgt.
--
Gruß Scotty
Oben schriebst Du:
Scotty schrieb:
> Nur kosten solche Vergleiche wirklich Zeit und die habe ich nicht(Ich> meine jetzt nicht das Programmieren sondern die Laufzeit).
Dann rückst Du endlich mal damit heraus, daß so ein Vergleich nur alle
1ms nötig ist.
Und wenn man Dich darauf hinweist, daß das nur 0,005% CPU-Last mehr
sind, spielst Du die beleidigte Leberwurst.
Die Antworten können immer nur so gut, wie Deine Informationen sein.
Entweder Deine Informationen sind falsch, oder Du optimierst an der
völlig falschen Stelle rum.
Wenn ich was in einem bestehenden Programm optimiere, dann muß das schon
eine CPU-Last deutlich >5% haben
Peter
Scotty schrieb:
> Nirgends in diesem Artikel wird beschrieben das die Flusskontrolle> selbst zu programmieren ist. Ganz davon abgesehen, das es Schwachsinn> ist, da ein ATMega gar nicht damit umgehen kann wenn man ihn über einen> virtuellen Comport ala USB mit Daten versorgt.
Ein ATMega kann mit allem umgehen, was Du programmierst. Und selbst ein
virtueller COM-Port hört auf Handshakesignale. Es kann zwar sein, daß
auf ein gelöschtes CTS hin noch ein paar Bytes aus dem Puffer des
USB-Seriell-ICs purzeln, aber man löscht das CTS ja nicht erst, wenn der
Puffer schon voll ist, sondern bei etwa 80% des maximalen Füllstandes.
So kenne ich das jedenfalls.
Scotty schrieb:
> Hatte ich an dieser Lösung auch schon weil ich auf den Latency-Timer des> USB reingefallen bin.
Aber nur, wenn der PC nach jedem Byte wartet, bis eins zurück kommt.
Auch bei ner echten PC-UART halbiert man dadurch die Datenrate.
Deshalb immer die Daten in Blöcken schicken (z.B. 256Byte).
Das hat allerdings überhaupt absolut garnichts mit dem AVR zu tun, daß
ihm plötzlich nur ein popliger 16Bit Vergleich die Puste ausgehen lassen
soll.
Peter
Scotty schrieb:
> Nur mal eine theoretische Rechnung:> 115.200 Baud 8,N,1> ergibt theoretisch 11.520 Bytes die pro Sekunde übertragen werden> können.
Und praktisch kann man durch geeignete Protokolle durchaus >10kB/s
Nutzdaten drüberbekommen.
> Kaum zu glauben wenn man dann aber feststellt des nur 1000 gesendete und> 1000 empfangene Bytes waren.> Kannst du jeder Zeit prüfen. Schick mal 1000 enzelne Bytes zu Deinem µC,> dieser soll nach jedem Byte ein Byte zurückschicken.
Auf diese Weise bekommst du auch ein Gbit-Ethernet auf einen Durchsatz
im einstelligen Mbit-Bereich gedrückt. Ping-Pong-Spielen bringt nur dann
guten Durchsatz, wenn man ausreichend viele Bälle gleichzeitig in der
Luft hält.
Ergo: nicht nach jedem Byte warten. RS232 kann Full-Duplex, also kann
man das nächste Byte bereits übertragen, während man auf die Antwort
wartet. Ein bisschen Handshake drumherum braucht man dann natürlich
noch, um mit Übertragungsstörungen etc. umzugehen (via Retransmit z.B.),
und dann landet man letztendlich fast zwangsläufig bei paketorientierten
Protokollen. Damit bekommt man die Leitung dann auch (näherungsweise,
und abzüglich Overhead) an den sprichwörtlichen Anschlag.
Andreas
Andreas Ferber schrieb:
> Auf diese Weise bekommst du auch ein Gbit-Ethernet auf einen Durchsatz> im einstelligen Mbit-Bereich gedrückt. Ping-Pong-Spielen bringt nur dann> guten Durchsatz, wenn man ausreichend viele Bälle gleichzeitig in der> Luft hält.
Stichwort zum Googlen noch dazu: Bandwidth-Delay Product
Andreas
Scotty schrieb:
> Kannst du jeder Zeit prüfen. Schick mal 1000 enzelne Bytes zu Deinem µC,> dieser soll nach jedem Byte ein Byte zurückschicken.
Vielleicht prüfst du ja erst einmal selbst, was du da so schreibst?
Da du's offenbar nicht getan hast, habe ich es mal für dich getan.
Man nehme folgendes total simpel geschriebene Progrämmchen:
1
#include<avr/io.h>
2
3
#define BAUD 115200
4
#define F_CPU 7372800
5
#include<util/setbaud.h>
6
7
staticvoid
8
ioinit(void)
9
{
10
UBRR0H=UBRRH_VALUE;
11
UBRR0L=UBRRL_VALUE;
12
UCSR0B=_BV(RXEN0)|_BV(TXEN0);
13
}
14
15
staticuint8_t
16
get_char(void)
17
{
18
while((UCSR0A&_BV(RXC0))==0)
19
/* wait */;
20
returnUDR0;
21
}
22
23
staticvoid
24
put_char(uint8_tc)
25
{
26
while((UCSR0A&_BV(UDRE0))==0)
27
/* wait */;
28
UDR0=c;
29
}
30
31
int
32
main(void)
33
{
34
ioinit();
35
36
for(;;){
37
put_char(get_char());
38
}
39
}
Würde man in der Praxis natürlich nie so machen, sondern eher mit
Interrupts und Ringpuffern arbeiten, aber für die Demonstration sollte
es genug sein.
Compiliert für einen ATmega2560, den ich gerade zur Hand hatte
(steckt in einem STK600). Danach dieser kleine Python-Script
(einfach nur, weil pyserial eine nette, simple Abstraktion der
seriellen Schnittstelle gibt, müsste also auch unter Windows
funktionieren):
print"Sent 10000 chars in %g s, overall bit rate %d bit/s"%\
23
(runtime,int(10*10000.0/runtime))
Ergebnis?
1
% time ./ttyio.py
2
Sent 10000 chars in 0.999604 s, overall bit rate 100039 bit/s
Immerhin bereits 87 % der Bruttodatenrate, keineswegs die von dir
proklamierten 10 % -- und das für eine strohdoofe Variante von
Firmware und einschließlich allen Overheads, den der Python-
Interpreter da noch mit reinbringt.
Sag ich doch keiner von Euch kann anscheinend sich auf das eigentliche
Thema konzentrieren.
Ich schrieb:
"Schick mal 1000 einzelne Bytes zu Deinem µC,
dieser soll nach jedem Byte ein Byte zurückschicken."
Als Antwort kam u.a.
> s = "*" * 100;> for i in range(0, 100):
ser.write(s)
>
Der "rotzt" mit ein Schlag aber 100 Bytes raus. Das war nicht die
Anforderunng.
Weiter
> Aber nur, wenn der PC nach jedem Byte wartet, bis eins zurück kommt.
Da steht es doch, genau das was ich ausgesagt habe.
> Deshalb immer die Daten in Blöcken schicken (z.B. 256Byte).
Genau das versuche ich gerade, nur das die Blöcke bei mir ruhig etwas
größer sein dürfen. Aber danch hatte ich gar nicht gefragt, weil ich das
schon selber rausbekommen.
Weiter
> Ein ATMega kann mit allem umgehen, was Du programmierst.
Gebe ich Dir ohne Einschränkungen Recht.
> Und selbst ein virtueller COM-Port hört auf Handshakesignale.
Ja aber nicht zur µC-Seite sonder nur zum PC(oder sonstigen Master)
> Es kann zwar sein, daß auf ein gelöschtes CTS hin noch ein paar Bytes> aus dem Puffer des USB-Seriell-ICs purzeln, aber man löscht das CTS ja> nicht erst, wenn der Puffer schon voll ist, sondern bei etwa 80% des> maximalen Füllstandes.
Das würde mich echt mal interessieren, wie man so etwas realisiert, ohne
einen Datenverlust!
> So kenne ich das jedenfalls.
Nett das Du das dazu geschrieben hast.
@Peter
> Dann rückst Du endlich mal damit heraus, daß so ein Vergleich nur alle> 1ms nötig ist.
Das habe ich doch niemals geschrieben, woher nimmst Du diese Erkentnis?
Hier steht defintiv was 1 ms benötigen sollte:
"Dieses Verfahren setzt aber vorraus, dass das Füllen im schneller ist
als das Abarbeiten. Beim Abarbeiten werden immer 2 Bytes aus dem
Speicher betrachtet, also 256 Vörgange, So ein Vorgang sollte ca. 1 ms
dauern."
Mit dem Vorgang ist das gemeint was der µC mit seinen 2 Bytes anfangen
soll, die er gerade bearbeitet.
> Und wenn man Dich darauf hinweist, daß das nur 0,005% CPU-Last mehr> sind, spielst Du die beleidigte Leberwurst.
a) brauch ich diesen Hinweis nicht, ich habe nie danach gefragt. Und b)
bin ich nicht beleidigt.
@All
Leute, erst lesen und dann antworten.
Ich habe ein Projekt, welches ich realisieren will. Nur wirklich kurz:
* Eine 6-Achsen CNC-Maschine
* Eine .Net-Framework-Anwendung
* Anwendung liefert die fertigen Daten für die Endstufen und
Leistungsschalter.
* USB-Übertragung
Zum AVR bzw. der Steuerung:
* Diese Schaltung enkoppelt das Timing-Problem einer Windows-Anwendung.
Bevor Ihr jetzt wieder auf die "wildesten Ideen" kommt
* Der Rechner(PC) macht nichts anderes als die Steuerungsdaten für die
Endstufen und Leistungsschalterzu erstellen.
* Es läuft keine andere Software auf diesem Rechner(Multitasking).
* Rechner und Steuerung müssen jeder Zeit de Ausführung unterbrechen
können!(Not-Stop - Not Aus)
So, das sind so ungefähr die Eckdaten. Wie Ihr hoffentlich seht geht es
um ein relativ komplexes Projekt(an dem ich auch nicht erst seit Gestern
dran sitze). Ersichtlich sollte aber sein, welche Aufgabe der µC an
dieser Stelle hat. Er soll das Timing der Maschine steuern, und das so
gut es geht. Hierzu folgendes:
Der PC erstellt die Rohdaten für die Endstufen und Leistungsschalter.
Das sind meißt mehrere 100tausend Byte. Diese werden werden nun immer in
512 Byte großen Stücken an den µC gesendet. Der µC bereitet dann die
Sequenzen für die Endstufen und Leistungschalter auf.
--
Gruß Scotty
Scotty schrieb:
> @All> Leute, erst lesen und dann antworten.
Oder lies Du erstmal, was Du schreibst.
Dein Problem im ersten Thread ist doch, daß Du keine Zeit für einen
Vergleich hast, richtig?
Aber bisher ist weit und breit nichts Zeitkritisches zu sehen.
Deine einzige Angabe (1ms) läßt sogar auf sehr viel Zeit schließen.
Man kann nur dann etwas optimieren, wenn erkennbar ist, was daran nicht
optimal ist.
Peter
@Peter,
> Dein Problem im ersten Thread ist doch, daß Du keine Zeit für einen> Vergleich hast, richtig?
Falsch, schau doch mal was ich geschrieben habe:
"Nein, es sind 512 Takte. Es müssen erst 512 Bytes empfangen werden, bis
die zuverarbeitenden Routine den Buffer "anfassen darf". Es wird immer
zwischen den Buffern "umgeschaltet". Während der eine gefüllt wird, wird
der andere abgearbeitet damit das Ganze "flüssig" wird. Deswegen muss
die zufüllenden Routine immer schneller sein als die abarbeitende. Jeder
Takt der beim befüllen entsteht verringert die Zeit zum Abarbeiten und
Füllen. Deswegen ist jeder Takt zu viel wenn er nicht sein müsste."
ich habe nicht geschrieben, das ich !keine! Zeit habe, es geht hier nur
darumum Reserven zu schaffen(Oh das versteht Er bestimmt auch wieder
falsch).
> Aber bisher ist weit und breit nichts Zeitkritisches zu sehen.> Deine einzige Angabe (1ms) läßt sogar auf sehr viel Zeit schließen.
Verabschiede ich doch mal von dieser Millisekunde, Du weißt doch gar
nicht, wie weit das "aufgebohrt" wird. Vielleicht wird daraus auch mal
250 µs. Es hat Dich nun wirklich nicht zu interessieren.
> Man kann nur dann etwas optimieren, wenn erkennbar ist, was daran nicht> optimal ist.
Genau und dieses Verfahren nennt man "Worst Case" um diesem ohne großen
Aufwand entgegen zu wirken nutzt man sugessive Aproximation. Dieser Weg
ist aber in vielen Fällen falsch. Du kennst vielleich das Beispiel mit
den Autoreifen und der Wand. Oh waren wohl die falschen, nemmen wir bein
nächsten Versuch doch lieber Winterreifen.
Und genau so ist es bei mir auch. Fährt die Maschine nicht in einer
vorgeben Zeit an eine bestimmte Position, erstelle ich nur Schrott.
So für mit wird das langsam aber sicher OT.
Ich habe Frage gestellt und habe die Informationen erhalten die benötigt
habe und dafür Danke.
--
Gruß Scotty
Scotty schrieb:
> Genau und dieses Verfahren nennt man "Worst Case" um diesem ohne großen> Aufwand entgegen zu wirken nutzt man sugessive Aproximation.
Suggestive Approximation? :-)
SCNR...
Wenn du 1000 einzelne Bytes zu deinem Controller schickst und dann
jeweils auf eine Antwort wartest, dann testest du natürlich nicht
die Geschwindigkeit des Controllers, sondern die deines PCs. Dass
normale PC-Betriebssysteme nicht echtzeitfähig sind, sollte man
schon mal irgendwo gehört haben. Wenn du mit USB arbeiten darfst,
bist du natürlich gleich ganz erschlagen, denn dann nützen dir
deine ganzen fiktiven 115200 Bd rein gar nichts, weil deine Antwort
vom Controller erst nach 1 ms wieder zurück kommt. (Ohne USB könnte
es schneller gehen, je nachdem, mit welcher Taktrate dein Betriebs-
system die Task wieder aufweckt, nachdem das gewünschte Zeichen
reingelaufen ist.)
Aber dass man keine request-response-Protokolle baut, wenn man viele
Daten durchsetzen will, dass wussten unsere Vorfahren schon vor über
30 Jahren. Bereits Kermit (und meiner Meinung nach auch X-Modem)
hatten ein "window", eine Anzahl von Paketen, die abgesendet werden
kann, bevor zwingend auf eine Bestätigung gewartet wird.
Ist schon komisch...
Da hat einer ein Problem, dann wird ihm nachgewiesen, daß sein Problem
auf einem Denkfehler beruht, und was macht der Fragesteller?
Er wehrt sich mit Händen und Füßen gegen diese Einsicht.
Wieso stellt er dann überhaupt diese Frage?
War ihm langweilig, oder wollte er einfach nur Aufmerksamkeit
bekommen?
@Jörg,
es ist mir auch bekannt, dass man versuchen sollte größtmöglich
Datenblöcke zu versenden. Bei meinem ersten Versuch wollte ich aber nach
jedem 2 Byte Datenblock eine Antwort. Dass das so nicht realisierbar ist
mir mir schon vor meiner Fragestellung bekannt gewesen, sonst hätte ich
nicht die Frage gestellt wie man besten das SRAM adressiert. Irgendwo
muss ich ja wohl temporär meine Daten lassen. Was den USB betrifft, so
"darf" ich nicht damit arbeiten sondern muss es. Aber es war nicht meine
Frage wie man Daten übermittelt sondern wie man auf den Datenspeicher zu
greift. Diese Antwort habe ich in unterschiedlichen Varianten erhalten.
Ich weiß nicht warum Ihr Euch jetzt daran "aufhängt", wie man eine
Datenübertragung realisiert. Ganz davon abgesehen hätte die Datenquelle
sonst was sein können. Es hätte genauso sein können das der bspw. PC die
Datensenke ist. Es hätte aber auch so sein können das es gar keinen PC
im System hat. Alles wäre möglich gewesen und das unabhängig von meiner
Frage. Hab Ihr durch Eure Spekulationen selbst festgestellt(AD-Wandler,
Speicherkarte).
Zusatzinformationen sind schön, so zum Beispiel die Variante mit dem
Timer die von travelrec vorgeschlagen wurde. Doch ich hasse es wenn man
nur irgendwelche Vermutungen anstellt und diese evtl. mit nicht
hilfreichen oder gar falschen Beiträgen dekoriert.
Jeder hat seine eigene Vorgehensweise. Ich persönlich ziehe es vor
kritischen Stellen im vornherein zu testen. Die Übertagungen und
Verarbeitung der Daten ist eine solche Stelle. Ob ich mit meinem
jetzigen Ansatz glücklich werde weiß ich erst wenn ich es ausgiebig
getestet habe. Nur eines weiß ich auf jeden Fall: Durch das Übertragen
der Daten in Blöcken habe ich ein anderes Problem. Ich darf die
Steuerung nicht einfach unterbrechen nur weil irgend ein Sensor
ausgelöst hat. Eine Funktion der Maschine ist nämlich das Abtasten von
Oberflächen. Hierzu wird der Abtaster solange verfahren bis er auf die
Oberfläche stößt. Wenn ich jetzt aber sage, verfahr mal 256 Schritte
kann es sein, das der Abtaster vielleicht schon nach 30 Schritten die
Oberfläche erreicht hat. Was jetzt aber auf keinen Fall passieren darf
ist dass weitere Schritte erfolgen. Und es muss gewährleisten sein, das
der Master erfährt wann der Abtaster die Oberfläche berührt hat. Für
diesen Problem habe ich schon einen Ansatz, dazu muss ich aber das
Protokoll ändern. All diese Feinheiten führen dazu, dass der µC immer
mehr zu tun bekommt. Nein, ich werde nicht einfach einen schnelleren
Prozessor wählen nur weil ich irgendwo verschwenderisch mit Resourcen
umgegangen bin.
@Hans
> Da hat einer ein Problem, dann wird ihm nachgewiesen, daß sein Problem> auf einem Denkfehler beruht, und was macht der Fragesteller?
Hier ist es schon wieder. Welche Frage habe ich gestellt? Und jetzt
erzähle mir mal wo mein Denkfehler ist und wo es an Einsicht fehlen
sollte.
> Wieso stellt er dann überhaupt diese Frage?
Selbst im Topic steht immer noch um was es geht. Anscheinend hattest Du
Langeweile um Dein Posting zu schreiben.
Das wird mir jetzt langsam aber sicher zu dumm. Ich will nicht über
meine Datenübertragung oder sonst etwas diskutieren. Meine Frage ist
beantwortet und das habe ich bereits mitgeteilt. Damit sollte das Thema
eigentlich erledigt sein. Du hättest Dir also Dein Kommentar sparen
können.
Also nochmals an Spess, Michael, Sebastian und travelrec. Danke für Eure
Antworten.
--
Gruß Scotty
Jetzt muß ich auch nochmal was dazu sagen. Hab zwar nicht so viel Ahnung
aber eine Überlegung ist es denke mal wert. Wenn man jetzt einfach 2µC
nimmt einer empfängt die Daten und schreibt sie in seinen RAM und der
andere Steuert die Maschine. Ist beim Empfänger-µC ein Datenblock voll
setzt er einen Port ist beim Steuerprozessor Zeit zum empangen setzt er
einen Port und der Empfänger-µC sendet. Ich denke man ist dann nicht
Zeitlich an den PC gebunden und die Datenübertragung kann schnell gehen
zwischen den Beiden µC. Der Steuer-µC kann den Datenemfpang jederzeit
abbrechen und es ist mehr Ram im Steuer-µC für andere Sachen Vorhanden.
Scotty schrieb:
> Selbst im Topic steht immer noch um was es geht. Anscheinend hattest Du> Langeweile um Dein Posting zu schreiben.>> Das wird mir jetzt langsam aber sicher zu dumm. Ich will nicht über> meine Datenübertragung oder sonst etwas diskutieren.
Das Topic lautet: SRAM addressieren
Das lernt man prinzipiell in der zweiten Doppelstunde des VHS-Kurses
"Mikrocontroller für Anfänger". Wo ist also die Frage?
Dann folgen im Text drei absatzlang kommentierte Assemblerbefehle,
zusammen mit dem Hinweis auf "Spezialregister". VHS erste Doppelstunde.
Im weiteren folgt dann ziemlich nichtssagendes Geschreibsel über das
System, was du da bastelst. Das einzige, was man daraus entnehmen kann,
ist, das du deine Aufgabe nicht beschreiben kannst, die Randbedingungen
nicht nennen willst oder kannst, die Kommunikation über USB pathologisch
blödsinnig implementiert ist, und du in dem ganzen Durcheinander jetzt
versuchst, irgendwo ein- oder zwei Taktzyklen einzusparen.
Das da der ein- oder andere erste einmal fragt, ob du da an den
richtigen Problemen bastelst, ist irgendwie nachvollziehbar.
>Ich programmiere seit über 25 Jahren und glaube mir, da ist schon>einiges "gegen die Wand gefahren" nur weil man im Vornherein falsch>gerechnet und Randbedingungen ausser Acht gelassen hat.
Ich weiß nicht, was du 25 Jahre programmierst, aber Mikrocontroller
waren es mit Sicherheit nicht. Und die allermeisten Projekte werden
nicht gegen die Wand gefahren, weil man da im Vornherein falsch
gerechnet und Randbedingungen ausser Acht gelassen hat, sondern weil man
im Vornherein gar keine definiert und festgelegt hat. Siehe dein
Beispiel hier.
Oliver
Hallo Mario,
ich glaube nicht das ich 2 Prozessoren brauche, zu mal es sicherlich zu
einem ähnlichen Problem kommen wird. Irgendwie mussen die Daten nämlich
ausgetauscht werden, zumindest in eine Richtung.
Die zweimal 512 Bytes sollten reichen um das Timming Problem in den
Griff zu bekommen.
Aber wie gesagt, es ist nicht das Übertagungsproblem was mirSorgen
macht. Ob ich überhaupt ein Problem bekomme weiß ich nicht. Ich will nur
nicht die Lage kommen, dass ich wirklich ein Problem bekomme nur weil
die Routinen durch unüberlegtes Handeln zu langsam werden. Aber das war
nun wirklich meine Frage.
--
Gruß Scotty
Und wenn man einfach 513 Byte an den µC schickt und hintereinander
abspeichert. Das programm sieht nach ob das 513te gesetz ist und
verwendet den Block setzt vorher das Byte zurück damit die nächsten
Daten im anderen Block gespeichert werden. also nicht ständig Prüfen
wieviel schon ankam sondern einfach vom PC eine Art EndByte setzen und
vom µC rücksetzen
Die andere und weitaus elegantere Art und Weise ist die Verwendung eines
Ringpuffers mit vielleicht 600 Bytes. Ein Schreibzeiger wird hochgezählt
und der Lesezeiger tuckelt bedarfsweise hinterher. Ist der betreffende
Zeiger oben angekommen, wird er zurückgesetzt und wieder hochgezählt.
Wenn die Differenz zwischen Schreib- und Lesezeiger größer 512 ist, wird
das SRAM auf andere Speicher oder Peripherie übertragen und dabei bewegt
sich der Lesezeiger auf den Schreibzeiger zu. Ist die Differenz zwischen
Lese- und Schreibzeiger =0, dann wurde alles weggespeichert. Vorteil:
Lesen und Schreiben kann beinahe zeitgleich stattfinden und man braucht
nur etwas mehr Speicher, als Nutzdaten zu erwarten sind, um eine Reserve
zu haben.
@Travel Rec.
So wuerde ich das zwar auch machen, aber wenn der TO sich schon ueber
einen Compare Befehl aufregt das der das ganze Projekt zum scheitern
verurteilt ...
Vielleicht sollte er doch mal darueber nachdenken einen etwas
schnelleren Prozessor zu verwenden. Bei mir ist wegen einem Befehl mehr
noch nie ein Projekt gescheitert.
Gruss Helmi
Travel Rec. schrieb:
> Ein Schreibzeiger wird hochgezählt> und der Lesezeiger tuckelt bedarfsweise hinterher.
Ich dachte die Frage war: Wie kann man Die Daten Speichern ohne ständig
zu Prüfen oder mit zu zählen?
Ok, letzter Vesuch.
Die Idee mit dem Ringspeicher ist eine schöne Sache, nur kennt der
Master in diesem Fall keine Grenzen. Diese bedeuten er würde auch die
komplette Sequenz "rausrotzen". So etwas können aber mehrere 100.000
Byte sein sein, je nach dem wie komplex die Bearbeitung des Werkstücks.
Nur ein nur kurze Aufgabe dauert vielleicht 5 Minuten, das entspricht 5
60 1000 = 300.000 ms Für jede Millisekunde werden 2 Bytes benötigt.
Es müssen also 600.000 Bytes in den Controller gelangen und dabei darf
es keine Verluste oder Verzögerungen geben. die Maschine muss immer so
viel Daten zur Verfügung haben, das sie reibungslos arbeiten kann. Vom
PC ist das kein Problem, alle benötigten Daten werden vorher berechnet.
Im obigen Fall hätte er 600.000 Byte großes Byte-Array. Ich brauche nur
eine eine Anweisung in der Anwendung und er würde diese 600.000 Byte an
die USB-Schnittstelle senden. Nur fängt der Controller dann an "zu
kotzen" weil gar nicht weiss, wohin damit. Timeouts sind dann regelrecht
vorprogrammiert.
Zurück zum Ringspeicher: So etwas ähnliches realisiere ich ja in dem ich
2 Bänke benutze. Also
PC sendet 512 Byte
µC quitiert den Empfang und beginnt dieses Bank abzuarbeiten
PC senden darauf die nächsten 512 Byte
Jetzt muss der µC neben der Abarbeitung der aktuellen Bank die Daten
empfangen und die andere Bank speichern.
Erst wenn die aktuelle Bank abgearbeitet ist gibt der µC das Kommando,
Ok jetzt die nächsten 512 Byte.
So läuft das immer im Wechsel, eine Bank wird befüllt und die Andere
zeitgleich abgearbeitet.
Das Befüllen darf nur nich längert dauern als das Abarbeiten.
Sollte der µC etwas feststellen, bspw. ein Sensor hat ausgelöst sendet
er unmittelbar an eine Information an den PC, so das dieser darauf
reagieren kann und die Daten ändert. Der µC übermittelt dem PC nur noch
an welcher Position im Speicher und in welcher Bank er sich befand, dann
setzt er seine Adress- und Bankzähler auf Null. Der PC kann anhand der
Werte des Adress- und Bankzähler geanau feststellen wo sich die
Steuerung gerade befand. Nun kann der PC den Controller wieder anweisen
irgend etwas zu tun, in dem er wieder 512 Bytes an den Controller
sendet. Das ganze SPiel endet dann damit bis der PC keine Daten mehr
sendet.
Dieses Prinzip sollte funktionieren.
@Peter
Warum hängst Du Dich an diesem einem Takt auf? Vielleicht ist ist später
genau der der eine Störung hervorruft. Und nein, es kommt kein
schnellerProzessor zum Einsatz, so etwas kostet Geld. Ich höre es schon,
"Diese 50 Cent", es sind halt nicht nur 50 Cent. Ändert sich das
Pinlayout nur eines Bausteines und gerade bei solchen Tausendfüßlern ist
das ganze PCB-Layout "vorn Arsch"(Entschuldige die Ausdrucksweise, aber
so ist es nun mal). Neu routen kostet Zeit(Hierzu sei angemerkt, ich
erstelle mein PCBs nicht durch einen Autorouter, nicht weil ich es nicht
könnte). Neben bei darfst Du eine neue Platine erstellen(oder erstellen
lassen). Im ungünstigsten Fall reich vielleicht noch nicht mal das
Gehäuse aus, weil die Platine zu groß geworden ist. Und schnell werden
aus 50 Cent eben mal 50 Euro. Glaube mir, alles schon da gewesen. Da
wurden ganze Schaltschränke ausgetauscht nur weil sie voll mit 19
Zoll-Einschubgehäusen waren. Dann wurde ein Netzteil geändert und passt
nicht mehr in den angedachten Einschub. Ergo musste ein weiterer
Einschub her. Schade, in den Schaltschränken war aber kein Platz mehr.
Kurz um gut,diese Maßnahme hat vielen Leute graue Haare beschert und die
Aktion hat 2 Wochen gedauert und ca. 8 1/2 Tausend Euro gekostet.
Schizophrenie an der ganzen Sache das neue Netzteil kostet weniger als
das Ursprüngliche.
Der Fehler war aber offensichtlich. Man sagte "Ok Dauerlast liegt bei X
also noch mal 20% drauf und das passt schon". Schade nur das einige
Hersteller der eingebaute Prozessormodule dabei gegangen waren und haben
ihre Prozessoren ubertaktet um die Anforderungen zu erfüllen. Nun was
passiert wenn man einen Prozzesor übertaktet wissen wohl eher die
wenigsten. MIt steigender Frequenz sinkt der Innenwiderstand, dies führt
zu einer höheren Stromaufnahme und damit zu erhöhter Leistungsaufnahme.
Nur ist die Leistung nicht nur Rechnenleistung sondern auch
Arbeitsleistung. So ein Prozessor setzt dann diese Arbeitsleistung in
Wärme um. Wird diese Wärme nicht schnel lgenug abführt verhält sich das
Ding wie eine Schmelzsicherung und geht in "die ewigen Jagdgründe der
Elektronik ein"
@Mario
Ich sag doch, wer lesen kann ist klar im Vorteil. Fange doch mal
Urspungsposting in diesem Thread an.
--
Gruß Scotty
So viel Quatsch auf einmal lesen zu müssen, tut schon weh.
Ich kann nur hoffen, daß kein vernünftiger Programmierer sich mit diesem
Unsinn weiter beschäftigt.
Scotty schrieb:
> Nur kosten solche Vergleiche wirklich Zeit und die habe ich nicht(Ich> meine jetzt nicht das Programmieren sondern die Laufzeit).
Scotty schrieb:
> @Mario> Ich sag doch, wer lesen kann ist klar im Vorteil. Fange doch mal> Urspungsposting in diesem Thread an.
Was Du geschrieben hast, oder zwischen den Zeilen gedacht?
@Hans
> So viel Quatsch auf einmal lesen zu müssen, tut schon weh.
genau so wie dieses hier?
> Und wenn man Dich darauf hinweist, daß das nur 0,005% CPU-Last mehr> sind...
Woher wird diese Erkenntnis genommen?
> Wenn ich was in einem bestehenden Programm optimiere, dann muß das schon> eine CPU-Last deutlich >5% haben
Auch ein Aussage, jedoch sehr wenig aussagend.
Zu mal man ja weiß was er tun würde, Prozessor austauschen.
@Hannnes
Auch diesen Kommentar, wie denn mit dem Smilie hättest Du Dir sparen
können.
--
Gruß Scotty
Scotty schrieb:
> @Hans>>> So viel Quatsch auf einmal lesen zu müssen, tut schon weh.>> genau so wie dieses hier?>> Und wenn man Dich darauf hinweist, daß das nur 0,005% CPU-Last mehr>> sind...>> Woher wird diese Erkenntnis genommen?
Aus jahrelanger Praxis in Hardware- und Software-Entwicklung. Peter ist
nämlich einer von denen, die wirklich Ahnung haben, und das nicht nur
betreffs AVRs.
>>> Wenn ich was in einem bestehenden Programm optimiere, dann muß das schon>> eine CPU-Last deutlich >5% haben>> Auch ein Aussage, jedoch sehr wenig aussagend.
Ist mit Sicherheit mehrfach belegt, würdest Du auch sicher finden, wenn
Du Dich mal ohne Scheuklappen etwas in diesem Forum umsiehst.
>> Zu mal man ja weiß was er tun würde, Prozessor austauschen.
Nöö, er würde vermutlich die Aufgaben so (zwischen PC und AVR)
aufteilen, dass der Flaschenhals der USB-Zeitscheibe nicht mehr stört.
> @Hannnes> Auch diesen Kommentar, wie denn mit dem Smilie hättest Du Dir sparen> können.
Seit wann bestimmst Du hier die Spielregeln??? Außerdem ist das meine
Sache, ob ich mich über diesen Thread (und Dein Verhalten) amüsiere und
ggf Beifall spende. Du schwingst doch auch die Keule und drischt auf
Jeden ein, dessen Antwort Dir nicht hundertprozentig passt. Du musst
Dich also nicht wundern.
> --> Gruß Scotty
...