Es ist bei 200kHz Signalfrequenz und damit wohl vorzugsweise 2MHz Samplerate zumindest keine Freude. Man würde es wohl nicht mit Controller machen. Sondern entweder FPGA das genügend RAM an Board hat oder TTL-Grab.
Wenn man sich auf 8 Bit Dynamik beschränkt:
8 Bit A/D-Wandler mit Latch
8 Bit D/A-Wandler mit Latch
8kx8 SRAM 70nsec davon aber nur 256 Byte benutzen
8 Bit Zähler 74HC40xx als Adreßgenerator fürs RAM
Steuerlogik 74HCxx
( eventuell per Poti einstellbarer RC-)Taktgenerator für die Steuerlogik, muß mit 8MHz klappern. Die Steuerlogik macht in ihren 4 Schritten:
Lesezyklus RAM auf Latch des D/A.
Schreibzyklus A/D auf RAM. Starten der nächsten A/D-Wandlung
inkrementieren des Adereßzählers.
no Operation
Knackpunkt ist der Flash-A/D-Wandler sowie D/A-Wandler die man eventuell nicht bei Reichelt/Conrad findet. Sonst ist es aber simple Technik nur eben mit Nachteil viel Fädeldraht.
Ein ganz anderer Ansatz. Mit einem Funktionsgenerator (z.B. HP33120A, geht aber sicher auch mit anderen) kann man einen einmaligen Burst durch ein externes Signal triggern. Dann reduziert sich der Aufwand auf einen Komparator und Verzögerung für den Triggerimpuls. Ich kenne mich da nicht aus, aber das könnte mit einem Timer 555 funktionieren. Aber da gibt es ja jede Menge Spezialisten für diesen Baustein. Ich würde es mit einem MSP430F2101 für ~1EUR realisieren. Der hat einen Komparator und 1% Taktgenerator on Board.
Bin weiterhin der Meinung daß wegen der hier hohen Geschwindigkeitsanforderungen ein beliebiger 8 Bit Controller mühsam ist. Eine lineare Codesequenz für 256 Byte auf 68HC08
Für PIC sieht das folgendermaßen aus: (jeder Befehl 200ns bei 20 MHz Takt, für das goto 2x200ns)
start:
MOVFW INDF ;Lade Bit aus Tabelle, hier komplettes Byte, weil ;schneller, INDF ist für indirekte Addressierung das ;Register mit der Adresse 0, Addressierung über FSR MOVWF PORTA ;Das was vorher nach w geladen wurde auf einen Port ;ausgeben MOVFW PORTB ;Lese PORTB ins Work-Register (Akkumulator) MOVWF INDF ;Schreibe PORTB Zustand in das durch FSR adressierte ;Register INCF FSR ;Incrementiere den Zeiger auf die Tabelle MOVLW 0x20 ;Anfangsadresse der Tabelle laden BTFSC FSR.7 ;Wenn Überlauf bei 8F MOVWF FSR ; dann FSR auf den Wert 0x20 setzen, Tabellenanfang goto start ; Schleife beenden
Wenn noch ein Enable/Strobe für den AD und den DA ausgegeben werden muss, wirds natürlich etwas länger.
AVR müsste auch gehen: Bei 20MHz Takt ein Maschinenzyklus 50ns
Ist aber insgesammt knapp, da hast du schon recht. Nur die Schaltung wird damit extrem simpel.
---------------------------------------------------------------------- ;Registerbelegung ;Z ist immer R31:R30 .def W = R16 ;Universalregister (Ich nenne es mal auch W) .def LIML = R17 ;Adresslimit (Ende der Tabelle) .def LIMH = R18
;Konstanten .equ BASEL = 0x60 ;Basisadresse der Tabelle (0x0060) .equ BASEH = 0x00 ;(0x0100 fuer AVRs mit extended I/O) ;Anzahl der Werte in der Tabelle .equ SIZEL = 0xA7 ;167 Werte (Delay: 167 * 600ns = 100.2us) .equ SIZEH = 0x00 ;Darf auch 16Bit haben
;Initialisierung (Geht auch schneller, aber ist ja egal) INIT: LDI LIML, BASEL ;Lade 16Bit Basisadresse in LIM LDI LIMH, BASEH LDI W, SIZEL ;Addiere 16Bit Tabellengroesse ADD LIML, W LDI W, SIZEH ADC LIMH, W
;Schleife laeuft 600ns START: LDI ZL, BASEL ;Lade Basisadresse der Tabelle in Pointer Z LDI ZH, BASEH LOOP: LD W, Z ;Wert an Adresse Z aus Tabelle in W laden OUT PORTB, W ;W in Latch von Port B schreiben IN W, PINA ;Pinstatus von Port A in W laden ST Z+, W ;W an Adresse Z schreiben und Pointer erhoehen CP ZL, LIML ;16Bit Vergleich von Pointer Z mit LIM CPC ZH, LIMH BRSH START ;Am Ende => Beginne wieder am Anfang der Tabelle NOP ;Kompensiert das Laden der Basisadresse RJMP LOOP ;Schleife beenden
Die indirekten Speicherzugriffe und die Spruenge brauchen 2 Takte, sonst alles 1 Takt zu 50ns bei 20MHz. Die Schleife braucht 12 Takte bzw. 600ns (=> Sampling erfolgt mit ca. 1.7MHz). 100us Verzoegerung waeren 2000 Takte, mit 167 Werten erreicht man 100.2us Verzoegerung.
Begrenzt man die Tabellengroesse auf 8Bit bzw. 256 Werte, dann spart das
2 Takte in der Schleife. Die Schleife braucht dann nur 10 Takte und man kommt auf 2MHz Samplingrate. Wuerde fuer 100us noch reichen (Tabelle haette dann 200 Werte und man wuerde die 100us sogar genau treffen).
Als CPU kaeme z.B. ein ATtiny44 in Frage, der hat 256 Byte RAM und darf mit 20MHz laufen.
Das war die digitale Variante, offenbar war aber 8Bit analog gewuenscht. Da muesste man einen AVR mit 3 I/O-Ports nehmen (z.B. ATmega8) und noch ADC (z.B. AD7822 im "Stand alone mode") und DAC (z.B. DAC0830 im "Flow-Through mode") dranhaengen. Koennte etwa so aussehen:
---------------------------------------------------------------------- ;Registerbelegung ;Z ist immer R31:R30 .def W = R16 ;Universalregister (Ich nenne es mal auch W) .def LIML = R17 ;Adresslimit (Ende der Tabelle)
;Pins .equ ADC = PC0 ;ADC pin /CONVST sei an PC0 angeschlossen
;Konstanten .equ BASEL = 0x00 ;Basisadresse der Tabelle (0x0100) .equ BASEH = 0x01 ;Anzahl der Werte in der Tabelle (max. 255) .equ SIZEL = 0x8F ;143 Werte (Delay: 143 * 700ns = 100.1us)
;Initialisierung (Geht auch schneller, aber ist ja egal) INIT: LDI LIML, BASEL ;Lade 16Bit Basisadresse in LIM LDI W, SIZEL ;Addiere 8Bit Tabellengroesse ADD LIML, W
;Schleife laeuft 700ns START: LDI ZL, BASEL ;Lade Basisadresse der Tabelle in Pointer Z LOOP: LD W, Z ;Wert an Adresse Z aus Tabelle in W laden OUT PORTB, W ;W in DAC an Port B schreiben IN W, PIND ;ADC Daten von Port D in W laden (nach 500ns) ST Z+, W ;W an Adresse Z schreiben und Pointer erhoehen CBI PORTC, ADC ;A/D-Wandlung starten CP ZL, LIML ;8Bit Vergleich von Pointer Z mit LIM SBI PORTC, ADC ;Pulsbreite 150ns BRSH START ;Am Ende => Beginne wieder am Anfang der Tabelle RJMP LOOP ;Schleife beenden
So koennte man prinzipiell mit 8Bit Aufloesung immer noch auf eine Samplingrate von ca. 1.4MHz kommen. Will man explizit in den DAC-Latch schreiben, dann gehen nochmal 4 Takte drauf und man landet bei ca.
AVR ist auch etwas billiger als PIC. Ich habe AVR bisher aber nur mit WINAVR programmiert, deshalb ist mir bei Assembler der PIC etwas geläuufiger. Aber das ist ein gutes Beispiel, an dem man sehen kann, dass die ATmegas den PICs deutlich überlegen sind.
Den ATmega8 gibts im DIP-Gehaeuse bei Reichelt schon ab einem Stueck fuer 1.25 EUR. Bei der Analogloesung werden aber wohl ADC und DAC den Gesamtpreis dominieren.
... und dass man nicht pauschal alles in C programmieren sollte. Gerade AVRs lassen sich wirklich schoen in Assembler programmieren - besonders bei 16Bit und 32Bit Operationen im Vergleich zu PIC16.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.