Forum: Mikrocontroller und Digitale Elektronik Heavy-Metal-Maschine von Elektor


von hermy (Gast)


Lesenswert?

Hallo,

hat hier mal jemand die Heavy-Metal-Maschine von Elektor gebaut?

Wenn ja, welche Klangerfahrungen konnte er sammeln?

Ich überlege derzeit, mir auch so ein Teil zu bauen (allerdings 
eventuell statt mit vier mit acht Oszis und einem AVR als 
Hüllkurvengenerator).

: Verschoben durch User
von hermy (Gast)


Lesenswert?

Hat hier etwa noch keiner die weltberümte Heavy-Metal-Maschine von 
Elektor gebaut?
Dabei hat Elektor das Projekt doch in mindestens drei Büchern 
veröffentlicht (mindestens!)
;)

von der Gast (Gast)


Lesenswert?

Hallo hermy,

am Besten fragst du in ca. 3,5h noch einmal nach, vielleicht meldet hat 
dann einer der vielen Nachbauer ein Einsehen und meldet sich. Vielleicht 
hat er deinen Beitrag nur übersehen, obwohl er nur darauf gewartet hat, 
dass er eine Anfrage brantworten darf.

der Gast

von Ingolf O. (headshotzombie)


Lesenswert?

Nichtmal die Elektor-Suche findet was bei Eingabe von "heavy metal 
machine" bzw. nur von "heavy metal"...

von hermy (Gast)


Lesenswert?

Ingolf O. schrieb:
> Nichtmal die Elektor-Suche findet was bei Eingabe von "heavy metal
> machine" bzw. nur von "heavy metal"...

tatsächlich nicht???

Also das Teil funktioniert folgendermaßen:

Man hat vier Rechteckgeneratoren, deren Frequenzen mit Potis in weiten 
Bereichen geregelt werden können.

Jeweils zwei Rechteckgeneratoren werden über ein EXOR-Gatter 
zusammengemischt.

Die beiden erhaltenen Signale werden wieder über ein EXOR-Gatter 
zusammengemischt.

Das so entstandene Signal durchläuft einen Hüllkurvengenerator mit einem 
OpAmp 3080, bei dem die Anstiegszeit und die Abschwellzeit geregelt 
werden kann.

Das Ergebnis soll eine Fülle unbeschreiblicher, metallähnlicher 
Geräusche sein, die man damit erzeugen kann.
Vom Hammerschlag auf einen Ambos bis zum chinesischen Supergong oder dem 
Lärm einer Maschinenhalle...

von Ingolf O. (headshotzombie)


Lesenswert?

Hast Du nicht die konkrete Elektor-Heftnummer und den Jahrgang dazu zur 
Hand?

von hermy (Gast)


Lesenswert?

Ingolf O. schrieb:
> Hast Du nicht die konkrete Elektor-Heftnummer und den Jahrgang dazu zur
> Hand?
wahrscheinlich irgendwann 1989

hier der schaltplan:
http://www.drummachines.de/beatboxer/beatboxer/elekhevy.htm

von hermy (Gast)


Lesenswert?

PS:
man beachte den text unter dem schaltplan, bes. den letzten satz...

"Klassische Multioszillatorenschaltung mit OTA VCA. Die Hüllkurve wird 
durch Kondensatorladung und -entladung erzeugt. Der Decay Bereich lässt 
sich mittels 4fach Schalter umschalten und mit einem Potentiometer 
einstellen. Als Trigger dient ein normaler Taster. Eher ein 
Lötübungsstück als ein Drum Synth."

von Ingolf O. (headshotzombie)


Lesenswert?

Elektor 7/86 S.54

von Oktoberfestbesucher (Gast)


Lesenswert?

Diese Schaltung war mir bislang unbekannt.
Aber ich habe irgendwann in den 80'er Jahren des letzten Jahrhunderts 
eine ähnliche Schaltung aus der ELRAD aufgebaut.
Aus meiner Erinnerung heraus, ist ja ca. 25 Jahre her kann ich nur sagen 
Sehr empfehlenswert
Soweit ich mich erinnere, waren es dort 5 oder 6 Rechteckoszillatoren 
die mit XOR-Gattern verknüpft wurden.

>Ich überlege derzeit, mir auch so ein Teil zu bauen (allerdings
>eventuell statt mit vier mit acht Oszis und einem AVR als
>Hüllkurvengenerator).

Die Rechteckfrequenzen kannst du auch mit dem AVR machen, falls du 
lieber programmieren statt löten willst:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
unsigned short int Phasen_acc1 = 0;
5
unsigned short int Phasen_acc2 = 0;
6
unsigned short int Phasen_acc3 = 0;
7
unsigned short int Phasen_acc4 = 0;
8
unsigned short int Phasen_acc5 = 0;
9
unsigned short int Frequenz1 = 262 * 65536 / 31250; // C
10
unsigned short int Frequenz2 = 294 * 65536 / 31250; // D
11
unsigned short int Frequenz3 = 330 * 65536 / 31250; // E
12
unsigned short int Frequenz4 = 349 * 65536 / 31250; // F
13
unsigned short int Frequenz5 = 392 * 65536 / 31250; // G
14
unsigned char PORTB_mirror = 0;
15
16
int main(void)
17
{
18
  DDRB = 0x1F;      // PB0 bis PB4 sind Output
19
  TCCR1 = 0b00000001;    // Prescaler = CK 
20
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable
21
  sei();          // Enable Interrrupt
22
  while(1){}        // Endlosschleife
23
}
24
//**************************************************************
25
ISR(TIMER1_OVF_vect)
26
{
27
  Phasen_acc1 += Frequenz1;
28
  Phasen_acc2 += Frequenz2;
29
  Phasen_acc3 += Frequenz3;
30
  Phasen_acc4 += Frequenz4;
31
  Phasen_acc5 += Frequenz5;
32
33
PORTB_mirror  = (Phasen_acc1 & 0x8000)>>15 
34
               |(Phasen_acc2 & 0x8000)>>14
35
               |(Phasen_acc3 & 0x8000)>>13
36
               |(Phasen_acc4 & 0x8000)>>12      
37
               |(Phasen_acc5 & 0x8000)>>11;
38
39
  PORTB = PORTB_mirror;
40
41
}
42
//**************************************************************
Halt uns mal über deine Fortschritte auf dem laufenden.

von hermy (Gast)


Lesenswert?

Hey, Danke für das Programm!

>Die Rechteckfrequenzen kannst du auch mit dem AVR machen, falls du
>lieber programmieren statt löten willst:

Das will ich tatsächlich lieber! Aber so ganz ist mir nicht klar, wie 
ein AVR vier bis sechs in der Frequenz stufenlos regelbare 
Rechteckoszillatoren simulieren kann. So ein µC kann doch nur 
ganzzahlige Teiler seiner Taktfrequenz als Rechteckschwingungen 
ausgeben...

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> So ein µC kann doch nur
> ganzzahlige Teiler seiner Taktfrequenz als Rechteckschwingungen
> ausgeben...

Das stimmt im Prinzip auch, der µC muss also *ein kleines bischen 
schummeln*
Dazu ist der eine Rechteck mal etwas länger oder kürzer als der andere.
Auf einem Oszilloskop ist das als gewisse Unschärfe der Rechteckflanken 
durchaus zu sehen.
Im Frequenzspektrum ist dieses als eine Art Grundrauschen zu sehen, die 
unendlichen Oberwellen der Rechteckschwingung werden unendlich an 
F_abtast_halbe gespiegelt.
1
  Phasen_acc1 += Frequenz1;
Dies ist eine Software DDS (Digitale Direkt Synthese)
1
(Phasen_acc1 & 0x8000)
dient nur dazu das most significant Bit herauszuschneiden.

von hermy (Gast)


Lesenswert?

aha, interessant... ich bin alles andere als ein C-profi, nehme meistens 
lieber bascom, weil für simple sachen für mich einfacher.

wie verstellt man bei dem angegebenen programm denn die frequenzen von 
außen?

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> wie verstellt man bei dem angegebenen programm denn die frequenzen von
> außen?

Frequenz1 bis Frequenz5 sind globale Variablen.
Du könntest z.B. an die Analog-eingänge des µC Potis anlöten und die 
Spannungen im Hauptprogtramm mit dem ADC-Wandler messen.

von hermy (Gast)


Lesenswert?

Oktoberfestbesucher schrieb:
> Du könntest z.B. an die Analog-eingänge des µC Potis anlöten und die
> Spannungen im Hauptprogtramm mit dem ADC-Wandler messen.

stört das nicht die rechteck-frequenzen, wenn plötzlich zwischendrin 
werte über den ADC eingelesen werden?

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Ich glaube, der Prozessor wird sich dabei immer noch langweilen. Denn 
die Frequenzen sollen ja im NF-Bereich (maximal 20 Kiloherz) liegen. Der 
Prozessor kann aber Megaherz.

von hermy (Gast)


Lesenswert?

Christian H. schrieb:
> Ich glaube, der Prozessor wird sich dabei immer noch langweilen. Denn
> die Frequenzen sollen ja im NF-Bereich (maximal 20 Kiloherz) liegen. Der
> Prozessor kann aber Megaherz.
glaube, so bis 50khz sollten pro oszi minimal möglich sein, weil es ja 
um die mischprodukte (interferenzen) geht, denn es können auch längst 
nicht mehr hörbare frequenzen mischprodukte im nf-bereich erzeugen.

bei 100khz läge die periodendauer immerhin schon bei 10ns

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

falsch, 10µs ;)
Schafft der µC locker.

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> stört das nicht die rechteck-frequenzen, wenn plötzlich zwischendrin
> werte über den ADC eingelesen werden?

Die Frequenzen werden im Timerinterrupt erzeugt.
Einlesen der ADC-Werte im Hauptprogramm.
Also kein Problem.

von hermy (Gast)


Lesenswert?

stimmt, 10µs, war wohl doch schon ein bisschen spät gestern ;)
ok, dann gehts ja...

wie erzeugt man denn die Frequenzen im Timerinterrupt?
Schätze mal, Timerinterrupt bedeutet, dass irgendein register 
runtergezählt wird und immer bei einem bestimmten wert irgendwas macht, 
z.b. port von hi auf lo stellen (oder umhgekehrt) zur 
rechteckerzeugung...!?!?!

von T. C. (tripplex)


Lesenswert?

Timerinterrupt sagt nur das in einer bestimmten Zeit dieser
Teil des Programmes periodisch angesprungen wird.
Ob du dann einen PortPin setzt oder etwas anderes tust ist dir 
überlassen.
Aber du hast Recht mit dem was du gesagt hast :)

von hermy (Gast)


Lesenswert?

Pascal L. schrieb:
> Timerinterrupt sagt nur das in einer bestimmten Zeit dieser
> Teil des Programmes periodisch angesprungen wird.

kann man pro timer auch mehrere solcher interrupts vorsehen?

im moment ist mir nicht ganz klar, wie man mit einem einzigen 
timerinterrupt vier oder mehr rechteckgeneratoren simulieren will, die 
von der frequenz her unabhängig voneinander jeder für sich individuell 
eingestellt werden können...

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> im moment ist mir nicht ganz klar, wie man mit einem einzigen
> timerinterrupt vier oder mehr rechteckgeneratoren simulieren will, die
> von der frequenz her unabhängig voneinander jeder für sich individuell
> eingestellt werden können...

Ich habe am 19.04.2010 um 16:48 Uhr hier einen Quellcode gepostet.

Du brauchst ihn nur compilieren (AVR Studio 4 und Winavr) und mit einem 
Programmiergerät (Ponyprog) in einen ATtiny25 brennen.
An den Portleitungen PB0 bis PB4 hast du dann die Frequenzen
262Hz, 294Hz, 330Hz, 349Hz und 392Hz.
Dies entspricht den Tönen C, D, E, F und G.

Benutze dies als Ausgangsbasis und versuche zu verstehen was dort 
passiert.

von hermy (Gast)


Lesenswert?

Oktoberfestbesucher schrieb:
> Ich habe am 19.04.2010 um 16:48 Uhr hier einen Quellcode gepostet.
>
> Du brauchst ihn nur compilieren (AVR Studio 4 und Winavr) und mit einem
> Programmiergerät (Ponyprog) in einen ATtiny25 brennen.
> An den Portleitungen PB0 bis PB4 hast du dann die Frequenzen
> 262Hz, 294Hz, 330Hz, 349Hz und 392Hz.
> Dies entspricht den Tönen C, D, E, F und G.
>
> Benutze dies als Ausgangsbasis und versuche zu verstehen was dort
> passiert.

hallo o-festbesucher,

bin z.zt. dabei, das AVR studio 4 einzurichten. braucht man das winAVR 
zum C-programmieren (habe auf dieser seite unter "AVR" (oben links unter 
"home") bei den programmen nichts weiter mit der bezeichnung gefunden)?

leider habe ich nur Mega8-Controller und größer vorrätig.

das brennen könnte man wohl auch mit bascom erledigen, denke ich (ist 
nämlich schon auf dem rechner)

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> braucht man das winAVR
> zum C-programmieren

Ja, musst du runterladen und installieren.
Ist der Compiler.
Wenn du dann bei AVR Studio 4 ein neues Projekt aufmachst, hast du die 
Wahl zwischen Atmel AVR Assembler und GCC.
GCC = Gnu C Compiler.

>leider habe ich nur Mega8-Controller und größer vorrätig.

in dem C-Rogramm sind die folgenden 2 Zeilen:
speziell auf den ATtiny25 zugeschnitten, damit wird der Timer und der 
Interrupt configuriert. Musst du umschreiben oder ATtiny25 kaufen.
1
  TCCR1 = 0b00000001;    // Prescaler = CK 
2
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable

>das brennen könnte man wohl auch mit bascom erledigen, denke ich (ist
>nämlich schon auf dem rechner)

wenn du da ein Programmiertool hast mit dem du eine *.hex Datei in einen 
µC programmieren kannst, sollte das OK sein.

Wenn du dich mit BASCOM auskennst, kannst du dir mal
Beitrag "BASCOM Programm nach C übersetzen"
anschauen...

von hermy (Gast)


Lesenswert?

Hallo,

bin im Moment noch mit einem anderen Projekt beschäftigt.

Habe mir aber mal ein paar weitere Gedanken zur HMM gemacht.

5 Oszis sind natürlich super, weil man so alle 4 EXOR-Gatter im 4070 zum 
Einsatz bringen kann.

Prima wäre natürlich, wenn man auf Knopfdruck die genauen Frequenzen der 
5 Oszis anzeigen könnte, dann hätte man die Möglichkeit, Klänge zu 
reproduzieren.

Habe hier ein Bord mit M32 und Vier-Zeilen-LCD, das bietet sich gradezu 
an.

Stellt sich noch die Frage, wie die Frequenzen verstellt werden.
Man braucht ja im Grunde 10 Leitungen dafür, wenn man mit Drucktastern 
arbeitet, also pro Oszi 1x "f erhöhen" und 1x "f erniedrigen".

So viel erst mal, danke für den Link zum Bascom-in-C-Übersetzen

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> 5 Oszis sind natürlich super, weil man so alle 4 EXOR-Gatter im 4070 zum
> Einsatz bringen kann.

Es geht noch toller:
Die EXOR-Gatter kann man auch in Software machen:
1
PORTB         = ((Phasen_acc1 >> 8)
2
                ^(Phasen_acc2 >> 8)
3
                ^(Phasen_acc3 >> 8)
4
                ^(Phasen_acc4 >> 8)
5
                ^(Phasen_acc5 >> 8)) >> 7

>Man braucht ja im Grunde 10 Leitungen dafür, wenn man mit Drucktastern
>arbeitet, also pro Oszi 1x "f erhöhen" und 1x "f erniedrigen".

Oder mit 5 Poti's an den ADC-Eingängen

von hermy (Gast)


Lesenswert?

Oktoberfestbesucher schrieb:
> Es geht noch toller:
> Die EXOR-Gatter kann man auch in Software machen

Das wäre natürlich die Non-Plus-Ultra-Lösung!!!!!!!!

Potis sind für die Anwendung natürlich wesentlich komfortabler als 
Druckschalter.

Aber schafft der AVR denn auch alles gleichzeitig, fünf unabhängige 
Rechteckoszillatoren, deren EXOR-Verknügpung UND das Einlesen von fünf 
AD-Werten?

Meine Idee wäre, die Potis nur auf Knopfdruck einzulesen. Dann müßten 
die AD-Wandler nur auf Demand ausgewertet werden und ansonsten wäre der 
Controller von Messoperationen befreit und könnte sich ganz der 
Soundausgabe widmen...

von Oktoberfestbesucher (Gast)


Lesenswert?

Sowas funktioniert so:
1. Die Versorgungsspannung wird eingeschaltet
2. Der µC kommt aus dem Reset
3. Timer & Interrupt werden initialisiert => es gibt ca. 100000 mal pro 
Sekunde einen Timerinterrupt. Dort werden die Frequenzen erzeugt, die 
Bits XOR-verknüpft und am Port ausgegeben.
4. Das Hauptprogramm ist eine Endlosschleife und wird ca. 100000 mal pro 
Sekunde unterbrochen ohne das das weiter stört.
Im Hauptprogramm werden die Poti's eingelesen.
Mit diesen Werten der Potis werden die Variablen geändert die das 
Interrupt-Programm zur Erzeugung der Frequenzen verwendet.
Dann wird das Display aktualisiert.
Und weiter zum Anfang der Hauptprogramm-Endlosschleife.

von hermy (Gast)


Lesenswert?

Oktoberfestbesucher schrieb:
> Dann wird das Display aktualisiert.
> Und weiter zum Anfang der Hauptprogramm-Endlosschleife.

Danke für die näheren Informationen zum Programmablauf!

Hatte unter Bascom mal eine Servosteuerung für 18 Servos mit M32 
programmiert. Da zuckten alle paar hundert mS die Servos aus 
unerfindlichen Gründen alle gleichzeitig.
Nach einigem Suchen und Probieren bin ich darauf gekommen, dass es am 
LCD-Display lag.
Habe daraufhin die Displaysteuerung aus dem Programm genommen und dann 
war das Servozucken verschwunden.

Bist Du sicher, dass bei der Interrupt-Programmierung solche (in dem 
Fall akkustischen) Zuckeffekte nicht auch auftreten können?

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> Bist Du sicher, dass bei der Interrupt-Programmierung solche (in dem
> Fall akkustischen) Zuckeffekte nicht auch auftreten können?

In diesem Fall ja!

von hermy (Gast)


Lesenswert?

Oktoberfestbesucher schrieb:
> In diesem Fall ja!

Wie kann man denn abschätzen, ob ein Interrupt den periodischen 
Gesamtablauf stört oder nicht?

von Oktoberfestbesucher (Gast)


Lesenswert?

hermy schrieb:
> Wie kann man denn abschätzen, ob ein Interrupt den periodischen
> Gesamtablauf stört oder nicht?

Wenn der µC z.B mit 8MHz läuft und der Timer so programmiert ist, das 
z.B. 100000 Timer-interrupts pro Sekund auftrete, dann musst du in der 
Timerinterrupt-routine weniger als 8MHz/100000 = 80 Taktzyklen 
verbrauchen.
Bedenke das auch noch ein paar Taktzyklen für den Rücksprung draufgehen.
Verbrauchst du mehr als 80 taktzyklen in der Timerinterruptroutine, 
holpert das ganze, für's Hauptprogramm bleib nix mehr an rechenleistung 
über und einige Timerinterups werden verschluckt.

von MWS (Gast)


Lesenswert?

Bitteschön, mal 'ne Übersetzung des Ursprungscodes zum Testen. Fand's 
interessant. Keine Ahnung ob bugfrei, Fehler dürfen behalten werden ;-)
Braucht ca. 63% Rechenleistung des µC, d.h. ~160 der 256 Takte die 
zwischen den Overflows zur Verfügung stehen. Ohne ASM in Bascom m.E. 
nicht zu machen.
1
$regfile = "m32def.dat"
2
$crystal = 8000000
3
$hwstack = 64
4
$swstack = 64
5
$framesize = 32
6
7
Const F1_preset = Fix(262 * 65536 / 31250)                  ' C
8
Const F2_preset = Fix(294 * 65536 / 31250)                  ' D
9
Const F3_preset = Fix(330 * 65536 / 31250)                  ' E
10
Const F4_preset = Fix(349 * 65536 / 31250)                  ' F
11
Const F5_preset = Fix(392 * 65536 / 31250)                  ' G
12
13
Dim Phasen_acc1 As Integer
14
Dim Phasen_acc2 As Integer
15
Dim Phasen_acc3 As Integer
16
Dim Phasen_acc4 As Integer
17
Dim Phasen_acc5 As Integer
18
Dim Frequenz1 As Integer
19
Dim Frequenz2 As Integer
20
Dim Frequenz3 As Integer
21
Dim Frequenz4 As Integer
22
Dim Frequenz5 As Integer
23
24
Frequenz1 = F1_preset
25
Frequenz2 = F2_preset
26
Frequenz3 = F3_preset
27
Frequenz4 = F4_preset
28
Frequenz5 = F5_preset
29
30
On Ovf0 Isr_ovf Nosave
31
Enable Ovf0
32
33
Ddrb = Bits(pb4 , Pb3 , Pb2 , Pb1 , Pb0)
34
Config Timer0 = Timer , Prescale = 1
35
36
Enable Interrupts
37
38
Do
39
40
Loop
41
42
End
43
44
Isr_ovf:
45
  !PUSH                    R16
46
  !IN                      R16,                       SREG
47
  !PUSH                    R16
48
  !PUSH                    R17
49
  !PUSH                    R18
50
  !PUSH                    R19
51
  !PUSH                    R20
52
  !PUSH                    XL
53
  !PUSH                    XH
54
  !PUSH                    ZL
55
  !PUSH                    ZH
56
Loadadr Phasen_acc1 , X
57
Loadadr Frequenz1 , Z
58
  !LDI                     R20,                       2^4
59
!ISR_Ovf_calc_start:
60
  !LD                      R16,                       X+
61
  !LD                      R17,                       X
62
  !LD                      R18,                       Z+
63
  !LD                      R19,                       Z+
64
  !ADD                     R16,                       R18
65
  !ADC                     R17,                       R19
66
  !ST                      X,                         R17
67
  !ST                      -X,                        R16
68
  !ADIW                    XL,                        2
69
  !BST                     R17,                       7
70
  !BLD                     R20,                       5
71
  !LSR                     R20
72
  !BRCC                    ISR_Ovf_calc_start
73
  !OUT                     PORTB,                     R20
74
  !POP                     ZH
75
  !POP                     ZL
76
  !POP                     XH
77
  !POP                     XL
78
  !POP                     R20
79
  !POP                     R19
80
  !POP                     R18
81
  !POP                     R17
82
  !POP                     R16
83
  !OUT                     SREG,                      R16
84
  !POP                     R16
85
Return

von Oktoberfestbesucher (Gast)


Lesenswert?

Melodie.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000017e  00000000  00000000  00000094  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000016  00800060  0000017e  00000212  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          0000000b  00800076  00800076  00000228  2**0
                  ALLOC
  3 .debug_aranges 00000020  00000000  00000000  00000228  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_pubnames 000000da  00000000  00000000  00000248  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_info   00000188  00000000  00000000  00000322  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_abbrev 00000089  00000000  00000000  000004aa  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_line   000000c1  00000000  00000000  00000533  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_frame  00000030  00000000  00000000  000005f4  2**2
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_str    0000011f  00000000  00000000  00000624  2**0
                  CONTENTS, READONLY, DEBUGGING

Disassembly of section .text:

00000000 <__vectors>:
   0:  0e c0         rjmp  .+28       ; 0x1e <__ctors_end>
   2:  26 c0         rjmp  .+76       ; 0x50 <__bad_interrupt>
   4:  25 c0         rjmp  .+74       ; 0x50 <__bad_interrupt>
   6:  24 c0         rjmp  .+72       ; 0x50 <__bad_interrupt>
   8:  2d c0         rjmp  .+90       ; 0x64 <__vector_4>
   a:  22 c0         rjmp  .+68       ; 0x50 <__bad_interrupt>
   c:  21 c0         rjmp  .+66       ; 0x50 <__bad_interrupt>
   e:  20 c0         rjmp  .+64       ; 0x50 <__bad_interrupt>
  10:  1f c0         rjmp  .+62       ; 0x50 <__bad_interrupt>
  12:  1e c0         rjmp  .+60       ; 0x50 <__bad_interrupt>
  14:  1d c0         rjmp  .+58       ; 0x50 <__bad_interrupt>
  16:  1c c0         rjmp  .+56       ; 0x50 <__bad_interrupt>
  18:  1b c0         rjmp  .+54       ; 0x50 <__bad_interrupt>
  1a:  1a c0         rjmp  .+52       ; 0x50 <__bad_interrupt>
  1c:  19 c0         rjmp  .+50       ; 0x50 <__bad_interrupt>

0000001e <__ctors_end>:
  1e:  11 24         eor  r1, r1
  20:  1f be         out  0x3f, r1  ; 63
  22:  cf ed         ldi  r28, 0xDF  ; 223
  24:  cd bf         out  0x3d, r28  ; 61

00000026 <__do_copy_data>:
  26:  10 e0         ldi  r17, 0x00  ; 0
  28:  a0 e6         ldi  r26, 0x60  ; 96
  2a:  b0 e0         ldi  r27, 0x00  ; 0
  2c:  ee e7         ldi  r30, 0x7E  ; 126
  2e:  f1 e0         ldi  r31, 0x01  ; 1
  30:  02 c0         rjmp  .+4        ; 0x36 <.do_copy_data_start>

00000032 <.do_copy_data_loop>:
  32:  05 90         lpm  r0, Z+
  34:  0d 92         st  X+, r0

00000036 <.do_copy_data_start>:
  36:  a6 37         cpi  r26, 0x76  ; 118
  38:  b1 07         cpc  r27, r17
  3a:  d9 f7         brne  .-10       ; 0x32 <.do_copy_data_loop>

0000003c <__do_clear_bss>:
  3c:  10 e0         ldi  r17, 0x00  ; 0
  3e:  a6 e7         ldi  r26, 0x76  ; 118
  40:  b0 e0         ldi  r27, 0x00  ; 0
  42:  01 c0         rjmp  .+2        ; 0x46 <.do_clear_bss_start>

00000044 <.do_clear_bss_loop>:
  44:  1d 92         st  X+, r1

00000046 <.do_clear_bss_start>:
  46:  a1 38         cpi  r26, 0x81  ; 129
  48:  b1 07         cpc  r27, r17
  4a:  e1 f7         brne  .-8        ; 0x44 <.do_clear_bss_loop>
  4c:  02 d0         rcall  .+4        ; 0x52 <main>
  4e:  95 c0         rjmp  .+298      ; 0x17a <_exit>

00000050 <__bad_interrupt>:
  50:  d7 cf         rjmp  .-82       ; 0x0 <__vectors>

00000052 <main>:
unsigned short int Frequenz5 = 392 * 65536 / 31250;
unsigned char PORTB_mirror = 0;

int main(void)
{
  DDRB = 0x1F;      // PB0 bis PB4 sind Output
  52:  8f e1         ldi  r24, 0x1F  ; 31
  54:  87 bb         out  0x17, r24  ; 23
  TCCR1 = 0b00000001;    // Prescaler = CK
  56:  81 e0         ldi  r24, 0x01  ; 1
  58:  80 bf         out  0x30, r24  ; 48
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable
  5a:  89 b7         in  r24, 0x39  ; 57
  5c:  84 60         ori  r24, 0x04  ; 4
  5e:  89 bf         out  0x39, r24  ; 57
  sei();          // Enable Interrrupt
  60:  78 94         sei
  62:  ff cf         rjmp  .-2        ; 0x62 <main+0x10>

00000064 <__vector_4>:
  while(1){}        // Endlosschleife
}
//**************************************************************
ISR(TIMER1_OVF_vect)
{
  64:  1f 92         push  r1
  66:  0f 92         push  r0
  68:  0f b6         in  r0, 0x3f  ; 63
  6a:  0f 92         push  r0
  6c:  11 24         eor  r1, r1
  6e:  2f 93         push  r18
  70:  3f 93         push  r19
  72:  4f 93         push  r20
  74:  5f 93         push  r21
  76:  6f 93         push  r22
  78:  7f 93         push  r23
  7a:  8f 93         push  r24
  7c:  9f 93         push  r25
  7e:  af 93         push  r26
  80:  bf 93         push  r27
  82:  ef 93         push  r30
  84:  ff 93         push  r31
  Phasen_acc1 += Frequenz1;
  86:  a0 91 6c 00   lds  r26, 0x006C
  8a:  b0 91 6d 00   lds  r27, 0x006D
  8e:  80 91 76 00   lds  r24, 0x0076
  92:  90 91 77 00   lds  r25, 0x0077
  96:  a8 0f         add  r26, r24
  98:  b9 1f         adc  r27, r25
  9a:  b0 93 77 00   sts  0x0077, r27
  9e:  a0 93 76 00   sts  0x0076, r26
  Phasen_acc2 += Frequenz2;
  a2:  e0 91 6e 00   lds  r30, 0x006E
  a6:  f0 91 6f 00   lds  r31, 0x006F
  aa:  80 91 78 00   lds  r24, 0x0078
  ae:  90 91 79 00   lds  r25, 0x0079
  b2:  e8 0f         add  r30, r24
  b4:  f9 1f         adc  r31, r25
  b6:  f0 93 79 00   sts  0x0079, r31
  ba:  e0 93 78 00   sts  0x0078, r30
  Phasen_acc3 += Frequenz3;
  be:  20 91 70 00   lds  r18, 0x0070
  c2:  30 91 71 00   lds  r19, 0x0071
  c6:  80 91 7a 00   lds  r24, 0x007A
  ca:  90 91 7b 00   lds  r25, 0x007B
  ce:  28 0f         add  r18, r24
  d0:  39 1f         adc  r19, r25
  d2:  30 93 7b 00   sts  0x007B, r19
  d6:  20 93 7a 00   sts  0x007A, r18
  Phasen_acc4 += Frequenz4;
  da:  60 91 72 00   lds  r22, 0x0072
  de:  70 91 73 00   lds  r23, 0x0073
  e2:  80 91 7c 00   lds  r24, 0x007C
  e6:  90 91 7d 00   lds  r25, 0x007D
  ea:  68 0f         add  r22, r24
  ec:  79 1f         adc  r23, r25
  ee:  70 93 7d 00   sts  0x007D, r23
  f2:  60 93 7c 00   sts  0x007C, r22
  Phasen_acc5 += Frequenz5;
  f6:  40 91 74 00   lds  r20, 0x0074
  fa:  50 91 75 00   lds  r21, 0x0075
  fe:  80 91 7e 00   lds  r24, 0x007E
 102:  90 91 7f 00   lds  r25, 0x007F
 106:  48 0f         add  r20, r24
 108:  59 1f         adc  r21, r25
 10a:  50 93 7f 00   sts  0x007F, r21
 10e:  40 93 7e 00   sts  0x007E, r20

  PORTB_mirror = (Phasen_acc1 & 0x8000)>>15
 112:  e0 70         andi  r30, 0x00  ; 0
 114:  f0 78         andi  r31, 0x80  ; 128
 116:  8f 2f         mov  r24, r31
 118:  82 95         swap  r24
 11a:  86 95         lsr  r24
 11c:  86 95         lsr  r24
 11e:  83 70         andi  r24, 0x03  ; 3
 120:  20 70         andi  r18, 0x00  ; 0
 122:  30 78         andi  r19, 0x80  ; 128
 124:  93 2f         mov  r25, r19
 126:  92 95         swap  r25
 128:  96 95         lsr  r25
 12a:  97 70         andi  r25, 0x07  ; 7
 12c:  89 2b         or  r24, r25
 12e:  9b 2f         mov  r25, r27
 130:  99 1f         adc  r25, r25
 132:  99 27         eor  r25, r25
 134:  99 1f         adc  r25, r25
 136:  89 2b         or  r24, r25
 138:  60 70         andi  r22, 0x00  ; 0
 13a:  70 78         andi  r23, 0x80  ; 128
 13c:  97 2f         mov  r25, r23
 13e:  92 95         swap  r25
 140:  9f 70         andi  r25, 0x0F  ; 15
 142:  89 2b         or  r24, r25
 144:  40 70         andi  r20, 0x00  ; 0
 146:  50 78         andi  r21, 0x80  ; 128
 148:  95 2f         mov  r25, r21
 14a:  96 95         lsr  r25
 14c:  96 95         lsr  r25
 14e:  96 95         lsr  r25
 150:  89 2b         or  r24, r25
 152:  80 93 80 00   sts  0x0080, r24
          |(Phasen_acc2 & 0x8000)>>14
          |(Phasen_acc3 & 0x8000)>>13
          |(Phasen_acc4 & 0x8000)>>12
          |(Phasen_acc5 & 0x8000)>>11;
  PORTB = PORTB_mirror;
 156:  88 bb         out  0x18, r24  ; 24
}
 158:  ff 91         pop  r31
 15a:  ef 91         pop  r30
 15c:  bf 91         pop  r27
 15e:  af 91         pop  r26
 160:  9f 91         pop  r25
 162:  8f 91         pop  r24
 164:  7f 91         pop  r23
 166:  6f 91         pop  r22
 168:  5f 91         pop  r21
 16a:  4f 91         pop  r20
 16c:  3f 91         pop  r19
 16e:  2f 91         pop  r18
 170:  0f 90         pop  r0
 172:  0f be         out  0x3f, r0  ; 63
 174:  0f 90         pop  r0
 176:  1f 90         pop  r1
 178:  18 95         reti

0000017a <_exit>:
 17a:  f8 94         cli

0000017c <__stop_program>:
 17c:  ff cf         rjmp  .-2        ; 0x17c <__stop_program>

von Oktoberfestbesucher (Gast)


Lesenswert?

MWS schrieb:
> Ohne ASM in Bascom m.E.
> nicht zu machen.

Dann machs in C

von MWS (Gast)


Lesenswert?

> MWS schrieb:
>> Ohne ASM in Bascom m.E.
>> nicht zu machen.

> Dann machs in C

Mag kein C. Dann lieber ASM.

von Лдгпысруш-ук (Gast)


Lesenswert?

>Mag kein C. Dann lieber ASM.
Eher: Kann kein C. Dann lieber ASM

Dann guckst du dir den Code in 2 Jahren an und verstehst Null!

von MWS (Gast)


Lesenswert?

Nachtrag:
Kleiner Schönheitsfehler, "unsigned short int" muss mit "Word" übersetzt 
werden, statt mit "Integer", hat allerdings auf die eigentliche Routine 
keinen Einfluss.
1
Dim Phasen_acc1 As Word
2
...

@Oktoberfestbesucher,
nicht schlecht was C da produziert hat, aber meine Lösung ist kleiner 
und schneller als das C Compilat, wenn auch nur unwesentlich, 13 Takte. 
Und das obwohl mein Code 'ne Schleife benutzt und nicht "ungerollt" ist.

@Лдгпысруш-ук
> Dann guckst du dir den Code in 2 Jahren an und verstehst Null!
Wenn ich's ohne Kommentare lasse, dann muss ich in zwei Jahren erst 
wieder drüber nachdenken, da hast Du recht. Würde mir aber beim C Code 
ganz genauso passieren, denn ich habe mich noch nie mit DDS beschäftigt 
und offen gesagt nur sehr geringe Ahnung davon. Aber ich versteh' C und 
kann ganz leidlich ASM.

> Eher: Kann kein C.
Das hättest Du jetzt nicht sagen dürfen, ich will mir die verbogene 
Sprache nur nicht antun, mit Makefile und einer Legion von möglichen 
Schalterchen. Da ich C nicht übe, wäre ich im Schreiben natürlich 
erstmal langsamer als in Bascom, und müsste mir ein paar Dinge aneignen, 
geht aber recht schnell. Ich hab' nur einfach keine Lust auf C. Außerdem 
schreib ich gern ASM und Inlineassembler in C ist nur noch peinlich. Das 
tu ich mir sicher nicht an. Das ich C verstehe, sollte Dir aus meiner 
Übersetzung klar werden.

Was wird das jetzt eigentlich wieder ? Wieder so'n Längenvergleich oder 
der übliche Versuch der Missionierung ?

Mein Code war für hermy oder andere gedacht, die eben C nicht können, 
nicht mögen, oder was auch immer. Kannst ja drüber weglesen was ich 
geschrieben hab'.

von MWS (Gast)


Lesenswert?

Hier noch die EXOR Version der ISR:
1
Isr_ovf:
2
  !PUSH                    R16
3
  !IN                      R16,                       SREG
4
  !PUSH                    R16
5
  !PUSH                    R17
6
  !PUSH                    R18
7
  !PUSH                    R19
8
  !PUSH                    R20
9
  !PUSH                    R21
10
  !PUSH                    XL
11
  !PUSH                    XH
12
  !PUSH                    ZL
13
  !PUSH                    ZH
14
Loadadr Phasen_acc1 , X
15
Loadadr Frequenz1 , Z
16
  !CLR                     R20
17
  !LDI                     R21,                       5
18
!ISR_Ovf_calc_start:
19
  !LD                      R16,                       X+
20
  !LD                      R17,                       X
21
  !LD                      R18,                       Z+
22
  !LD                      R19,                       Z+
23
  !ADD                     R16,                       R18
24
  !ADC                     R17,                       R19
25
  !ST                      X,                         R17
26
  !ST                      -X,                        R16
27
  !ADIW                    XL,                        2
28
  !EOR                     R20,                       R17
29
  !DEC                     R21
30
  !BRNE                    ISR_Ovf_calc_start
31
  !BST                     R20,                       7
32
  !BLD                     R21,                       0
33
  !OUT                     PORTB,                     R21
34
  !POP                     ZH
35
  !POP                     ZL
36
  !POP                     XH
37
  !POP                     XL
38
  !POP                     R21
39
  !POP                     R20
40
  !POP                     R19
41
  !POP                     R18
42
  !POP                     R17
43
  !POP                     R16
44
  !OUT                     SREG,                      R16
45
  !POP                     R16
46
Return

@ Oktoberfestbesucher,

Danke für die Vorlage.

von hermi (Gast)


Lesenswert?

Hallo,
ich verstehe leider im Moment fast nur Datensalat.

Wie strickt man das ASM-Prog denn jetzt zusammen, damit es funktioniert 
(mit EXOR und ADC/Potis)?
Das ist jetzt ohne LCD, oder?

von Oktoberfestbesucher (Gast)


Lesenswert?

Ich habe hier mal einen kleinen Ausschnitt aus einem Assembler-programm 
das ich vor 2 Jahren geschrieben habe.
Da ich keine Zeit zum schreiben von Kommentaren habe,
verwende ich viele Label. Damit wird das Programm dann quasi 
selbstkommentierend...
1
;********************************************************************
2
; Motorschutzschalter 506157 
3
; 21.10.2008
4
; AT TINY84
5
; Status und ADC-Wert wird über RS232 mit 115200 Baud ausgeben
6
;********************************************************************
7
.include "C:\Programme\Atmel\AVR Tools\AvrAssembler2\Appnotes\TN84def.inc"
8
;********************************************************************
9
.equ  Schutzbuegel     = 0  ;PINB Eingang
10
.equ  Freigabe_Taster  = 1  ;PINB Eingang
11
.equ  RS232_Port       = 2  ;PortB Ausgang
12
13
.equ  Switch_PT100     = 2  ;PortA Ausgang
14
.equ  Switch_PT1000    = 3  ;PortA Ausgang
15
.equ  Relais_Motor_ON  = 4  ;PortA Ausgang
16
.equ  HCT4094_Strobe   = 5  ;PortA Ausgang
17
.equ  HCT4094_Data     = 6  ;PortA Ausgang
18
.equ  HCT4094_Clk      = 7  ;PortA Ausgang
19
20
.equ  Led_Overheated   = 0x01
21
.equ  Led_560k_Switch  = 0x02
22
.equ  Led_Buegel_err   = 0x04
23
.equ  Led_Buegel_ok    = 0x08
24
.equ  Led_PT100        = 0x10
25
.equ  Led_PT1000       = 0x20
26
.equ  Led_Run          = 0x40
27
.equ  Led_Freigabe     = 0x80
28
;********************************************************************
29
.def    ACC             = R16
30
.def    Loopcounter     = R17
31
.def    buff_l          = R18
32
.def    buff_h          = R19
33
.def    Led_Status      = R20
34
35
.def    Zahl_l          = R24
36
.def    Zahl_h          = R25
37
;********************************************************************
38
.CSEG
39
Start:
40
    RCALL  Port_init
41
    CLR    Led_Status
42
    RCALL  Led_Status_Anzeigen
43
;********************************************************************
44
    ldi    ZH,high(2*Botschaft1)
45
    ldi    ZL,low(2*Botschaft1)
46
    RCALL  Text_ausgeben
47
    RCALL  Spannungsteiler_Messung
48
    RCALL  Zahl_ausgeben
49
    MOV    Zahl_l,ACC
50
    LDI    Zahl_h,0
51
    RCALL  Zahl_ausgeben
52
    RCALL  CR_LF_ausgeben
53
    TST    ACC
54
    BRNE   Hardwarefehler
55
;********************************************************************
56
Sensor_such_Schleife:
57
    ldi    ZH,high(2*Botschaft2)
58
    ldi    ZL,low(2*Botschaft2)
59
    RCALL  Text_ausgeben
60
    RCALL  Switch_560k_Messung
61
    SBR    Led_Status,Led_560k_Switch
62
    RCALL  Led_Status_Anzeigen
63
    CBR    Led_Status,Led_560k_Switch
64
    RCALL  Zahl_ausgeben
65
    MOV    Zahl_l,ACC
66
    LDI    Zahl_h,0
67
    RCALL  Zahl_ausgeben
68
    RCALL  CRLF_ausgeben
69
    TST    ACC
70
    BREQ   Switch_560k_Sensor
71
    RCALL  Delay_1000
72
73
    SBR    Led_Status,Led_PT100
74
    RCALL  Led_Status_Anzeigen
75
    ldi    ZH,high(2*Botschaft3)
76
    ldi    ZL,low(2*Botschaft3)
77
    RCALL  Text_ausgeben
78
    RCALL  PT100_Messung
79
    RCALL  Zahl_ausgeben
80
    MOV    Zahl_l,ACC
81
    LDI    Zahl_h,0
82
    RCALL  Zahl_ausgeben
83
    RCALL  CRLF_ausgeben
84
    TST    ACC
85
    BREQ   PT100_Sensor
86
    CBR    Led_Status,Led_PT100
87
    RCALL  Delay_1000
88
89
    SBR    Led_Status,Led_PT1000
90
    RCALL  Led_Status_Anzeigen
91
    ldi    ZH,high(2*Botschaft4)
92
    ldi    ZL,low(2*Botschaft4)
93
    RCALL  Text_ausgeben
94
    RCALL  PT1000_Messung
95
    RCALL  Zahl_ausgeben
96
    MOV    Zahl_l,ACC
97
    LDI    Zahl_h,0
98
    RCALL  Zahl_ausgeben
99
    RCALL  CRLF_ausgeben
100
    TST    ACC
101
    BREQ   PT1000_Sensor
102
    CBR    Led_Status,Led_PT1000
103
    RCALL  Delay_1000
104
105
    RJMP   Sensor_such_Schleife
106
;********************************************************************

von MWS (Gast)


Lesenswert?

hermi oder hermy ?

Das ist nur die (hoffnungsvollerweise fehlerfreie) Bascom Übersetzung 
des von Oktoberfestbesucher geposteten C Codes. Mein letztes Post war 
die auf XOR geänderte ISR, auch laut C Beispielcode, die dann halt nur 
auf einem Ausgang das ver-xor-te Signal rausgibt.

Der Originalcode arbeitet mit festen Frequenzvorgaben, diese sind in 
Frequenz1..5 abgelegt, d.h. der erste Beispielscode gibt an 5 Pins 5 
feste Frequenzen laut Vorgabe aus, der zweite Beispielscode die 
ver-xor-ung dieser 5 Frequenzen. Alles, was Du zusätzlich willst, musst 
Du selbst programmieren, also ADC abfragen, Frequenzen setzen, LCD 
Ausgabe usw.

Es gibt nur eine Sache, auf die Du aufpassen musst, und zwar ist es der 
"atomare" Zugriff auf die Variablen Frequenz1..5. Grund dafür ist, daß 
beim Neubeschreiben diese Variablen jederzeit ein Timerinterrupt 
dazwischenhauen kann, und dann ist möglicherweise nur ein Byte des Words 
oder des unsigned short ints geschrieben. Das würde falsche Werte und 
demgemäß zufällige Töne ergeben und die würde man hören.

Man darf den Timerinterrupt auch nicht sperren, denn das würde die DDS 
Erzeugung stören. Das Problem ist zu lösen, indem man ein 
Synchronisationsflag am Ende der ISR setzt. Man wartet dann bis dieses 
Flag gesetzt ist, und schreibt erst dann neue Werte nach Frequenz1..5

Aus Gesagtem sollte auch klar sein, daß das Programm ohne weitere 
Interrupts arbeiten muss, solange Sound ausgegeben wird.

Wenn Du soweit bist, dann sag Bescheid, aber versuch erstmal 
Oktoberfestbesucher's Code oder meinen in der einfachsten Version zum 
Laufen zu bringen.

@Oktoberfestbesucher,

ja, so versuch ich meine Labels auch anzulegen.

von Oktoberfestbesucher (Gast)


Lesenswert?

MWS schrieb:
> Das Problem ist zu lösen, indem man ein
> Synchronisationsflag am Ende der ISR setzt. Man wartet dann bis dieses
> Flag gesetzt ist, und schreibt erst dann neue Werte nach Frequenz1..5

?????????

> Aus Gesagtem sollte auch klar sein, daß das Programm ohne weitere
> Interrupts arbeiten muss, solange Sound ausgegeben wird.

?????????

Die Sounderzeugung passiert aus der Interrupt-Service-Routine (ISR) 
heraus.
Dieses läuft quasi im Hintergrund.

Es ist völlig OK, wenn das Hauptprogramm eine der globalen 
16-Bit-Variablen ändert, kurz für ein paar Taktzyklen, den 
Timerinterrupt zu sperren. Ein Interrupt der während dieser Sperrzeit 
ausgelöst wird, wird dann nur ein paar Taktzyklen später bedient.

Es ist in diesem Falle aber auch OK, wenn man, während das Hauptprogramm 
eine der 16-Bit-Variablen ändert, den Timerinterrupt nicht sperrt.
Die 16-Bit_Variablen werden nur geändert, während jemand am Poti dreht.
Da bei dieser ganzen Geschichte eh metallisch klingende Sounds mit einem 
breiten Frequenzspektrum erzeugt werden, stören ein paar falsche Töne 
überhaupt nicht.

von MWS (Gast)


Lesenswert?

Oktoberfestbesucher,

ich dachte nur ein wenig weiter.

Ersteres wäre mein Ansatz gewesen, ein ungestörtes Schreiben der 
Variablen zu ermöglichen, ohne den DDS Ablauf zu stören. Ein Sync-Flag 
ist m.E. der sauberere Weg, als den Int zu sperren.

Es könnte doch jemand auf die Idee kommen einen Sequenzer reinzubasteln, 
oder die Tonhöhe in einer Schleife zu verändern. Das würde zu häufigeren 
Zugriffen führen und sich störend auswirken.
Aber da ich's "trocken" programmiert und nicht angehört hab', lass' ich 
mir da gerne etwas sagen.

> Dieses läuft quasi im Hintergrund.
Ja, schon klar :D

Aber andere ISRs, wie z.B. eine Timer1 ISR als Zeitgeber für einen 
Sequenzer können die Ausführung der DDS Timer ISR verzögern. Allein die 
5 Poti Lösung braucht keine anderen ISRs.

von Oktoberfestbesucher (Gast)


Lesenswert?

MWS schrieb:
> Aber andere ISRs, wie z.B. eine Timer1 ISR als Zeitgeber für einen
> Sequenzer können die Ausführung der DDS Timer ISR verzögern.

Dann muss so ein Interrupt eine niedrige Priorität bekommen.

Oder kein Interrupt für so was verwenden, sondern folgende Lösung:
In der Sounderzeugungs-interrupt-routine wird jedesmal eine globale 
Variable hochgezählt. Im Hauptprogramm wird dann per Polling geschaut ob 
sie diesen oder jenen Wert erreicht hat und dann die Soundfrequenzen 
gewechselt.

von MWS (Gast)


Lesenswert?

Oktoberfestbesucher schrieb:
> Dann muss so ein Interrupt eine niedrige Priorität bekommen.
Bei AVRs nur durch nested Interrupts möglich

> Im Hauptprogramm wird dann per Polling geschaut ob sie diesen oder jenen
> Wert erreicht hat und dann die Soundfrequenzen gewechselt.

Klar, aber man kann einen anderen Timer, sofern verfügbar, pollen. Aber 
das war ja mein Argument, keine Ints verwenden. Natürlich gehen nested 
Ints, nur sollte der Zauberlehrling da wissen was er tut :D

War nicht für Dich gedacht, Dir muss ich's nicht erklären, Du weist ja 
was Du machst.

von hermy (Gast)


Lesenswert?

von mir nur eine kurze meldung nebenbei.

hab mir ein paar bücher über AVRs besorgt, um mich mal in die basis 
einzulesen, wie das mit den ganzen registern, interrupts, timern etc. 
funktioniert, das war bei bascom doch irgendwie auf der strecke 
geblieben.

wo sind wir denn jetzt, gibt es schon eine fertige version, die man nur 
noch auf den chip zu brennen braucht?

viele grüße!

von Karl H. (kbuchegg)


Lesenswert?

hermy schrieb:

> wo sind wir denn jetzt, gibt es schon eine fertige version, die man nur
> noch auf den chip zu brennen braucht?

Ich sach mal so:
Es ist dein Projekt!

von hermy (Gast)


Lesenswert?

ich sehe schon, man hat ein einsehen und das thema zurückverschoben...

Karl heinz Buchegger schrieb:
> hermy schrieb:
>
>> wo sind wir denn jetzt, gibt es schon eine fertige version, die man nur
>> noch auf den chip zu brennen braucht?
>
> Ich sach mal so:
> Es ist dein Projekt!

ein paar tage brauche ich mindestens noch, um die sache ASM-mässig 
zusammenzustricken ;)
und einen echten überblick hab ich z.zt. auch nicht. bei den ganzen 
programmzeilen oben, die alle nicht von mir stammen, würde ich eher mal 
sagen, es ist UNSER projekt!

von Karl H. (kbuchegg)


Lesenswert?

hermy schrieb:
> ich sehe schon, man hat ein einsehen und das thema zurückverschoben...
>
> Karl heinz Buchegger schrieb:
>> hermy schrieb:
>>
>>> wo sind wir denn jetzt, gibt es schon eine fertige version, die man nur
>>> noch auf den chip zu brennen braucht?
>>
>> Ich sach mal so:
>> Es ist dein Projekt!
>
> ein paar tage brauche ich mindestens noch, um die sache ASM-mässig
> zusammenzustricken ;)
> und einen echten überblick hab ich z.zt. auch nicht. bei den ganzen
> programmzeilen oben, die alle nicht von mir stammen, würde ich eher mal
> sagen, es ist UNSER projekt!

Genau das würde ich nicht sagen.
Es ist dein Projekt und jemand hilft dir dabei.

Du hast Schwierigkeiten bei diesem 30 Zeiler den Überblick zu behalten? 
Na dann, gutes Gelingen.

Ich denke du hast das Prinzip immer noch nicht durchschaut.
Analogie:
Ich steh mit einer Nadel hinter dir und steche dich jede Sekunde einmal 
in den Allerwertesten. Du zählst mit und bei jedem 2-ten Stich hebst du 
den linken Arm, bei jedem 3-ten Stich hebst du den rechten Arm.
Wie sieht das für jemanden aus, der nicht weiß, dass ich mit einer Nadel 
hinter dir stehe?
Nun für den sieht es so aus, als ob sich dein linker Arm mit einer 
Frequenz von 0.5Hz hebt, während sich dein linker Arm mit einer Frequenz 
von 0.33Hz hebt. Wenn ich dir jetzt sage, dass sich dein rechter Arm bei 
jedem 5-ten mal heben soll, dann bekommt dein rechter Arm eine Frequenz 
von 0.2Hz.
Obwohl du nur einen Zeitgeber hast, hast du unterschiedliche Frequenzen 
erzeugt. Und wenn du noch 3 Arme mehr hättest, könntest du mit diesem 
Schema 5 unterschiedliche Frequenzen erzeugen. Du darfst nur nicht mit 
den Zählern für die Arme durcheinander kommen.

von MWS (Gast)


Lesenswert?

hermy schrieb:
> ein paar tage brauche ich mindestens noch, um die sache ASM-mässig
> zusammenzustricken ;)

Sehr interessant, da in ASM nix zusammengestrickt werden muss.

In Oktoberfestbesucher's Code nicht und in meinem auch nicht.
Möglicherweise ist Dir die leere  while(1){} oder die leere Do/Loop 
entgangen, die nur darauf wartet Deine Geistesblitze bezüglich Variation 
der 5 Frequenzen aufzunehmen. Das kann alles in gutem alten C oder 
Bascom geschehen.

von hermy (Gast)


Lesenswert?

MWS schrieb:
> In Oktoberfestbesucher's Code nicht und in meinem auch nicht.
> Möglicherweise ist Dir die leere  while(1){} oder die leere Do/Loop
> entgangen, die nur darauf wartet Deine Geistesblitze bezüglich Variation
> der 5 Frequenzen aufzunehmen. Das kann alles in gutem alten C oder
> Bascom geschehen.

ich muss auch gestehen, dass ich mich noch nicht intensiv mit den progs 
beschäftigt habe.

ehrlich gesagt wollte ich sogar auch noch eigene ASM-gehversuche 
unternehmen ;)


nette analogie mit den armen, aber bei dem versuch, mir in den 
allerwertesten zu stechen, würden meine arme sich eher in richtung 
mensch-mit-der-nadel bewegen (aua, und zwar nicht für mich ;-))

spass beiseite, wie geht das denn jetzt mit den "unscharfen" flanken zur 
stufenlosen frequenzregelung?
es macht ja keinen sinn, wenn man nur bestimmte teiler einer 
grundfrequenz erzeugen kann...

morgen mehr, bis dahin guten rutsch an alle leser in den 1.5.!
;)

von Karl H. (kbuchegg)


Lesenswert?

hermy schrieb:

> spass beiseite, wie geht das denn jetzt mit den "unscharfen" flanken zur
> stufenlosen frequenzregelung?
> es macht ja keinen sinn, wenn man nur bestimmte teiler einer
> grundfrequenz erzeugen kann...

Das kommt drauf an :-)
Wenn ich dich nicht einmal in der Sekunde steche, sondern 1000 mal und 
du nicht bis 2 sondern bis 2000 zählst, dann haben wir beide auch wieder 
0.5Hz erzeugt.
Aber: Anstatt bis 2000, kann ich dich jetzt auch bis 1999 zählen lassen, 
was einer Armhebefreuqenz von 0.50025Hz entspricht. Und wenn ich dich 
bis 1998 zählen lasse, dann hast du eine Armhebefrequenz von 0.5005Hz.
Jetzt kann ich dich natürlich nicht nur 1000 mal in der Sekunde stechen, 
sondern auch 10000 mal, mit dem Effekt, das ich deinen Zählerstand (und 
damit die zu erzeugende Frequenz) noch feiner abstufen kann. OK, das 
geht nicht, weil du nicht so schnell zählen kannst. Aber dein µC kann 
das :-)

von ... (Gast)


Lesenswert?

Nimm eine größere Nadel. Was meinst Du wie schnell er auf einmal Zählen 
kann :-)

von Karl H. (kbuchegg)


Lesenswert?

Wenn er weiter so phantasielos agiert, nehm ich die ganz große 
Klistierspritze :-)

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.