マイコンを使ったノイズジェネレータを作ってみる。
ノイズというより疑似乱数が正しい(´・ω・ ` )
今回は線形帰還シフトレジスタを使って製作。
プログラムは下記の通り。数年前に書いたものなので、
もうちょっとスマートに書き直せるとこはあったりする。
(変数yとそれを使うswitch文を消せば、ADコンバータ処理時間を短くできそう)
このプログラムのキモはここ、
temp = (x & 0x0001)^((x & 0x0004) >> 2)^((x & 0x0008) >> 3) ^((x & 0x0020) >> 5);
ここでフィボナッチLFSRの処理を用いていて疑似乱数を生成している。
参考にしたwiki↓
生成した疑似乱数のうち適当なビットをマイコンから出力してやればOK。
また、ADコンバーターから読み取った値を使って疑似乱数を計算する時間を変えている。
計算時間を変えることで周波数特性が変わりノイズが高く・低く聞こえるようになるためだと思う(´・ω・ ` )
ちなみに時間が早いとホワイトノイズのように聞こえ、遅いとピンクノイズのよう聞こえる。
/*NoiseGene.c
*プログラム上で乱数を発生させ、PB0に出力する。
* 乱数の生成はシフトレジスタを使う。
* Author:longtail */
#define F_CPU 1000000UL // 1MHz
#include <util/delay.h> //delay関数を使用する
#include <avr/io.h>
#include <avr/interrupt.h> //割り込み
#define cbi(addr,bit) addr&=~_BV(bit)
#define sbi(addr,bit) addr|=_BV(bit)
//変数の定義
unsigned short int temp=0,x=0xace2,y=0;
//関数の設定
void InitialHard(void);
int main(void) { //メインプログラム
InitialHard(); //ハードの初期化
sei();
while(1){
ADCSRA=ADCSRA | 0b01000000; //ADC Start
while(bit_is_set(ADCSRA,ADSC)); //ADSCが1の間繰り替えす
y=ADC/256;
switch(y){
case 0:
TCCR0B=0b00000101;
break;
case 1:
TCCR0B=0b00000100;
break;
case 2:
TCCR0B=0b00000011;
break;
case 3:
default:
TCCR0B=0b00000010;
break;
}
}
}
void InitialHard(void){
//ポートBの設定
DDRB=0b11110111; // PB3以外を出力に設定します。PB1はSW
PORTB=0;
//タイマカウンタの設定
TIMSK0=0b00000110;
TCCR0A=0b10000010;
TCCR0B=0b00000010;
OCR0A=10;
//A/Dコンバータの設定
ADMUX=0b00000011;
ADCSRA=0b10000100;
//ピン割り込み設定
//EICRA=0b00000010;
//EIMSK=0b00000001;
}
ISR(TIM0_COMPA_vect){
temp = (x & 0x0001)^((x & 0x0004) >> 2)^((x & 0x0008) >> 3) ^((x & 0x0020) >> 5);
x=(x>>1)|(temp<<15);
//PORTB=x;
if (x>>15&&1){
sbi(PORTB,1);
}else{
cbi(PORTB,1);
}
// PORTB=~PORTB;
}