趣味の電子工作などの記録。時にLinuxへ行ったり、ガジェットに浮気したりするので、なかなかまとまらない。
RSS icon
  • SCP1000とKXP84を同時に動かす

    投稿日 2011年 5月 2日 コメントはありません

    タイトルの通りです。

    CSを別々にして両方のデバイスをSPIにぶら下げただけです。

    ただ、加速度計の方は周期的にデータを取りたいので一捻りしています。Arduinoで無理やりタイマ割り込みを設定し、割り込み処理ルーチン内でSPIにアクセスにいった上に浮動小数点演算までやるという無茶なことをしています。当然、SCP1000のSPIアクセスや非割り込み処理部分での浮動小数点演算と干渉しますので、SCP1000にアクセスに行くときや浮動小数点演算を行う箇所では割り込みを禁止しています。

    以下に主要部分を記載します。

    #include <avr/interrupt.h>
    #ifndef cbi
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #endif
    #ifndef sbi
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #endif
    
    volatile unsigned long timer1_count = 0;
    //////////////////////////////////////////////
    // Timer1 Interrupt
    SIGNAL(TIMER1_COMPA_vect)  // See voctor list sec.11-4
    {
       timer1_count++;
       IntAccProc(); <--割り込み処理で呼びたい関数
    }
    
    // Initialize Timer1 as Interval Timer
    void InitTimer1(unsigned long int cycle_in_ns){
      double t;
      TCCR1A = 0;
      TCCR1B = 0;
      // set timer 1 prescale factor to 64
      sbi(TCCR1B, CS11);
      sbi(TCCR1B, CS10);
      // Change mode 8bit-pwm to 16bit
      sbi(TCCR1B,WGM12); 
      // Set Cycle (10000000ns / 125ns) 
    #if F_CPU >= 16000000L
      t = cycle_in_ns/62.5;
    #else
      t = cycle_in_ns/125.0; // 
    #endif
      OCR1A = (unsigned int)(t/64.0);
      // Enable Timer0 OCIE1A interrupt
      sbi(TIMSK1,OCIE1A);
    }

    反則技だと思いますが、やっぱり割り込みは使いたいですからね。
    そうそう、干渉しそうな場所は cli()で割り込みを禁止し、必要がなくなったら sei()で割り込みを許可してやる必要があります。