0

MSP430 マイクロプロセッサと Launchpad キットを使用して音楽プレーヤーを作成する必要がある課題を完了しようとしています。プレーヤーは完全に機能していますが、何らかの理由で特定の音符を超えて演奏しようとすると、トーンではなく速いクリック音が出力されます。

スピーカーがより高いトーンを生成できることはわかっているので、ソフトウェアの問題であると確信しており、おそらく何らかの数学エラーが発生しています。これが私のコードです(少なくともメモを処理する部分):

asm(" .length 10000");
asm(" .width 132");

#include "msp430g2553.h"
//-----------------------
// define the bit mask (within P1) corresponding to output TA0
#define TA0_BIT 0x02
// define the port and location for the button (this is the built in button)
// specific bit for the button
#define BUTTON_BIT 0x04

#define PLUS_BUTTON 0x08  //Defines the "GO FASTER" button to P1.3
#define MINUS_BUTTON 0x10 //Defines the "SLOW DOWN" button to P1.4
#define SHIFT 0x20
//----------------------------------
// Some global variables (mainly to look at in the debugger)
volatile unsigned halfPeriod; // half period count for the timer
volatile unsigned long intcount=0; // number of times the interrupt has occurred
volatile unsigned soundOn=0; // state of sound: 0 or OUTMOD_4 (0x0080)
volatile int noteCount = 0;
volatile int noteLength = 0;
volatile int deltaHP=1; // step in half period per half period
volatile unsigned int plus_on;
volatile unsigned int minus_on;
volatile double speed = 1;
volatile int shiftkey = 0;

static const int noteArray[] =   {800, 1000, 900, 800}; //THESE ARE THE NOTES
static const int noteLengths[] = {200,  500,  500, 500}; 

void init_timer(void); // routine to setup the timer
void init_button(void); // routine to setup the button
// ++++++++++++++++++++++++++
void main(){
    WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
    BCSCTL1 = CALBC1_1MHZ; // 1Mhz calibration for clock
    DCOCTL = CALDCO_1MHZ;
    //halfPeriod=noteArray[0]; // initial half-period at lowest frequency
    init_timer(); // initialize timer
    init_button(); // initialize the button
    _bis_SR_register(GIE+LPM0_bits);// enable general interrupts and power down CPU
}
// +++++++++++++++++++++++++++
// Sound Production System
void init_timer(){ // initialization and start of timer
    TA0CTL |=TACLR; // reset clock
    TA0CTL =TASSEL1+ID_0+MC_2; // clock source = SMCLK, clock divider=1, continuous mode,
    TA0CCTL0=soundOn+CCIE; // compare mode, outmod=sound, interrupt CCR1 on
    TA0CCR0 = TAR+noteArray[0]; // time for first alarm
    P1SEL|=TA0_BIT; // connect timer output to pin
    P1DIR|=TA0_BIT;
}
// +++++++++++++++++++++++++++
void interrupt sound_handler(){
    TACCR0 += (noteArray[noteCount]); // advance 'alarm' time
    if (soundOn){ // change half period if the sound is playing
        noteLength++;
        if (noteLength >= (speed* noteLengths[noteCount])) {
            noteLength=0;
            noteCount++;
            if (noteCount == sizeof(noteArray)/sizeof(int)) {
                //halfPeriod += deltaHP;
                noteCount = 0;
                //deltaHP=-deltaHP;
            }
        }
    }
    TA0CCTL0 = CCIE + soundOn; //  update control register with current soundOn
    ++intcount; // advance debug counter
}
ISR_VECTOR(sound_handler,".int09") // declare interrupt vector

現在、エラーを示すために、4 つのランダムな長さのランダムなノートが 4 つしかありません。800 から 900 の音価の間のどこかで奇妙なクリック ノイズが発生します。8xx より小さい数値に対してエラーを生成する何かがコードに欠けているのでしょうか? 分割エラーなどのスポットは見当たりませんが、間違っている可能性があります。ありがとうございました。

また、エラーが発生した場合、クリックが非常に長く続き、その音符の対応する長さよりもはるかに長く続くことに注意してください。ただし、それは永続的ではありません. 最終的に、プレーヤーは次の音符に移動し、900 程度より大きい限り、通常どおりに再生します。

4

1 に答える 1