排列に格納したいくつかの音を順番に鳴らす

https://github.com/ti-nspire/AVR/tree/master/Music_Box

https://ti-nspire.hatenablog.com/entry/2019/04/16/100444では、鳴らす音をシリアルポートから指定したが、今度はあらかじめ排列にノートをいくつか仕込んでおいて、スイッチを押すたびにそのノートを順番に鳴らしてみる。

f:id:ti-nspire:20190525113004j:plain:h300f:id:ti-nspire:20190525112937p:plain:h300

#include <avr/io.h>
#include <util/delay.h>
#include "scale16.h"

void playNote(uint16_t period, uint16_t duration, uint8_t whichPort, uint8_t whichPin) {
    for (int elapsed = 0; elapsed < duration; elapsed += period) {
        for (int i = 0; i < period; i++) {
            _delay_us(1);
        }
        switch(whichPort){
            //case 'B': PORTB ^= (1 << whichPin); break;
            //case 'C': PORTC ^= (1 << whichPin); break;
            case 'D': PORTD ^= (1 << whichPin); break;
            default: break;
        }
    }
}

int main(void) {
    const uint16_t Notes[] = {C5,E5,G5,B5};                        // このノートを順番に鳴らす。
    const uint8_t NumOfNotes = (sizeof(Notes) / sizeof(uint16_t)); // ノートの数を取得しておく。
    uint8_t whichNote = -1;
    uint8_t wasPressed = 0;

    DDRD  |= (1 << PD6); // PD6のIOをOUTに設定し、そこにスピーカーをつなぐ。
    PORTD |= (1 << PD2); // PD2を内部プルアップし、そこに押しボタンをつないでディジタル入力として使う。

    while (1) {
        if (bit_is_clear(PIND, PD2)) {
            if (!wasPressed) {
                wasPressed = 1;
                whichNote++;
                if (whichNote == NumOfNotes) {whichNote = 0;} // 鳴らしたいノートのインデックスが末尾を飛びだしたらインデックスを先頭に戻す。
                //whichNote %= NumOfNotes;
            }
            playNote(Notes[whichNote], 1600, 'D', PD6);
        } else {
            wasPressed = 0;
        }
    }
    
    return 0;
}