Hello everyone,
I hope someone can help me with my current Arduino project. I am trying to make a Digitaly Controlled Oscillator for a synthesizer, and as one part of that I need to be able to read an analogue voltage from the arduino.
I want to trigger an update of the ADC every time Timer0 overflows, and once the ADC has updated, have it throw and interupt.
From reading the data sheet I belive that this is possible but it doesnt work in my code. It works in free-running mode, but that will poll the ADC too fast for my needs. When triggering from the Timer0 overflow, the interupt routine never gets called, and I cant for the life of me seem to find out why.
I should point out that I am quite new to dealing with registers on the arduino so perhaps that will factor into this.
Here is my code so far (sorry for the mess

:
/* */
#include <math.h>
#include "pins_arduino.h"
/* */
namespace PreScaler
{
enum ePsk
{
C_PSK_1 = 0b00000001,
C_PSK_8 = 0b00000010,
C_PSK_64 = 0b00000011,
C_PSK_256 = 0b00000100,
C_PSK_1024 = 0b00000101
};
};
/* */
int lSt = 0;
ISR( TIMER1_COMPA_vect )
{
/* change this to use bitwize xor
* on the output port
* some funny errors with this
*/
if ( lSt == 0 ) digitalWrite( 9, HIGH );
else digitalWrite( 9, LOW );
lSt = 1 - lSt;
}
/* */
void set_pll_freq( uint16_t aFreq )
{
int32_t lOCR = (F_CPU / (aFreq * 2)) - 1;
int8_t lPsk = PreScaler::C_PSK_1;
/* find prescaler and set ctc max */
if ( lOCR > 0xFFFF )
{
lOCR = (F_CPU / (aFreq * 2 * 64)) - 1;
if ( lOCR > 0xFFFF )
lOCR = 0xFFFF;
lPsk = PreScaler::C_PSK_64;
}
/* update the registers */
TCCR1B = (TCCR1B & 0b11111000) | lPsk;
OCR1A = lOCR;
}
/* */
void start_pll( void )
{
/* setup the output pin */
pinMode( 9, OUTPUT );
/* setup 16bit timer */
TCCR1A = 0b10000000;
TCCR1B = 0b00001000;
TCCR1B = TCCR1B | (PreScaler::C_PSK_1);
/* enable the interupt */
TIMSK1 = 0b00000010;
}
/* */
uint16_t gAPM = 0;
bool gPitchChange = false;
ISR( ADC_vect )
{
uint16_t lAPM = 0;
// if ( (ADCSRA | 0b00010000) != 0 )
// {
lAPM = ADCL;
lAPM += ADCH << 8;
/* compare without jitter */
if ( (lAPM>>1) != (gAPM>>1) )
{
gPitchChange = true;
gAPM = lAPM;
}
// }
/* re-enable the interupt */
// ADCSRA = 0b10101111;
}
/* */
void start_apm( void )
{
/* setup 8bit timer */
TCCR0A = 0b00000000;
TCCR0B = 0b00000000;
TCCR0B = TCCR0B | (PreScaler::C_PSK_1024);
TIMSK0 = 0b00000000;
/* setup the d-a converter */
DIDR0 = 0b00111111;
ADMUX = 0b01000000;
// ADCSRB = 0b00000000; // free running mode
ADCSRB = 0b00000100; // timer 0 overflow
ADCSRA = 0b11101111;
}
/* */
extern
void setup( void )
{
/* analogue pitch modulation */
start_apm( );
/* phase locked loop output */
start_pll( );
/* enable the output */
gPitchChange = true;
}
/* */
uint32_t note = 1;
/* */
extern
void loop( void )
{
/* nothing yet */
// set_pll_freq( (uint16_t)(pow( 2.0f, (float)note/12.0f )) + (lA/7));
if ( gPitchChange )
{
set_pll_freq( gAPM );
gPitchChange = false;
}
}
Timer 0 and the ADC are setup in the start_apm function.
Currently, the program should read an analogue voltage on Analogue Pin 0 and output a square wave of proportional frequency on pin 9.
I would be most greatfull for some assistance with this problem.
I am using the Arduino Duemilanove with the Atmega328p chip.