Arduino AVRでマルチタスクしてみない [ATmarquino Arduino]
折角なので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; } }
2018-11-02 11:47
nice!(0)
コメント(0)
コメント 0