" type="text/css" id="hpbsmtparts">
本文へスキップ

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





ホーム >準備室 >AVRマイコンTips集1

AVRマイコンTips集1

シフト演算子

ビット演算子とはを直接操作する演算子をいいます。”<<” は左シフト、”>>” は右シフトです。これらの演算子を、シフト演算子といいます。
算術演算子を使って 2 倍したり、 1 / 2 倍するのに比較すると、はるかに高速です。
ポートレジスタ等の設定に使用します。
[例]ポートBの1と2を出力に設定する場合
DDRB = (1 << DDB1)|(1 << DDB2);
DDB1=1、DDB2=2です。(Atmega328を使用する場合はヘッダファイル「iom328p.h」に記載されています。)
1 << DDB1の意味は1を左に1ビットシフトする意味ですので値は2(0b00000010)です。
1 << DDB2の意味は1を左に2ビットシフトする意味ですので値は4(0b00000100)です。

ビットセット _BV

_BV(1)は1ビット目をセットします。1 << 1と同じ意味です。
使い方
 ポートBの1ビット目に’1’を出力 PORTB |= _BV(1) ;
 ポートBの1ビット目に’0’を出力  PORTB &= ~_BV(1);

ビットセット、ビットクリア:マクロを定義

以下をプログラムの最初の方で定義します。
#define    cbi( addr, bit)       addr &= ~(1 << bit)    // addrのbit目を'0'にする。
#define    sbi( addr, bit)       addr |= (1 << bit)       // addrのbit目を'1'にする。

使い方
ポートBの1ビット目に’1’を出力 sbi( PORTB, 1);
ポートBの1ビット目に’0’を出力 cbi( PORTB, 0);

ビットフィールド

構造体を使用すると、変数のデータ領域をビット単位で割り当てることができます。その構造体のメンバにビット単位で変数を定義する機能をビットフィールドと いいます。
ビットフィールドに共用体を定義すると、ビットフィールドの各値を一度にクリアすることができます。

[例]
union switch_states // スイッチ状態フラグ
{
    uint8_t BYTE;
    struct
    {
         uint8_t mode          :1; // 時計変更モード
         uint8_t mode_keep :1; // 時計変更モード確定
         uint8_t red             :1; // 赤スイッチON
         uint8_t red_keep     :1; // 赤スイッチON->OFF
         uint8_t yellow          :1; // 黄スイッチON
         uint8_t yellow_keep :1; // 黄スイッチON->OFF
         uint8_t green           :1; // 緑スイッチON
         uint8_t green_keep   :1; // 緑スイッチON->OFF
     } BIT;
};

union switch_states uSwitchState;

ビットフィールドをセット    → uSwitchState.BIT.mode = 1;
ピットフィールド全体をクリア→ uSwitchState.BYTE = 0;

_delay_ms

プログラムの待ち時間するのに使用します。
例えばスイッチのチャタリング時間10ms待つ等に使用します。
[使用法]
最初に#defineで F_CPU(クロックを定義しておきます。)
次に「util/delay.h」をインクルードしておきます。delay.h内でF_CPUの値を使用するのでdelay.hよりも先に定義しておきます。シミュレータで確認したところ最適化無しだと時間が待ち時間が少しずれます。(AVR Studio 5で確認しました。)

サンプルプログラム
#define    F_CPU    1000000UL      // 1MHzの場合
#include  <util/delay.h>               // インクルードします。

main()
{
       //  プログラム
       // ・・・・・・・
       //
       _delay_ms(10); // 10ミリ秒
       _delay_ms(100);      // 100ミリ秒
       _delay_ms(1000);  //  1秒/
       //  プログラム
       // ・・・・・・・
       //
}

割込関数SIGNAL(割込ベクタアドレス)

割込処理を記述する関数です。
SIGNALまたは、ISRを使用します。
割込ベクタアドレスは例えばATmega328Pは「iom328.h」内の「Interrupt Vectors」に記載されています。
割り込み処理を行う場合は、使用する割込を許可しておきsei()で全体の割込を許可します。

[使用法]
タイマ1のオーバーフロー割込発生
オーバーフローが発生するとOV_FLGに1を加算する。(OV_Flgはグローバルで変数宣言されているとします。)

SIGNAL(TIMER1_OVF_vect)
{
      ++OV_FLG;
}

ATmega328Pの割込ベクタ一覧(iom328P.hより抜粋)
 #define INT0_vect _VECTOR(1) /* External Interrupt Request 0 */
#define INT1_vect _VECTOR(2) /* External Interrupt Request 1 */
#define PCINT0_vect _VECTOR(3) /* Pin Change Interrupt Request 0 */
#define PCINT1_vect _VECTOR(4) /* Pin Change Interrupt Request 0 */
#define PCINT2_vect _VECTOR(5) /* Pin Change Interrupt Request 1 */
#define WDT_vect _VECTOR(6) /* Watchdog Time-out Interrupt */
#define TIMER2_COMPA_vect _VECTOR(7) /* Timer/Counter2 Compare Match A */
#define TIMER2_COMPB_vect _VECTOR(8) /* Timer/Counter2 Compare Match A */
#define TIMER2_OVF_vect _VECTOR(9) /* Timer/Counter2 Overflow */
#define TIMER1_CAPT_vect _VECTOR(10) /* Timer/Counter1 Capture Event */
#define TIMER1_COMPA_vect _VECTOR(11) /* Timer/Counter1 Compare Match A */
#define TIMER1_COMPB_vect _VECTOR(12) /* Timer/Counter1 Compare Match B */
#define TIMER1_OVF_vect _VECTOR(13) /* Timer/Counter1 Overflow */
#define TIMER0_COMPA_vect _VECTOR(14) /* TimerCounter0 Compare Match A */
#define TIMER0_COMPB_vect _VECTOR(15) /* TimerCounter0 Compare Match B */
#define TIMER0_OVF_vect _VECTOR(16) /* Timer/Couner0 Overflow */
#define SPI_STC_vect _VECTOR(17) /* SPI Serial Transfer Complete */
#define USART_RX_vect _VECTOR(18) /* USART Rx Complete */
#define USART_UDRE_vect _VECTOR(19) /* USART, Data Register Empty */
#define USART_TX_vect _VECTOR(20) /* USART Tx Complete */
#define ADC_vect _VECTOR(21) /* ADC Conversion Complete */
#define EE_READY_vect _VECTOR(22) /* EEPROM Ready */
#define ANALOG_COMP_vect _VECTOR(23) /* Analog Comparator */
#define TWI_vect _VECTOR(24) /* Two-wire Serial Interface */
#define SPM_READY_vect _VECTOR(25) /* Store Program Memory Read */