[ 今度は1秒毎に音が出る物を作る! ]マーカーとして「1秒毎に音が出る」物を作ります。これを作る方法は色々あるのですが内臓のタイマーを使うとスムーズにできます。
ブザーはおなじみの圧電ブザーを使いました、音は少し小さいのですが省エネです。☆1秒間隔を作る。
☆音出し用にタイマーがもう一つあると簡単ですが、ATTiny13Aは一つしかありません。で、メインのプログラムで作ることにします。[ タイマー/カウンター0の動作 ]タイマーはプリカウンターとして1:1、1:8、1:64、1:256、1:1024を選べます。ここでは1.2Mhzが発振ですので1/1024を使います。
1.2MHz(0.833uSec)*1024*146=125mSecを使います。最後の146は8bitのカウンター(TCNT0)が利用出来るのでこれで実行しています。125mSec毎に割り込みを発生させます。この時間に別のプログラムを実行させます。
実際にはこの割り込みが8回実行されると1秒になるので、別のプログラム(割り込みプログラム)でカウントアップさせ、8回つまり1秒になったらリセットするようになっています。
これで1秒の方は出来上がりました。次は音を作る方です。音は約2KHzの音を作って「圧電ブザー」を駆動して鳴らそうという物です。こちらも、Timer0をうまく使う方法もありますがメインプログラムの方で作り、音出しをさせます。
具体的には常時音を出させるプログラムで、I/Oポート・ビット0を250uSecでON-OFFさせ約2KHzの音を作っています。
このままだと連続して音が出てうるさいので、さっきの125mSecを使って8回の内1回だけ音出しを許可して、1秒毎に「ピー・ピー…」と音が出る仕組みにしました。
プログラムの結果!
全体に短いプログラムなので、トラブルなく動きました。
初めての人は、TCNT0の設定が分かり難いと思います。これは逆に設定しないと正常に動きません。
というのもTCNT0は8bitのレジスターなのですが、オーバーフロー方式で動かしています。つまり256-146(実際の動作)=120が設定になります。「直接146ではない」のです。
120を設定し、次に146回信号が来ると256回となり、桁上げとなりここで初めて割り込み信号が発生し、別のプログラム(割り込み)が動作する仕組みになっています。
この他にタイマー割り込みの許可(TOIE)を設定し、グローバル割り込み許可のSREGの設定が必要です。つまりTCNT0・TCCR0Bで1/256を選び・TOIEとSREGの"I"bitの設定(4つ)をします。
結構ややっこしいです、でもこれって慣れるより仕方がありません![ プログラム ]1.初めピンの初期設定・DDRBなどをする。
2.I/Oポートの設定。
3.タイマー0の4つを設定する。125mSecを作る。
4.割り込みでは、125mSecを8回カウントアップしています。
5.メインループで2KHzを作る。これで音が出ることになります。実際に動かしましたらタイミングが30/28だけ遅くなりました。146*28/30で計算し直し[146 から 136(120)]に変更して時間調整をしています。
9.8MHz発振でこんなに狂うのは仕方ありません。メーカーの資料(カタログ)によると+-10%の精度になっています。調整すると2%ぐらいまで合わせられる、とありました。
タイミング的に厳しい物は、どこかで調整するか、別のICを考える方が良いのでしよう。
そういえばメーカー製のリモコンの中にはほとんどセラロックを使ってコントロールしています。内部発振は少ないと思います。売り物はそれなりに作られています。----------------------------------------------------------------------------------- /* ATTiny-13A 2013/7/22 BY M.Kikuchi Spot sound maker on every Sec Low 0x6A High 0xFB 1.2Mhz BOD=2.7V :Configuration Registers Last Mod 2013/7/23 Used Rom 148 bytes */ char cu1; //for 1Sec Counter void TC0_Interrupt() iv IVT_ADDR_TIM0_OVF // 125msec *8 = 1 Sec { // 1.2MHz 1024*146=125mSec 256-146=110 set of again TCNT0=120; //Tuning 146/(30S -> 28S)=136 cu1++; if(cu1 == 8) // cu1 = 0 to 7 (Max) cu1=0; } void main() { DDRB =~0b00111000; // 0=input ~(0=output) PORTB= 0b00111000; // Pull UP cu1=0; // TCNT0 = 110; // 256-146=110 Max ORG TCCR0B = 5; // 1/1024 T/C0 set to start TOIE0_bit = 1; // Interrupt Start SREG_I_bit = 1; // Global Interrupt Enable // while(1){ if (cu1 == 0) { PORTB0_bit=1; // Sound ON Delay_us(250); // 2Khz PORTB0_bit=0; // Sound OFF Delay_us(250); } } } ------------------------------------------------------ :1000000022C0FECFFDCF06C0FBCFFACFF9CFF8CF8D :04001000F7CFF6CF61 :10004600BFE9BDBFB0E0BEBFB7ECB7BBB8E3B8BB56 :10005600B0E0B0936000BEE6B2BFB5E0B3BFB9B7DB :10006600B260B9BFBFB7B068BFBF009160000030D3 :1000760061F4B8B3B160B8BB04E60A95F1F7B8B35A :0E008600BE7FB8BB04E60A95F1F7EFCFFFCFBF :100014000F93EF93FF93BF93BFB7BF93B8E7B2BFFC :10002400009160000F5F00936000083019F4B0E0A5 :10003400B0936000BF91BFBFBF91FF91EF910F914B :0200440018950D :00000001FF
製作 2013/8/3
[MAIN MENU へ戻る]