mikrocontroller.net

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


Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 Moderator
Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!)
;)

Autor: der Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ingolf O. (headshotzombie)
Datum:

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

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Ingolf O. (headshotzombie)
Datum:

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

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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."

Autor: Ingolf O. (headshotzombie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Elektor 7/86 S.54

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include <avr/interrupt.h>

unsigned short int Phasen_acc1 = 0;
unsigned short int Phasen_acc2 = 0;
unsigned short int Phasen_acc3 = 0;
unsigned short int Phasen_acc4 = 0;
unsigned short int Phasen_acc5 = 0;
unsigned short int Frequenz1 = 262 * 65536 / 31250; // C
unsigned short int Frequenz2 = 294 * 65536 / 31250; // D
unsigned short int Frequenz3 = 330 * 65536 / 31250; // E
unsigned short int Frequenz4 = 349 * 65536 / 31250; // F
unsigned short int Frequenz5 = 392 * 65536 / 31250; // G
unsigned char PORTB_mirror = 0;

int main(void)
{
  DDRB = 0x1F;      // PB0 bis PB4 sind Output
  TCCR1 = 0b00000001;    // Prescaler = CK 
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable
  sei();          // Enable Interrrupt
  while(1){}        // Endlosschleife
}
//**************************************************************
ISR(TIMER1_OVF_vect)
{
  Phasen_acc1 += Frequenz1;
  Phasen_acc2 += Frequenz2;
  Phasen_acc3 += Frequenz3;
  Phasen_acc4 += Frequenz4;
  Phasen_acc5 += Frequenz5;

PORTB_mirror  = (Phasen_acc1 & 0x8000)>>15 
               |(Phasen_acc2 & 0x8000)>>14
               |(Phasen_acc3 & 0x8000)>>13
               |(Phasen_acc4 & 0x8000)>>12      
               |(Phasen_acc5 & 0x8000)>>11;

  PORTB = PORTB_mirror;

}
//**************************************************************
Halt uns mal über deine Fortschritte auf dem laufenden.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
  Phasen_acc1 += Frequenz1;
Dies ist eine Software DDS (Digitale Direkt Synthese)
(Phasen_acc1 & 0x8000)
dient nur dazu das most significant Bit herauszuschneiden.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hauke Radtki (lafkaschar) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
falsch, 10µs ;)
Schafft der µC locker.

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...!?!?!

Autor: T. C. (tripplex)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
  TCCR1 = 0b00000001;    // Prescaler = CK 
  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...

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
PORTB         = ((Phasen_acc1 >> 8)
                ^(Phasen_acc2 >> 8)
                ^(Phasen_acc3 >> 8)
                ^(Phasen_acc4 >> 8)
                ^(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

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oktoberfestbesucher schrieb:
> In diesem Fall ja!

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

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 64
$framesize = 32

Const F1_preset = Fix(262 * 65536 / 31250)                  ' C
Const F2_preset = Fix(294 * 65536 / 31250)                  ' D
Const F3_preset = Fix(330 * 65536 / 31250)                  ' E
Const F4_preset = Fix(349 * 65536 / 31250)                  ' F
Const F5_preset = Fix(392 * 65536 / 31250)                  ' G

Dim Phasen_acc1 As Integer
Dim Phasen_acc2 As Integer
Dim Phasen_acc3 As Integer
Dim Phasen_acc4 As Integer
Dim Phasen_acc5 As Integer
Dim Frequenz1 As Integer
Dim Frequenz2 As Integer
Dim Frequenz3 As Integer
Dim Frequenz4 As Integer
Dim Frequenz5 As Integer

Frequenz1 = F1_preset
Frequenz2 = F2_preset
Frequenz3 = F3_preset
Frequenz4 = F4_preset
Frequenz5 = F5_preset

On Ovf0 Isr_ovf Nosave
Enable Ovf0

Ddrb = Bits(pb4 , Pb3 , Pb2 , Pb1 , Pb0)
Config Timer0 = Timer , Prescale = 1

Enable Interrupts

Do

Loop

End

Isr_ovf:
  !PUSH                    R16
  !IN                      R16,                       SREG
  !PUSH                    R16
  !PUSH                    R17
  !PUSH                    R18
  !PUSH                    R19
  !PUSH                    R20
  !PUSH                    XL
  !PUSH                    XH
  !PUSH                    ZL
  !PUSH                    ZH
Loadadr Phasen_acc1 , X
Loadadr Frequenz1 , Z
  !LDI                     R20,                       2^4
!ISR_Ovf_calc_start:
  !LD                      R16,                       X+
  !LD                      R17,                       X
  !LD                      R18,                       Z+
  !LD                      R19,                       Z+
  !ADD                     R16,                       R18
  !ADC                     R17,                       R19
  !ST                      X,                         R17
  !ST                      -X,                        R16
  !ADIW                    XL,                        2
  !BST                     R17,                       7
  !BLD                     R20,                       5
  !LSR                     R20
  !BRCC                    ISR_Ovf_calc_start
  !OUT                     PORTB,                     R20
  !POP                     ZH
  !POP                     ZL
  !POP                     XH
  !POP                     XL
  !POP                     R20
  !POP                     R19
  !POP                     R18
  !POP                     R17
  !POP                     R16
  !OUT                     SREG,                      R16
  !POP                     R16
Return

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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>

Autor: Oktoberfestbesucher (Gast)
Datum:

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

Dann machs in C

Autor: MWS (Gast)
Datum:

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

> Dann machs in C

Mag kein C. Dann lieber ASM.

Autor: Лдгпысруш-ук (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: MWS (Gast)
Datum:

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

@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'.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch die EXOR Version der ISR:
Isr_ovf:
  !PUSH                    R16
  !IN                      R16,                       SREG
  !PUSH                    R16
  !PUSH                    R17
  !PUSH                    R18
  !PUSH                    R19
  !PUSH                    R20
  !PUSH                    R21
  !PUSH                    XL
  !PUSH                    XH
  !PUSH                    ZL
  !PUSH                    ZH
Loadadr Phasen_acc1 , X
Loadadr Frequenz1 , Z
  !CLR                     R20
  !LDI                     R21,                       5
!ISR_Ovf_calc_start:
  !LD                      R16,                       X+
  !LD                      R17,                       X
  !LD                      R18,                       Z+
  !LD                      R19,                       Z+
  !ADD                     R16,                       R18
  !ADC                     R17,                       R19
  !ST                      X,                         R17
  !ST                      -X,                        R16
  !ADIW                    XL,                        2
  !EOR                     R20,                       R17
  !DEC                     R21
  !BRNE                    ISR_Ovf_calc_start
  !BST                     R20,                       7
  !BLD                     R21,                       0
  !OUT                     PORTB,                     R21
  !POP                     ZH
  !POP                     ZL
  !POP                     XH
  !POP                     XL
  !POP                     R21
  !POP                     R20
  !POP                     R19
  !POP                     R18
  !POP                     R17
  !POP                     R16
  !OUT                     SREG,                      R16
  !POP                     R16
Return

@ Oktoberfestbesucher,

Danke für die Vorlage.

Autor: hermi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...
;********************************************************************
; Motorschutzschalter 506157 
; 21.10.2008
; AT TINY84
; Status und ADC-Wert wird über RS232 mit 115200 Baud ausgeben
;********************************************************************
.include "C:\Programme\Atmel\AVR Tools\AvrAssembler2\Appnotes\TN84def.inc"
;********************************************************************
.equ  Schutzbuegel     = 0  ;PINB Eingang
.equ  Freigabe_Taster  = 1  ;PINB Eingang
.equ  RS232_Port       = 2  ;PortB Ausgang

.equ  Switch_PT100     = 2  ;PortA Ausgang
.equ  Switch_PT1000    = 3  ;PortA Ausgang
.equ  Relais_Motor_ON  = 4  ;PortA Ausgang
.equ  HCT4094_Strobe   = 5  ;PortA Ausgang
.equ  HCT4094_Data     = 6  ;PortA Ausgang
.equ  HCT4094_Clk      = 7  ;PortA Ausgang

.equ  Led_Overheated   = 0x01
.equ  Led_560k_Switch  = 0x02
.equ  Led_Buegel_err   = 0x04
.equ  Led_Buegel_ok    = 0x08
.equ  Led_PT100        = 0x10
.equ  Led_PT1000       = 0x20
.equ  Led_Run          = 0x40
.equ  Led_Freigabe     = 0x80
;********************************************************************
.def    ACC             = R16
.def    Loopcounter     = R17
.def    buff_l          = R18
.def    buff_h          = R19
.def    Led_Status      = R20

.def    Zahl_l          = R24
.def    Zahl_h          = R25
;********************************************************************
.CSEG
Start:
    RCALL  Port_init
    CLR    Led_Status
    RCALL  Led_Status_Anzeigen
;********************************************************************
    ldi    ZH,high(2*Botschaft1)
    ldi    ZL,low(2*Botschaft1)
    RCALL  Text_ausgeben
    RCALL  Spannungsteiler_Messung
    RCALL  Zahl_ausgeben
    MOV    Zahl_l,ACC
    LDI    Zahl_h,0
    RCALL  Zahl_ausgeben
    RCALL  CR_LF_ausgeben
    TST    ACC
    BRNE   Hardwarefehler
;********************************************************************
Sensor_such_Schleife:
    ldi    ZH,high(2*Botschaft2)
    ldi    ZL,low(2*Botschaft2)
    RCALL  Text_ausgeben
    RCALL  Switch_560k_Messung
    SBR    Led_Status,Led_560k_Switch
    RCALL  Led_Status_Anzeigen
    CBR    Led_Status,Led_560k_Switch
    RCALL  Zahl_ausgeben
    MOV    Zahl_l,ACC
    LDI    Zahl_h,0
    RCALL  Zahl_ausgeben
    RCALL  CRLF_ausgeben
    TST    ACC
    BREQ   Switch_560k_Sensor
    RCALL  Delay_1000

    SBR    Led_Status,Led_PT100
    RCALL  Led_Status_Anzeigen
    ldi    ZH,high(2*Botschaft3)
    ldi    ZL,low(2*Botschaft3)
    RCALL  Text_ausgeben
    RCALL  PT100_Messung
    RCALL  Zahl_ausgeben
    MOV    Zahl_l,ACC
    LDI    Zahl_h,0
    RCALL  Zahl_ausgeben
    RCALL  CRLF_ausgeben
    TST    ACC
    BREQ   PT100_Sensor
    CBR    Led_Status,Led_PT100
    RCALL  Delay_1000

    SBR    Led_Status,Led_PT1000
    RCALL  Led_Status_Anzeigen
    ldi    ZH,high(2*Botschaft4)
    ldi    ZL,low(2*Botschaft4)
    RCALL  Text_ausgeben
    RCALL  PT1000_Messung
    RCALL  Zahl_ausgeben
    MOV    Zahl_l,ACC
    LDI    Zahl_h,0
    RCALL  Zahl_ausgeben
    RCALL  CRLF_ausgeben
    TST    ACC
    BREQ   PT1000_Sensor
    CBR    Led_Status,Led_PT1000
    RCALL  Delay_1000

    RJMP   Sensor_such_Schleife
;********************************************************************

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oktoberfestbesucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hermy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.!
;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: ... (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.