2013/04/24

[電子工作]Attiny13AのPCINTで外部ピン変化割り込み

,
 Attiny13Aを使ってちょっと遊んでいます。で、Attiny13Aにはピン変化(0→1、1→0とか)で割り込みを発生させる機能があります。割り込みにはINT0を使ったもの、PCINT[5..0]を使ったものの2種類が存在します。これらの違いは、使えるポートの数、割り込みに立ち上がり/立下りなどの制限をかけられるか、などなのですが、詳しい解説は以下のページを見てください。

AVR/ペリフェラル/外部割り込み - プロえく http://bit.ly/11L2QXi

 INT0を使ったものは便利なのですが、PB1しか使えず、今回既にLEDのための出力に使ってしまっているので、PCINTによる割り込みを使ってみることにしました。

 回路図は以下のような感じです。
fig.1 schematic
PB2にLED出力、PB4がスイッチ入力の単純な回路ですね。
 割り込みのためにプッシュスイッチを使ったのですが、チャタリングが発生してしまうため、防止のためにRC積分回路を入れています。時定数をどうするかは経験則だと思ったので、次のページを参考にさせて頂きました。

チャタリング防止回路のCR時定数 http://bit.ly/ZL38Nx

 基板を作ってて、最初はやっぱり動きませんでした。バグの原因は多分、

1)スルーホールだから裏側に配線あたってれば大丈夫だろうと思ってた(スイッチがGND落ちてなかった)
2)入力を見るレジスタを間違えていた(PORTBではなくPINB)
3)見るポートを間違えてた(2ではなく4)

だと思われます…今後のために置いておきます…


コードはこんな感じです。

#include <avr/io.h> 
#include <avr/interrupt.h>

//外部ピン変化の割り込み
ISR(PCINT0_vect){
   //自分でピンが立ってるかどうかチェックしなければいけない
   if(bit_is_set(PINB, PORTB4)){
      PORTB ^= (1 << PORTB2); //PB2を反転
   }  
}
 
//ピンの変化による割り込みを許可する
void initIOInterrupt(){
   //割り込みを有効にする
   GIMSK |= (1 << PCIE);

   //割り込み許可するポートを選ぶ
   PCMSK = 0b00010000; //PB4

   //全割り込みを許可
   sei();
}
 
void main(){
   //PORTBの入出力の方向を設定(PB4が入力、PB2が出力)
   DDRB |= (0 << DDB4) | (1 << DDB2);

   //PORTBの出力値を設定
   PORTB = 0b00010100;

   initIOInterrupt();

   while(true)
   {
      //TODO:: Please write your application code
   }
}

 ISR(PCINT0_vect)が、割り込んだ時に呼ばれる関数です。設定はinitIOInterrut()で設定しています。といってもやることは少なく、

1)GIMSKレジスタのPCIEにフラグ(1)を立て、PCINT割り込みを許可すること
2)PCMSKレジスタで割り込みに使うピンのところにフラグを立てること

の2つだけです。

 PCINTでは、割り込みが立ち上がりによるものなのか、立下りによるものなのかはユーザーが調べないといけません。なので、PINBを見ることで入力値を求めています。bit_is_set(A, B)は<avr/io.h>で読み込まれる?<avr/str_defs.h>でdefineされたマクロで、AのBビット目が1ならtrueになる…のかな。
 
 また、PCINT割り込みはポート変化が出力でも割り込みは発生するらしい(有志の方による日本語翻訳版データシートならp.31)。なので、関係ないポートは出力値を変えてもいいように、PCMSKを0にしておきます。

 INT0を使った割り込みは、次のBlogさんがとてもわかりやすい解説を書いてくださっているので、ぜひそちらを…
 
AVR入門(3) ピン入力と割り込み | stastaka's Blog http://bit.ly/11L86dz


 さて、AVRをちょっとは便利な道具として扱えるようになって来ました。後はADCとシリアル通信、RESETピンのI/Oポートとしての使用、が課題です…

0 コメント to “[電子工作]Attiny13AのPCINTで外部ピン変化割り込み”

コメントを投稿