Generator för rosa brus - miniprojekt

Berätta om dina pågående projekt.
Användarvisningsbild
grym
EF Sponsor
Inlägg: 17576
Blev medlem: 16 november 2003, 12:22:57
Ort: i det mörka småland

Inlägg av grym »

ser kul ut, är själv medlem av tinitusklubben, något jag bittert ångrar idag

väljer du pic så skulle jag gärna prova den med
Användarvisningsbild
Pehr
Inlägg: 341
Blev medlem: 11 januari 2006, 18:53:16
Ort: Norrköping

Inlägg av Pehr »

hey! eller varför inte analogt :wink: 8)
andr3as
Inlägg: 29
Blev medlem: 30 januari 2006, 13:55:44
Ort: Linköping

Inlägg av andr3as »

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.
Användarvisningsbild
Pehr
Inlägg: 341
Blev medlem: 11 januari 2006, 18:53:16
Ort: Norrköping

Inlägg av Pehr »

Ja, det är klart, den analoga kräver ju +/- 9V minst :?
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Jag betvivlar att programmet blir mätbart strömsnålare om du gör det själv än att låta kompilatorn optimera på högsta nivån.
Det finns säkert många andra saker man kan spara ström på som ger betydligt bättre utdelning. Sänka klockfrekvensen till ett minimum är ett.
Användarvisningsbild
HUGGBÄVERN
Tidigare soundbrigade
Inlägg: 34905
Blev medlem: 23 augusti 2006, 22:44:11
Ort: Lilla Paris
Kontakt:

Inlägg av HUGGBÄVERN »

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".
andr3as
Inlägg: 29
Blev medlem: 30 januari 2006, 13:55:44
Ort: Linköping

Inlägg av andr3as »

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:

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.
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...
Senast redigerad av andr3as 27 november 2007, 17:43:08, redigerad totalt 1 gång.
andr3as
Inlägg: 29
Blev medlem: 30 januari 2006, 13:55:44
Ort: Linköping

Inlägg av andr3as »

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
andr3as
Inlägg: 29
Blev medlem: 30 januari 2006, 13:55:44
Ort: Linköping

Inlägg av andr3as »

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
Skriv svar