AVR - Bluetooth

 Arduino 互換基板に AVR Studio 5 によりビルドしたプログラムを書き込み
動作させます。
 Arduino で割込みを追加するにはどうすればよいか(自分で割込みベクターの設定、
割込み処理の追加等)わからず、それならば GCC を使えば全部追加できると...
AVR Studio 5 を使ってみました。当然、全部自己責任です。

 作るソフトは Arduino で作成したものと同じです。但し、Bluetooth モジュールとの
通信速度は開始直後に変更しています。



 ハードウエア

 Arduino互換ボードにBluetooth モジュールを接続します。

Bluetooth モジュールは エイディシーテクノロジー株式会社( 無線化.com ) が販売している ZEAL-S01 を使用しました。
この製品は国内電波法認証を取得しているので気兼ねなく電波を出せます。
また Class 1 対応なので通信距離が少し離れても通信が期待できます。


( 3.3V で 16MHz クロック動作は少し規格から外れますので動作の保証はありません。)




拡張基板の回路図


 ソフトウエア

 ソフトウエアは AVR Studio 5 を使用します。デバッグは JTAGICE3 を利用しました。

ソフトウエアはメインの処理、初期設定、割込み処理に大別します。

1.初期設定はCPU内のレジスター設定、Bluetoothモジュールの初期設定のみです。
2.割込み処理はタイマー割込み、USARTの送受信割込みのみです。
3.メインはBluetoothよりのデータを受信してLEDをON/OFFさせます。

メイン部
 初期設定を行った後、Bluetooth よりのデータ待ちとなります。
Bluetooth より接続が無い場合はタイマーにより LED を点滅し、
接続された場合は LED を点灯状態にします。

int main(void)
{
    int iRDataNo ;
    unsigned char bPortB ;

    cli();                  // 割込みを禁止する。

    Initialize() ;          // 周辺装置を初期化する。(Timer のスタート)

    Usart_0_Initialize(BPS_9600) ;  // USART 設定

    sei();                  // 割込みを許可する。

    ZealSetup() ;           // ZEAL (USBモジュール) の初期設定を行う。

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

        iRDataNo = RecvData() ;
        if ( iRDataNo == 1 )        // 受信データが '1' であれば LED を ON する。
        {
            bPortB  = PORTB ;
            bPortB |= LED_12 ;
            PORTB   = bPortB ;
            SendCommand( LED_ON ) ;
        }
        else if ( iRDataNo == 0 )   // 受信データが '0' であれば LED を OFF する。
        {
            bPortB  = PORTB ;
            bPortB &= ~LED_12 ;
            PORTB   = bPortB ;
            SendCommand( LED_OFF ) ;
        }

    }
    
    return 0 ;
}

初期設定部
 これはCPU周辺(レジスター)と ZEAL の2つの初期設定を行います。

void Initialize(void)
{
    //-------------------------------------------------------
    // ポートの設定
    //-------------------------------------------------------
    // Port B 全てを出力に設定
    DDRB  = 0b11111111 ;

    // Port B PB5 High 
    PORTB = 0 ;

    // Port C 全てを出力に設定
    DDRC  = 0b11111111 ;

    // Port C 
    PORTC = 0b00000000 ;

    // Port D 設定
    //        ++----------- No connect
    //        ||+---------- Zeal CTS   LOW active output ( Zeal への要求 )
    //        |||+--------- Zeal RTS   LOW active input  ( Zeal からの要求 )
    //        ||||
    //        ||||+-------- Zeal Reset LOW active
    //        |||||+------- No connect
    //        ||||||+------ TxD
    //        |||||||+----- RxD
    //        ||||||||
    DDRD  = 0b11101111 ;

    PORTD = 0b00100000 ;    // Zeal に対して送信許可を行わない。(送信許可は ZealSetup 内で行う。)

    //-------------------------------------------------------
    // タイマーの設定
    //-------------------------------------------------------
    // 8 bit Timer 設定する。
    //         ++--------------- COM0A 標準ポート動作に設定する。
    //         ||++------------- COM0B 標準ポート動作に設定する。
    //         ||||++----------- Reserved
    //         ||||||++--------- WGM0 CTC動作
    //         ||||||||
    TCCR0A = 0b00000010 ;

    //         ++--------------- FOC0A, FOC0B
    //         ||++------------- Reserved
    //         ||||+------------ WGM02
    //         |||||+++--------- CS02, 1, 0 ( 1/256 )
    //         ||||||||
    TCCR0B = 0b00000101 ;       // 1/16MHz * 1024 = 64nsec

    OCR0A = (125-1) ;       // Output Compare A Register (0〜124) 125 * 64nsec = 8msec

    uiTimer_0 = TIMER0_INTERVAL ;
    
    //         +++++------------ Reserved
    //         |||||+----------- OCIE0B Output Compare Match B Interrupt Enable
    //         ||||||+---------- OCIE0A Output Compare Match A Interrupt Enable
    //         |||||||+--------- TOIE0  Timer Overflow Interrupt Enable
    //         ||||||||
    TIMSK0 = 0b00000010 ;

    uiWaitTime = 0 ;        // 時間待ちのタイマーをクリアする。
}

ZEAL の初期設定
 ZEALを一旦リセットし、AVRの通信速度をZEALの初期値(9600bps)より38400bps に変更し
ZEAL を待ち受け状態にします。

const char cmdBTSpeed[] = { "BTB384\r" } ;      // 通信速度を  38,400 bps に設定する。
const char cmdBTF04[]   = { "BTF04\r" } ;       // ZEAL Inquiry 応答に対応する。
const char cmdBTA[]     = { "BTA\r"   } ;       // 待ち受け状態とする。

void ZealSetup(void)
{
    // Port D 
    PORTD &= ~_BV(PD5) ;        // Zeal に対して送信許可を与える(当方、受信可)

    // Zeal Reset
    PORTD &= ~_BV(PD3) ;

    Wait_8msec( 5 ) ;

    PORTD |= _BV(PD3) ;
    
    Wait_8msec( 100 ) ; // 8×100= 0.8 秒 ... Zeal 応答可能まで待つ(応答無い時はコマンドを再送するが念の為)

    // ZEAL側の通信速度を変更する。初期値 9,600bps より 38,400 bps に変更する。
    do {
        SendCommand( cmdBTSpeed ) ;
    } while ( RecvResponse( respACKN ) ) ;
    Wait_8msec( 10 ) ;

    // AVR 側の通信速度を変更する。
    cli();          // 割込みを禁止する。
    Usart_0_Initialize(BPS_38400) ; // USART 設定
    sei();          // 割込みを許可する。

    // ZEAL を待ち受け状態に設定する。
    do {
        SendCommand( cmdBTF04 ) ;
    } while ( RecvResponse( respACKN ) ) ;
    Wait_8msec( 10 ) ;

    do {
        SendCommand( cmdBTA ) ;
    } while ( RecvResponse( respACKN ) ) ;
    Wait_8msec( 10 ) ;

    bConnectFlag = 1 ;  // 接続準備中(接続待ち)
}

割込み処理
 Arduino ではライブラリが処理してくれますが、自分で割込み処理を記述します。
割込み開始時のレジスター保存、割込み終了時のレジスター復帰、割込みよりの戻り処理は
AVR Studio (GCC) が自動で追加してくれます。

ISR (TIMER0_COMPA_vect)
{
    unsigned char bPortB ;

    if ( --uiTimer_0 == 0 )         // 320msec 毎に処理する。
    {
        if ( bConnectFlag == 1 )    // Bluetooth 待ち受けならば LED を点滅する。
        {
            bPortB  = PORTB ;
            bPortB ^= LED_13 ;
            PORTB   = bPortB ;
        }
        uiTimer_0 = TIMER0_INTERVAL ;   // 8msec × 40 = 320msec を設定する。
    }

    if ( uiWaitTime > 0 )
    {
        uiWaitTime-- ;
    }   
}


 プログラムはここに置いてあります。


 デバッグ & テスト

 JTAGICE3 デバッグを行うには AVR CPU のフューズ設定が必要です。
CPU が購入時のままだた DWEN は無効になっています。AVR Studio 5 の
メニューより ツール(T) 、AVR Programming を選択しフューズ設定を行って
下さい。
 なお、一旦、DWEN を有効とすると AVR Programming より戻せません。
デバッグ画面より Disable debugWIRE and Close を選択して元に戻して
下さい。


DWEN にチェックを追加します。
CKDEV8 はクロックを 1/8 にしない為にチェックを外します。

Android 側は S2 Bluetooth Terminal 2 をダウンロードして使用しました。


接続中の写真

連絡先 information-@-xstech.co.jp ( - を削除して@を半角文字に変更してください。)

Home

参考書籍 Ateml 社のホームページにはドキュメントがありますが中身は英語で書かれています。
日本語訳は AVR日本語情報サイト がありますので検索して下さい。