avr atTINY13a 2:自作


[avr IC]

[ 今度は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 へ戻る]

inserted by FC2 system