Generator för rosa brus - miniprojekt
speakman: Det ska bli batteridrivet så kan man spara lite ström med ett kortare program är det bara bra.
grym: Det är bara kul ifall konstruktionen blir använd, så jag kan skriva lite PIC-kod oavsett vad jag bygger själv.
Pehr: Japp!
Det kollade jag på först och det hade varit trevligt. Men jag vill kunna driva kretsen på 2 - 3 volt. Vid de spänningarna är det väl bara spänningsreferenser eller liknande som kan komma ifråga som bruskällor (eller?) och då är bruset så svagt (60 µVrms för LM385-1.2) att man måste skärma noga osv.
grym: Det är bara kul ifall konstruktionen blir använd, så jag kan skriva lite PIC-kod oavsett vad jag bygger själv.
Pehr: Japp!

- HUGGBÄVERN
- Tidigare soundbrigade
- Inlägg: 34907
- Blev medlem: 23 augusti 2006, 22:44:11
- Ort: Lilla Paris
- Kontakt:
För 185 år sedan byggde jag en enkel skärt-brusgenerator bestående av en brusande PN-övergång i en trissa (2N5210 eller nåt sånt) och en trissa med massa förstärkning till en keramisk öronsnäcka.
Beskjrivning i Popular Electronics eller Radio Electronics på 70-talet.
Den där grunkan på MusicFromOuterSpace funkar nog fint. Om man väljer OPAMP:ar som skulle fungera på +/-4V kan man ju modifiera och köra ett 9V-batteri med "fusknolla".
Beskjrivning i Popular Electronics eller Radio Electronics på 70-talet.
Den där grunkan på MusicFromOuterSpace funkar nog fint. Om man väljer OPAMP:ar som skulle fungera på +/-4V kan man ju modifiera och köra ett 9V-batteri med "fusknolla".
Sådär! Det tog ett tag, men nu är brusgeneratorn byggd och testad och den verkar fungera fint. Den låter "FFFFFFFFFFFFF" i alla fall. 
Speakman: Jag håller med dig, man ska inte optimera i onödan för det tar bara tid. I det här fallet så drar ju dessutom högtalaren 10 ggr mer ström än processorn gör. Så, tja, helt nödvändigt att skriva assemblerkod var det väl inte. *host*. Men det är ju kul att pyssla lite också.
Jag byggde med en ATtiny13 (finns hos Lawicel för 22kr+moms) men knåpade även ihop lite PIC-kod också. Den är bara simulerad men den borde fungera i verkligheten också.
Om jag räknat klockcyklerna rätt så är den effektiva samplingsfrekvensen ca 14.7kHz på en 8MHz PIC12F519 och 99kHz (!) på en 9.6MHz ATtiny13. Båda har alltså inbyggda oscillatorer med de frekvenserna.
Nu har jag minskat precisionen i if-satsen till 8 bitar och det försämrar "färgen" litegrann. I det här fallet (tinnitus-maskerare) så kvittar det ju iofs. Vill man ha högre precision så är det bara att titta i C-koden i ett tidigare inlägg.
Schemat är så enkelt det kan bli, så jag hoppas att lite ASCII-konst räcker:
Teoretisk maxeffekt (DC) in i högtalaren är 140mW, vilket är mer än den klarar utan att gå sönder, så jag drog aldrig upp volymen över 50%. Nu är ju AC-effekten nånting annat så om det är ett faktiskt problem vet jag inte riktigt. Vill man vara på den säkra sidan kan man ju alltid välja en större högtalare eller sätta ett motstånd i serie med P1...

Speakman: Jag håller med dig, man ska inte optimera i onödan för det tar bara tid. I det här fallet så drar ju dessutom högtalaren 10 ggr mer ström än processorn gör. Så, tja, helt nödvändigt att skriva assemblerkod var det väl inte. *host*. Men det är ju kul att pyssla lite också.
Jag byggde med en ATtiny13 (finns hos Lawicel för 22kr+moms) men knåpade även ihop lite PIC-kod också. Den är bara simulerad men den borde fungera i verkligheten också.
Om jag räknat klockcyklerna rätt så är den effektiva samplingsfrekvensen ca 14.7kHz på en 8MHz PIC12F519 och 99kHz (!) på en 9.6MHz ATtiny13. Båda har alltså inbyggda oscillatorer med de frekvenserna.
Nu har jag minskat precisionen i if-satsen till 8 bitar och det försämrar "färgen" litegrann. I det här fallet (tinnitus-maskerare) så kvittar det ju iofs. Vill man ha högre precision så är det bara att titta i C-koden i ett tidigare inlägg.
Schemat är så enkelt det kan bli, så jag hoppas att lite ASCII-konst räcker:
Kod: Markera allt
IC1
-------
| R5
RESET |----XXXX--|VCC
| R4 ________
PB4 |----XXXX--o--- | _ |
| R3 | | | | \ |
PB3 |----XXXX--o | -|- \ | C1
| R2 | X P1 | |--o---||--- /|
PB2 |----XXXX--o X<-----|+ / + | / |
| R1 | X |_/ || | S1
PB1 |----XXXX--o _|_ || |
| R0 | GND IC2 | \ |
PB0 |----XXXX-- _|_ \|
| GND
VCC |---|VCC
|
-------
R0 = 46.4k R5 = 22k IC1 = ATtiny13
R1 = 51.1k P1 = 10k, lin, trimpot IC2 = TS921 / TS922
R2 = 60.4k C1 = 220 uF
R3 = 53.6k S1 = 50mW, 16 ohm VCC = 3V
R4 = 42.2k
Avkoppling: 10uF + 2 st 100nF, en vid varje IC.
Senast redigerad av andr3as 27 november 2007, 17:43:08, redigerad totalt 1 gång.
Och här kommer koden till AVR ...
Kod: Markera allt
#include <tn13def.inc>
rjmp Reset
.def LFSR0 =r2
.def LFSR1 =r3
.def LFSR2 =r4
.def LFSR3 =r5
.def TAPS1 =r6
.def TAPS2 =r7
.def RND0 =r22
.def RND1 =r23
.def TMP1 =r24
.def U = r25
;UPDATE_RAND - calculate a new bit in the pseudo-random number generator.
;
;Parameters: @0 = destination register (8-bit).
; The new bit will be shifted in from the right.
;Requires: TAPS1 = 0xd0, TAPS2 = 1
;Modifies: SREG, LFSR0, LFSR1, LFSR2, LFSR3, @0
;Cycles: 9
.macro UPDATE_RAND
lsr LFSR3 ; Approximately equivalent C code:
ror LFSR2 ;
ror LFSR1 ; rnd = (rnd << 1) | (lfsr & 1);
ror LFSR0 ; lfsr = (lfsr >> 1)
brcc skip1 ; ^ (-(signed int)(lfsr & 1) & 0xd0000001u);
eor LFSR3, TAPS1
skip1:
brcc skip2
eor LFSR0, TAPS2
skip2:
rol @0
.endmacro
Reset:
rjmp Main
reti ;INT0
reti ;PCINT0
reti ;TIM0_OVF
reti ;EE_RDY
reti ;ANA_COMP
reti ;TIM0_COMPA
reti ;TIM0_COMPB
reti ;WDT
reti ;ADC
Main:
; Initialize the MCU
; Setup clock prescaler (assumes 9.6 MHz internal RC osc @ >= 3V supply)
ldi r16, 1 << CLKPCE ; Enable prescaler change
out CLKPR, r16
ldi r16, 0 ; Set prescaler = 1
out CLKPR, r16
; Setup stack.
ldi r16, low(RAMEND) ; Set up the stack
out SPL, r16
ldi r16, 0x1f ; Initialize PORTB0-4 = outputs
out DDRB, r16
; Initialize the PRNG
clr LFSR3
clr LFSR2
clr LFSR1
ldi r16,1
mov LFSR0,r16
ldi r16, 0xd0
mov TAPS1, r16
ldi r16, 1
mov TAPS2, r16
clr RND0
clr RND1
clr U
MainLoop:
; <-- 0 cycles
out PORTB, U ; Update output
; Run PRNG
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND r16
bst r16, 0 ; Store bit in T flag
; <-- +83 cycles
; Select random bit in U to update
cpi RND0, 1 ; subi RND0, 1
brlt Update_bit0
cpi RND0, 4 ; subi RND0, 3
brlt Update_bit1
cpi RND0, 16 ; subi RND0, 11
brlt Update_bit2
cpi RND0, 60 ; subi RND0, 39
brlt Update_bit3
cpi RND0, 234 ; subi RND0, 153
brlt Update_bit4
nop
nop
rjmp MainLoop ; <-- No bit updated: +14 cycles
; Update bit in U with a random bit.
Update_bit0:
bld U, 0
nop
nop
nop
nop
nop
nop
nop
nop
rjmp MainLoop ; <-- Bit 0 updated: +14 cycles
Update_bit1:
bld U, 1
nop
nop
nop
nop
nop
nop
rjmp MainLoop ; <-- Bit 1 updated: +14 cycles
Update_bit2:
bld U, 2
nop
nop
nop
nop
rjmp MainLoop ; <-- Bit 2 updated: +14 cycles
Update_bit3:
bld U, 3
nop
nop
rjmp MainLoop ; <-- Bit 3 updated: +14 cycles
Update_bit4:
bld U, 4
rjmp MainLoop ; <-- Bit 4 updated: +14 cycles
; <-- = 83 + 14 = 97 cycles
Och PIC-koden:
Kod: Markera allt
#include p12f519.inc
LFSR0 equ h'10'
LFSR1 equ h'11'
LFSR2 equ h'12'
LFSR3 equ h'13'
RND0 equ h'14'
U equ h'15'
TMP equ h'16'
C1 equ h'17'
C2 equ h'18'
C3 equ h'19'
C4 equ h'1a'
C5 equ h'1b'
UPDATE_RAND macro new_rnd
bcf STATUS, C
rrf LFSR3, 1
rrf LFSR2, 1
rrf LFSR1, 1
rrf LFSR0, 1
movlw h'd0'
btfsc STATUS, C
xorwf LFSR3, 1
movlw h'01'
btfsc STATUS, C
xorwf LFSR0, 1
rlf new_rnd, 1
endm
org 0
Main:
option h'0ffa' ; Watchdog disabled, 8 MHz INTOSC.
movwf OSCCAL
clrw
tris PORTB
clrf U
clrf TMP
clrf LFSR3
clrf LFSR2
clrf LFSR1
movlw 1
movwf LFSR0
movlw -d'1'
movwf C1
movlw -d'3'
movwf C2
movlw -d'11'
movwf C3
movlw -d'39'
movwf C4
movlw -d'153'
movwf C5
MainLoop:
movf TMP,0
movwf PORTB
UpdateComplete: ; Label used for logging in the simulator
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND RND0
UPDATE_RAND TMP
; <-- +2+9*12 = +110 cycles
movf RND0, 0
addwf C1, 0
btfss STATUS, C
goto Update_bit0
addwf C2, 0
btfss STATUS, C
goto Update_bit1
addwf C3, 0
btfss STATUS, C
goto Update_bit2
addwf C4, 0
btfss STATUS, C
goto Update_bit3
addwf C5, 0
btfss STATUS, C
goto Update_bit4
nop
nop
nop
nop
goto MainLoop ; <-- No bit updated: + 26 cycles
Update_bit0:
bcf U, 0
btfsc TMP, 0
bsf U, 0
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
goto MainLoop ; <-- Bit 0 updated: +26 cycles
Update_bit1:
bcf U, 1
btfsc TMP, 0
bsf U, 1
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
goto MainLoop ; <-- Bit 1 updated: +26 cycles
Update_bit2:
bcf U, 2
btfsc TMP, 0
bsf U, 2
nop
nop
nop
nop
nop
nop
nop
nop
goto MainLoop ; <-- Bit 2 updated: +26 cycles
Update_bit3:
bcf U, 3
btfsc TMP, 0
bsf U, 3
nop
nop
nop
nop
goto MainLoop ; <-- Bit 3 updated: +26 cycles
Update_bit4:
bcf U, 4
btfsc TMP, 0
bsf U, 4
goto MainLoop ; <-- Bit 4 updated: +26 cycles
end