本文へスキップ

アトメル社のAVRマイコンをつかった電子工作および無線を使った電子工作を紹介します。





ホーム > ソフト室 >AVRマイコンで始めるC言語の使い方 >スイッチ入力をする->外部割込を使う

AVRマイコンで始めるC言語の使い方

スイッチ入力をする。

[方法2]外部割込を使う。

前頁と同様にスイッチSW0を押している間はLED4を点灯させます。スイッチSW0を離している間はLED4を消灯させます。

1.外部割込について

外部割込にはINT0、INT1とPCINT0~PCINT23の割込があります。これらの割込について下表に示します。
INT0、INT1 PCINT0~PCINT23
割込要因 上昇端、下降端、両端
ローレベル
ピン変化
クロックとの関係 上昇端、下降端、両端 → クロックに同期 非同期
ローレベル      → 非同期
スリープモードとの関係 上昇端、下降端、両端 → アイドルまでOK アイドルを含む休止までOK
ローレベル      → アイドルを含む休止までOK
今回はスイッチPD0を使用します。
ピン変化割込PCINT16で割込を行います。
ピン変化割込のレジスタの設定方法について説明します。
  ・ピン変化割込マスクレジスタPCMSK2のPCINT16を'1(許可)'にします。
  ・次にPCIE1を'1'(許可)にします。
  ・その後に割込全体を許可します。
(1)ピン変化レジスタ PCICR
- - - - - PCIE2 PCIE1 PCIE0

PCIE2 PCINT16~PCINT23
PCIE1 PCINT8~PCINT14
PCIE0 PCINT0~PCINT7

(2)ピン変化割込マスクレジスタ PCMSK2
PCINT23 PCINT22 PCINT21 PCINT20 PCINT19 PCINT18 PCINT17 PCINT16

(3)ピン変化割込マスクレジスタ PCMSK1
- PCINT14 PCINT13 PCINT12 PCINT11 PCINT10 PCINT9 PCINT8

(4)ピン変化割込マスクレジスタ PCMSK0
PCINT7 PCINT6 PCINT5 PCINT4 PCINT3 PCINT2 PCINT1 PCINT0

2.フローチャート

(1)メイン処理

初期設定を行います。
  ・ポートの設定をします。
  ・SW0がピン変化割込の設定をします。
全体の割込を許可します。
その後メインプログラムは何もせずに無限ループを回ります。

(2)ピン変化割込処理

ピン変化割込が入るとメインから割込処理に移行します。
チャタリング時間10ms待ちます。
スイッチの状態をプログラムに読み込みます。
スイッチがONであればLED4を点灯し、OFFであればLED4を消灯します。
                                割込処理を終了し、メインに移行します。

3.プログラム

/*
 * avr007_PortInterrupt.c
 * スイッチ入力をする。
 * 外部割込を使って行います。
 *スイッチONでLED点灯
 *スイッチOFFでLED消灯
 */ 

#define    F_CPU    1000000UL // 1MHz

#include <util/delay.h>       // _delay_msを使用するためにインクルードします。
#include <avr/io.h>
#include <avr/interrupt.h>    // 割込を行うためにインクルードします。

void InitHard( void);         // ポートの初期化及び割込設定

int main(void)
{
        InitHard();             // ポートの初期化及び割込設定
        sei();                  // 全体の割込を許可
    
        while(1)
    {
        //TODO:: Please write your application code 
    }
}

void InitHard( void) // ポートの初期化
{
        // ポートB初期設定
        DDRB = 0xff;            // PB7~PB0を出力に設定します。
        PORTB = 0;              // PB7~PB0に'L'を出力します。
        // ポートC初期設定
        DDRC = 0x3f;            // PC7,PC6は初期(入力)、PC5~PC0を出力に設定します。
        PORTC = 0;              // PC7~PC0に'L'を出力します。
        // ポートD初期設定
        DDRD = 0xf0;            // PD7~PD4は出力、PD3~PD0は入力に設定します。
        PORTD = 0;              // PD7~PD0に'L'を出力します。
        
        // PD0=PCINT16 ピン変化割込設定
        PCMSK2 |= 1 << PCINT16;         // ピン変化マスクレジスタにPCINT16を許可
        PCICR |= 1 << PCIE2;            // ピン変化レジスタにPCINT16~PCINT23を許可
}

SIGNAL( PCINT2_vect)    // ピン変化割込処理
{
        _delay_ms(10);  // チャタリング10ms待ち
        
        if ( PIND & (1 << PIND0)) // スイッチSW0がOFFならば
        {
                PORTD &= ~( 1 << PORTD4);       // LED4を消灯
        }
        else  // スイッチSW0がON
        {
                PORTD |= 1 << PORTD4;   // LED4を点灯
        }
}
これでスイッチ入力は終了です。このプログラムではメイン処理をwhileループでまわしています。割込が入らないときはスリープにすることでマイコンの消費電流を抑止することができます。
みなさんでプログラムを改造してみてください。
前ページ次ページ