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?
> Wo kommen die Daten überhaupt her?
Bei zwei mal 512 Byte tippe ich auf Auslesen einer Speicherkarte... ;-)
...
@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"
Läubi .. schrieb:
> Falscher Ansatz!
Yep. Never start optimizing before you have profiled it.
@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 | static void |
8 | ioinit(void) |
9 | {
|
10 | UBRR0H = UBRRH_VALUE; |
11 | UBRR0L = UBRRL_VALUE; |
12 | UCSR0B = _BV(RXEN0) | _BV(TXEN0); |
13 | }
|
14 | |
15 | static uint8_t |
16 | get_char(void) |
17 | {
|
18 | while ((UCSR0A & _BV(RXC0)) == 0) |
19 | /* wait */; |
20 | return UDR0; |
21 | }
|
22 | |
23 | static void |
24 | put_char(uint8_t c) |
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):
1 | #! /usr/bin/env python
|
2 | |
3 | import serial |
4 | import time |
5 | |
6 | ser = serial.Serial('/dev/ttyS1', 115200, timeout=1, rtscts=0) |
7 | |
8 | s = "*" * 100; |
9 | |
10 | start = time.time() |
11 | amnt = 0 |
12 | for i in range(0, 100): |
13 | ser.write(s) |
14 | rv = ser.read(100) |
15 | amnt += len(rv) |
16 | stop = time.time() |
17 | |
18 | if amnt != 10000: |
19 | print "character loss!, read only %d chars" % amnt |
20 | |
21 | runtime = stop - start |
22 | 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 ...
Travel Rec. schrieb:
> Ich klink´ mich hier aus.
Jetzt, wo's gemütlich wird? ;-)
Aber der Popcorn-Stand hat schon zu.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.