Godtycklig vågform generator, för ~ 20$ (5 / 6 steg)
Steg 5: Programmering AWG
Här är en guide till programmering enheten. Jag börjar med programmet används för att generera 1.7 Mhz sinusvåg:START:
.include "m8515def.inc"; Detta är en definitionsfil, en mycket användbar sak att använda. Om du behöver en kopia, google arkivnamnen
REGISTERS0:
LDI r16, 0x00
LDI r17, 0x25
LDI r18, 0x7F
LDI r19, 0xD9; Load registrerar först, så senare din kod kan producera ~ 1 produktion per klockcykel
LDI r20, 0xFF; Dessa värden bestämdes av 127*sin(x)(pi/4), för positiva heltalsvärden för x.
ut DDRB, r20
2Mhz sine0:
ut PORTB, r18
ut PORTB, r19
ut PORTB, r20
ut PORTB, r19
ut PORTB, r18
ut PORTB, r17
ut PORTB, r16
ut PORTB, r17, en period av sinus våg @ 2Mhz om du använder en 16Mhz klockfrekvens
rjmp 2Mhz sine0
Här nedan följer exempel på 1Mhz sinustoner, skapas två olika sätt.
1Mhz sine0:
ut PORTB, r18
NOP
ut PORTB, r19
NOP
ut PORTB, r20
NOP
ut PORTB, r19
NOP
ut PORTB, r18
NOP
ut PORTB, r17, en period av sinus våg @ 1Mhz om du använder en 16Mhz klockfrekvens
NOP
ut PORTB, r16; Detta är den lat väg.
NOP
ut PORTB, r17; Nästa exempel visar på bättre sätt.
rjmp 1Mhz sine0
REGISTERS1:
LDI r16, 0x7F
LDI r17, 0xAB
LDI r18, 0xD1
LDI r19, 0xF6
LDI r20, 0xFE
LDI r21, 0x53; Märke vi har laddat 9 register till minne! Notera hur många register du har, och
LDI r22, 0x2D; gör god användning av dem. Där 127*sin(x)(pi/n), n kan vara valfritt antal register
LDI r23, 0x08, där antalet register plus 1 delat med 2... om jag har fel!
LDI r24, 0x00
1Mhz sine1:
ut PORTB, r16
ut PORTB, r17
ut PORTB, r18
ut PORTB, r19
ut PORTB, r20
ut PORTB, r19
ut PORTB, r18
ut PORTB, r17
ut PORTB, r16
ut PORTB, r21
ut PORTB, r22
ut PORTB, r23
ut PORTB, r24
ut PORTB, r23
ut PORTB, r22
ut PORTB, r21
rjmp 1Mhz sine1
Ovanstående är ett fint exempel på avvägningen mellan upplösning och frekvens. Genom att halvera upplösningen, kan du dubbla frekvensen. En lyhörd läsare
har märkt att både vågformer använder 0x7F (127) som en nollpunkt oavsett ordning registren är laddade... Du kan bestämma att en annan
nollpunkten är mer användbart för vissa vågformer... men för symmetriska sådana som du är mest sannolikt att använda, 0x7F är optimal.
Nu flyttar vi till ett mer komplicerat ämne... Hur skapar vi en 1.5Mhz vågform? Tänk:
sine(x)(PI/6)
som skulle vara korrekta upplösningen att använda... men, eftersom resolutionen delar jämnt in 2pi, men inte in i p/2... vår vågform ser konstigt,
eftersom ingen är produktionen motsvarar ett minimum eller maximum av funktionen, det vill säga något nära 0x00 eller 0xFF! För hög
frekvenser, vågformen kan vara ungefär rätt ändå, på grund av den naturliga kapacitans och induktans i någon krets. Detta motstår någon förändring
i ström eller spänning, så vid högre frekvenser, om du sparar 0x00 tio gånger, sedan 0xFF två gånger... den andra 0xFF ger dig ett något högre värde
än den första. Prova och se, det kanske eller kanske inte fungerar beroende på variabler som är alltför komplex för att diskutera här.
Poängen är att det är svårt eller omöjligt att generera frekvenser som inte är binär fraktioner av klockfrekvens... Vid mycket höga
frekvenser du kanske att "fuska" med hjälp av parasitiska kapacitans och induktans... och säkert vid lägre frekvenser frågan blir irrelevant
som vi ser i nästa exempel... men visst finns det vissa frekvenser som inte kan genereras.
En smart ingenjör (dvs: inte jag) kommer att installera ett uttag för att hålla den kristalloscillator används i denna enhet... så sätt han/hon kan trivialt ändra den
grundläggande frekvensen av enheten och få i huvudsak någon frekvens de vill inom specifikationerna för mikrokontroller
(Jag har sett billiga... 2$... atmels som fungerar upp till 20 Mhz klockhastigheter).
Nu, här är några kod för en avgjort lägre frekvens vågform. Det är i grunden från den webbsida som jag listat som referens:
http://www.AVR-ASM-tutorial.net/avr_en/AVR_DAC.html
Vågformen är en sawtooth våg. Gå kolla in hemsidan som är mycket användbar och koden det är riktigt bra för låg-medium frekvens vågformer.
.include "m8515def.inc"
START:
LDI r18, 0xFF
ut DDRD, r18
SAWTOOTH:
ut PORTD, r18
Inc r18
rjmp sawtooth
Detta genererar en vågform av ca 2,5 kilohertz. Du kan öka/minska frekvensen genom att lägga till pauser (nop) eller timers, eller du kan öka frekvensen
genom att minska upplösningen... istället för att inc (increment) enkel Lägg till ett nummer r18. Om du lägger till 2, skulle frekvensen fördubblas. Om du lägger till 3 och en paus
(nop), frekvensen ökar med 1,5 gånger.
Att göra en triangel våg, lägga till en KPI uttalande att testa om r18 motsvarar 0xFF, och i så fall filial till en liknande funktion som minskar eller tas bort från r18. Att funktionen måste ju testa om r18 = 0x00, och om så förgrena sig tillbaka till den första funktionen.
Jag slutar denna handledning med några ledtrådar om hur skickligt använda enheten:
-Använd rätt timer funktioner korrekt skapa lågfrekventa vågrörelser. Det är svårare än du tror att hålla koll på klockcykler av program i ditt huvud.
-Om timer-funktionerna skrämma dig (de skrämmer mig), räkna klockcykler i huvudet, och sedan testa den på din räckvidd så att det stämmer.
-En decimal till hex converter är en mycket användbar sak när du bestämmer vilka värden för register bör.
-Inte ansluta enheten till en antenn och använda den för trådlös kommunikation om du inte har en licens och vet vad du gör.
-Du kan förmodligen programmera upp till en 4 Mhz fyrkantsvåg med den här enheten... använda den som en variabel klocka källa, eller att injicera seriell kommunikation i en krets.
-8 av dessa tillsammans med en gemensam klocka skulle göra en riktigt cool programmerbara parallella källa.
-Generera neuron handlingspänningar med det, och utan tvekan spara din biologi lab en massa pengar.
-Göra ett piano med den.
-Enheten lämnar många ingångar på atmega oanvända. Om du vill att enheten ska vara bekväm men har begränsade funktioner, du kunde bygga ett
gränssnitt för det och en smart program så att du kan generera en rad vågformer och frekvenser utan omprogrammering.
-Kom ihåg att rjmp tar klockcykler och skapar en artefakt! Komma runt detta genom att inkludera många perioder i ditt program före looping. Använda bra
av alla det minnet på atmegas!
Föråldrade (Legion Labs är en ny, ideell, no-grader-krävs forskningsinsatser som för närvarande ligger i Montreal. Vi är inte knutna till några andra organisationer.
Har en medlem, sedan jag först helt nyligen ansåg utvidgning av denna operation.)
Aktuell: Legion Labs är medlem i en montreal-baserad ideell forskning/engineering insats med ett antal andra människor, som hyr ut en industriell workshop som en plats att mixtra.