SSブログ

Arduino AVRでマルチタスクしてみない [ATmarquino Arduino]

avrWaveGenerator_001.png


折角なのでPWMで2相出力してみる。
/**********************************************************/
/* AVR Atmega328P PWM generator                           */
/**********************************************************/
#include <avr/io.h>
#include <FlexiTimer2.h>

extern "C"
{
}

/**********************************************************/
/* prototypes                                             */
/**********************************************************/

/**********************************************************/
/* valiables                                              */
/**********************************************************/
#define  PWMA_PIN  9  // PB1:OC1A
#define  PWMB_PIN  10  // PB2:OC1B
#define  TIMER_COUNTER_CLOCK  (1000000)
#define  FREQUENCY            (50.0f)
#define  RESOLUTION           (32)
#define  PHASE_SHIFT          (-60.0f)

int scale = (256 / 2) - 1;  /**/
int offset = (256 / 2) - 0;  /* center position */
int waveTableCounter;
float channelPhase = (2 * M_PI * PHASE_SHIFT / 360.0f);
unsigned int waveTableA[ RESOLUTION ];
unsigned int waveTableB[ RESOLUTION ];

/**********************************************************/
/* setup                                                  */
/**********************************************************/
void setup()
{
  Serial.begin( 115200UL );
  Serial.println( "AVR Atmega328P PWM generator." );
  pinMode( PWMA_PIN, OUTPUT );
  pinMode( PWMB_PIN, OUTPUT );

  /* generate wave data */
  for( int i = 0; i < RESOLUTION; i++ )
  {
    int tempI = (int)(sin(2 * M_PI * i / RESOLUTION) * scale);
    waveTableA[ i ] = (unsigned int)tempI + offset;
    tempI = (int)(sin((2 * M_PI * i / RESOLUTION) + channelPhase) * scale);
    waveTableB[ i ] = (unsigned int)tempI + offset;
  }

  /* display wave data A */
  Serial.println( "WAVE DATA A" );
  for( int i = 0; i < RESOLUTION; i++ )
  {
    Serial.print( waveTableA[ i ], DEC );
    Serial.print( "," );
    if( (i % 10) == 9 ) Serial.println();
  }
  Serial.println();

  /* display wave data B */
  Serial.println( "WAVE DATA B" );
  for( int i = 0; i < RESOLUTION; i++ )
  {
    Serial.print( waveTableB[ i ], DEC );
    Serial.print( "," );
    if( (i % 10) == 9 ) Serial.println();
  }
  Serial.println();

  /* timer counter initialize. */
  TCCR1B = 0x00;  //  timer1 stop
  TCNT1 = 0x0000;  // 16bit counter clear
  TIMSK1 = 0x00;  // interrupt disable
  TCCR1A = 0b10100001;  //  0b10 10 00 01
    // OC1A : compare match goes OC1A to clear and top goes OC1A to set.
    // OC1B : compare match goes OC1B to clear and top goes OC1B to set.
    // fast 8bit PWM and top is 0x00FF. WGM = 0b0101
  TCCR1B = 0b00001010;  //  0b0 0 0 01 010
    // fast 8bit PWM and top is 0x00FF.
    // clkIO / 8 priscaller.
  OCR1A = waveTableA[ 0 ];
  OCR1B = waveTableB[ 0 ];
  TIMSK1 = 0x00;  // interrupt disable

  waveTableCounter = 1;

  FlexiTimer2::set( 1, 1.0f / (FREQUENCY * RESOLUTION), pwmUpdateHandler );
  FlexiTimer2::start();

  /* Infinite loop */
  while(1) {}
}

/**********************************************************/
/* loop ※使われない                                      */
/**********************************************************/
void loop()
{
}

/**********************************************************/
/* pwm update handler                                     */
/**********************************************************/
void pwmUpdateHandler()
{
  OCR1A = waveTableA[ waveTableCounter ];
  OCR1B = waveTableB[ waveTableCounter ];
  if( ++waveTableCounter >= RESOLUTION )
  {
    waveTableCounter = 0;
  }
}


nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。