Я пытаюсь собрать драм-машину, используя Atmega644. Драм-машина будет иметь 16 светодиодов, которые покажут, на каком 16-м такте она находится. Пользователь должен иметь возможность установить BPM, и поэтому обновление светодиода будет отличаться для разных BPM.
У меня 16 МГц Crystal установлен на XTAL1 и XTAL2. Я использовал калькулятор FUSE, чтобы записать биты FUSE в «генератор полного колебания» и удалить внутреннее деление тактовой частоты 8. Затем я настроил TIMER0 для выполнения этой задачи
#define F_CPU 16000000UL // 1MHz internal clock
unsigned int tempo = 250; // Default BPM of 120.
volatile unsigned int seq_timer = 0;
//set-up timer for 0.5 ms update
TIMSK0 = (1<<OCIE0A);
TCCR0A = (1 << WGM01) |(1<<WGM00);
TCCR0B = (0 << WGM02) | (0<< CS02) | (1 << CS01) | (1 << CS00); //divide by 64
OCR0A = 125;
ISR (TIMER0_COMPA_vect) {
if (seq_timer>0) {seq_timer--;}
}
//Update which 16th note we are at.
void step(void){
update_led();
step_number = step_number < 15 ? step_number +1 : 0;
}
//Shift the LED such that the LED corresponding to step_number is lit up.
void update_led(void) {
for (int j = 16; j>=0; j--)
{
if ((((1 << step_number))>>j) & 0x01) {
PORTD |= (1 << PD5); //Serial Input
}
else {
PORTD &= ~(1 << PD5);
}
PORTD |= (1 << PD4); //Read clock
PORTD &= ~(1<< PD4);
}
PORTD |= (1 << PD3); //Shift clock
_delay_ms(40);
PORTD &= ~(1 << PD3);
}
while (1)
{
if ((seq_timer == 0)) {
seq_timer = tempo;
step();
}
Шаговые функции вызывают функцию update_led (), которая загорается светодиодом, соответствующим номеру шага. По моим расчетам это должно произойти (16e6 / (64 * 250 * 125)) = 8 обновлений в секунду. Но вместо этого он делает 4 обновления / сек.
Я что-то упустил?