電子楽器の夢をみるのか -2ページ目

電子楽器の夢をみるのか

電子楽器製作をつづる。

さて、梅雨に入りました。
昨日、今日と急に激しい雨が襲ってきました。
だいたい、出かけようとするときに降り出すんですよね、雨って。
停滞気味の低気圧がゆっくりと北上しているらしく激しい雨が長時間降っているようです。
ちなみに生まれ故郷の宮崎では1日で1か月分の雨が降ったとか。どうゆうことやねん(´・ω・`)

YMZ294の製作!に行きたいとこですが、こっちも停滞気味(´・ω・`)
現在、マイコンとMIDI機器とのやり取りをするところを調べている所です。
シリアル通信と言うものを使うらしく、ちょっと戸惑っています。

分かり次第、また書きたいと思います。つづく




tiny13でAD変換をしよう。寄り道もこれで最後。
前回のプログラムでもう一つ注目したいところ
それはここ
      while(bit_is_set(ADCSRA,ADSC));    //ADSCが1の間繰り替えす
この文、要はAD変換が終わるまで待つという意味です。この文だけで
  1週間ほど悩んでました。で、その原因ってのが

「最適化」

でした。
実は書いたプログラムはそのままマイコンに書き込まれるわけではありません。そのままだとマイコンは内容を理解できません(´・ω・`)マイコンは0と1しか(機械語)わからないからです。

そこでマイコンが分かるようにパソコンが書いたプログラムを書き換えてくれます(ここではC言語を機械語に直してます)。ちなみにこのことをコンパイルと言います。

さて、この時問題が。プログラムを書き換えるときパソコン側(実際にはコンパイラという)が「この部分は無駄だな」と思うとその部分を省いてくれます。これを最適化と言います。このおかげでファイルの大きさが小さくなったり、処理が早くなったりといいことづくしです。
しかし、こちらが必要な部分も気を利かせて(?)カットしてしまうことがあります。おせっかいなやつめ(´・ω・`)
当初、書いていたプログラムは

   while(ADCSRA=ADCSRA & 0b01000000);
でした。AD変換が終わるまで待つという文で今回の話の最初に書いた文と意味は同じです。この文を詳しく説明すると、下から6bit目(ADSC)が1だと待つというプログラムです。
0になるまで何度も確認しています。ですが、パソコン側が
「何度も確認するのは大変だな。面倒だから1回だけ確認しよっと」
と考え、内容を書き換えてしまいます。そのため思ってた通りの動きをしてくれません。文は間違ってないのに動かない。このおかげでなかなか動いてくれませんでした。
解決策として

      while(bit_is_set(ADCSRA,ADSC));    //ADSCが1の間繰り替えす
と書くこと。意味は同じ。この文だと最適化せずにちゃんと思った通りに動いてくれます。
最適化しないように文を変えたりと、パソコンに言い聞かせる必要がありますね。

という訳で問題も解決し、マイコンに書き込み、動かしました( `・ω・´ )おおっ、抵抗を変えるとLEDの光るパターンが変わる。
これをFM音源とかの設定をいじくるとこに使いたいな~。あと、マイコンに音を出させて、可変抵抗をいじくったらその音の高さが変わるようにしたらおもしろいかも。アイデアがポンポンでてくる( `・ω・´ )別で楽器とか作れそう。
とりあえずAD変換は終わりにして次からはYMZ294に戻りたいと思います。楽しい寄り道でした。
さて今度こそ回路とプログラム!
とりあえず回路はこんな感じ

tiny13にはAD変換ができるI/Oポートが4つあります。4つのうち今回はADC2(PB4)を使用します。
右にある可変抵抗で電圧の大きさを変え、その値をAD変換でデジタルにします。
読み取った値をPB0からPB3に出力します。可変抵抗をいじくったら光るパターンが変わるよ。
本当は10bit分できるけどハードの仕様上4bitだけ。とりあえずAD変換してるよ!ってわかればいいかな。

それではメインのプログラム
/*
 * AD_test.c
 * ADCの結果をPORTBに出力するだけの回路
 * Tiny13の仕様上4bit分のみ出力
 * Created: 2014/05/17
 *  Author: longtail
 */
#define    F_CPU    1000000UL            //CL(クロック)を1MHz
#include <avr/io.h>
#include <util/delay.h>                    //wait関数
void Inthard(void);

int main(void){
    Inthard();
    while(1){
      ADCSRA=ADCSRA | 0b01000000;        //ADC Start
      while(bit_is_set(ADCSRA,ADSC));    //ADSCが1の間繰り替えす
      PORTB=ADC;                            //ADCの結果をxに格納
      _delay_ms(100);
    }
}
void Inthard(void){
    DDRB=0b11101111;                    //PB4以外出力
    PORTB=0b00000000;       
    ADMUX=0b00000010;                    //ADC2(PB4)を使用
    ADCSRA=0b10000111;                    //ADEN=1 ADC許可 ADPS2~0=1 CL/128の速さでADCを行う
    _delay_ms(5);                        //ちょっと待つ
}

これまでのと比べてずいぶん短め。やってることはちょっと濃い。
注目するところは2つ。まずは初期設定。
    ADMUAX=0b00000010;                    //ADC2(PB4)を使用
    ADCSRA=0b10000111;                    //ADEN=1 ADC許可 ADPS2~0=1 CL/128の速さでADCを行う

この2つのレジスタ(値を入れる箱)がAD変換の設定をするところ。今回つかったとこだけ説明します。

ADMUAXではMUX0,1(0bit,1bit目のこと(下から2ケタ分)特殊なレジスタには各bitごとに名前がついてる)だけ見ればOK。ここでどのピンを使うのか決めます。
MUXの値がそれぞれ
MUX1,MUX0=(0,0)=ADC0(PB5のこと)
               =(0,1)=ADC1(PB2)
               =(1,0)=ADC2(PB4)
               =(1,1)=ADC3(PB3)

今回はPB4を使うのでMUX1,MUX0=(1,0)と設定します。というわけでADMUAX=0b00000010; となります。
つぎにここ ADCSRA。まずADEN(下から7bit目)ここを1にするとAD変換ができるようになります。こびとさんを起こします。次にADSC(下から6bit目)はここでは0のままでいいですが、1にするとAD変換をしてくれます。今回のプログラムだとメインプログラムのここ
      ADCSRA=ADCSRA | 0b01000000;        //ADC Start
でAD変換を開始します。ちなみにAD変換が終了すると勝手に0に戻ります。
ここの命令は
   ADCSRA=0b11000111;
でもOK。もう一つ、ADPS2~0(下から0~2bit目)でAD変換をするタイミングを決めます。こんな感じで

ADPS2~0=(0,0,0) クロック/2の速さ
ADPS2~0=(0,0,1) クロック/2の速さ
ADPS2~0=(0,1,0) クロック/4の速さ
ADPS2~0=(0,1,1) クロック/8の速さ
ADPS2~0=(1,0,0) クロック/16の速さ
ADPS2~0=(1,0,1) クロック/32の速さ
ADPS2~0=(1,1,0) クロック/64の速さ
ADPS2~0=(1,1,1) クロック/128の速さ

早ければ早いほど瞬時にAD変換を行ってくれますが、早すぎるとちゃんとAD変換が出来なくなります。こびとがオーバーヒートしちゃう(´・ω・`)。クロックと相談しましょう。確か50kから200kHzぐらいにすればよかったかな?とりあえず余裕をもってクロック/128の速さで行います。
とりあえずこれだけの値を設定すればAD変換は出来ます。マイコンごとに設定が異なるのでそこは気を付けよう!

やっとこれで注目するとこ一つ目終わり。もう一個あるけど長くなるので一旦区切ります。
実は悩まされたのはこの次のやつ。
とりあえず続く





前回に引き続き、寄り道「tiny13でAD変換をする」
今回は回路、プログラムと行きたかったけどAD変換の話。

前回、AD変換はアナログ信号をデジタルに変換すると書きましたがどうやって変換するのか
マイコンの中にある回路が入力されたアナログ信号の値をあるタイミングごとに大きさを読み取っていきます。
要はこびとが頑張ってるんです。こんな感じで

こびとが頑張って読み込んだデータをマイコン(コンピュータ)に渡して処理します。
ちなみにtiny13は10bitの分解能を持っています。分解能ってのは入力された信号をどれだけ細かくとるかって話。分解能が良いほど細かくとることができます。ちなみに10bitだと1024分割することができます。
と、まぁこんな感じ。応用すれば録音とかできそう。
次回は今度こそ回路とプログラムです。続く


YMZ294を動かす!って話がメインなのですが、
ちょっと寄り道をします。(寄り道ばっかり(´・ω・`))

今回の寄り道は最終的にはYMZ294を動かしたり、FM音源につながる内容です。
と言う訳で、AD変換に寄り道します。
AD変換とは前回YMZ294を動かす(6)でちょこっと出てきましたが
簡単に説明すると
アナログ信号をデジタル信号に変換することです。

ところでアナログの信号とはなんでしょうか?
アナログ信号は私たちの身の回りにある音だったり温度だったり光だったりと連続的な量のことです。


実をいうとアナログ信号はマイコンには扱いづらい(´・ω・`)
なぜかというとマイコンはデジタル信号を用いて動いてるからです。デジタル信号は0と1(またはONとOFF)のみしかありません。
アナログ信号をそのままマイコンに入力すると、マイコンはデジタルでしか判断できないため、
0と1の信号として扱われてしまいます。

これでは思った通りの動きができません(´・ω・`)
そのため、アナログの信号をマイコンが使いやすいデジタルの信号に変える必要があります。その方法がAD変換です。(AD変換のAはアナログ(Analog)のA、Dはデジタル(Digital)のDの意味、そのまんま)
AD変換はマイコンで行うことができます。マイコン内部にAD変換をしてくれる回路が入っており、マイコン内部の設定をしてあげればAD変換を使うことができます。わざわざAD変換の回路を作る必要が無くていいね( `・ω・´ )

今回はAD変換だけしたいのでtiny13を使ってみようと思います。mega88はお休みです。
tiny13はmega88やtiny2313と比べてピン数が少なく、大きさも小さいです。しかしtiny2313にはないAD変換を使うことができます。
小っちゃいけど結構やれるぜって奴。山椒小粒はピリリと辛い


プログラムや用途などの説明は次回にします。
つづく