チーム1865
課題名
matrix piano
研究者名
Rikuya Aoyama
Akira Ikeuchi
Utsuki Ishibashi
使用器具
PSoC基盤
Miniprog
スピーカー
4×4マトリックスキーパッド
概要
4×4マトリックスキーパッドを用いてドレミファソラシドの音を使って演奏する
また演奏した曲を記録し再生することができる
4x4マトリックスキーパッドの使用法については演習資料 gpio_poll.pdfに記載してあるプロジェクトファイルをもとにした
ソースコード
#include <m8c.h>
#include "PSoCAPI.h"
static const keypad_LUT[256] =
{/* 0 1 2 3 4 5 6 7
8 9 A B C D E F */
/*0*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*1*/0x20, '1', '4', 0x20, '7', 0x20, 0x20, 0x20,
'*', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*2*/0x20, '2', '5', 0x20, '8', 0x20, 0x20, 0x20,
'0', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*3*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*4*/0x20, '3', '6', 0x20, '9', 0x20, 0x20, 0x20,
'#', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*5*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*6*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*7*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*8*/0x20, 'A', 'B', 0x20, 'C', 0x20, 0x20, 0x20,
'D', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*9*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*A*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*B*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*C*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*D*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*E*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*F*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
};
/* These two variables are used to store the row number and the column number */
BYTE rows,cols;
BYTE InterruptCounter=0;
/* These two variables store the key number */
unsigned char key[2] = {0x20,0};
/*****************************************************/
int music[100];
int j=0,i=0;
/****************Functions****************************/
/* Handles keypad function- Checks the key pressed and debounces key */
void KeyPadHandler(void);
/* Keypad scanning routine */
unsigned char keypad_scan(void);
/* Initializes user modules used in the design */
void InitModules(void);
/* Interrupt handler for GPIO interrupt */
void GPIOInterrupt(void);
/****************************************************/
void play(int music[]){
int l=0,k=0; for(l=0;l<j;l++){ LCD_1_Position(1,6); PWM16_1_WritePeriod(music[l]); if(music[l]==229) LCD_1_PrCString("D"); else if(music[l]==204) LCD_1_PrCString("L"); else if(music[l]==182) LCD_1_PrCString("M"); else if(music[l]==172) LCD_1_PrCString("F"); else if(music[l]==153) LCD_1_PrCString("S"); else if(music[l]==136) LCD_1_PrCString("R"); else if(music[l]==121) LCD_1_PrCString("C"); else if(music[l]==115) LCD_1_PrCString("DD"); else if(music[l]==0) LCD_1_PrCString("SILENT"); while(1){ k++; if(k>=20000)break; } k=0; }
}
void main(void)
{
/* Initialize variables and user modules */ InitModules(); /* Enable Global Interrupt */ M8C_EnableGInt; PWM16_1_Start(); while(1) { /* Check the Keypad status and update on LCD if any key is pressed */ if(key[0] != 0x20) { /* Valid key */ if(key[0]=='A'){ LCD_1_Position(0,9); LCD_1_PrCString("A"); i=1;j=0; } if(key[0]=='B'){ i=0; } if(key[0]=='C'){ play(music); LCD_1_Position(0,7); LCD_1_PrCString("C "); i=0;j=0; } /* Set LCD cursor position */ LCD_1_Position(0, 7); /* Display pressed keypad button */ LCD_1_PrString((char *)key); /* Set LCD cursor position */ LCD_1_Position(1,6); LCD_1_PrCString(" "); LCD_1_Position(1,6); /* Display nuymber of times key is pressed so far */ if(key[0] == '1'){ LCD_1_PrCString("D"); PWM16_1_WritePeriod(229); if(i=1){ music[j++]=229; } } if(key[0] == '2'){ LCD_1_PrCString("L"); PWM16_1_WritePeriod(204); if(i=1){ music[j++]=204; } } if(key[0] == '3'){ LCD_1_PrCString("M"); PWM16_1_WritePeriod(182); if(i=1){ music[j++]=182; } } if(key[0] == '4'){ LCD_1_PrCString("F"); PWM16_1_WritePeriod(172); if(i=1){ music[j++]=172; } } if(key[0] == '5'){ LCD_1_PrCString("S"); PWM16_1_WritePeriod(153); if(i=1){ music[j++]=153; } } if(key[0] == '6'){ LCD_1_PrCString("R"); PWM16_1_WritePeriod(136); if(i=1){ music[j++]=136; } } if(key[0] == '7'){ LCD_1_PrCString("C"); PWM16_1_WritePeriod(121); if(i=1){ music[j++]=121; } } if(key[0] == '8'){ LCD_1_PrCString("DD"); PWM16_1_WritePeriod(115); if(i=1){ music[j++]=115; } } if(key[0] == '9'){ LCD_1_PrCString("SILENT"); PWM16_1_WritePeriod(0); if(i=1){ music[j++]=0; } } /* Invalidate key */ key[0]=0x20; } /* Do other tasks */ }
}
/* This function initializes all the user modules used in the design */
void InitModules(void)
{
/* Initialize LCD */ LCD_1_Start(); LCD_1_Position(0,0); LCD_1_PrCString("Switch:"); LCD_1_Position(1,0); LCD_1_PrCString("Scale:"); /* Initilize timer- 10ms delay */ Timer16_1_WritePeriod(320); Timer16_1_EnableInt(); /* Enable GPIO interrupt */ INT_MSK0|=0x20; /* Write 1's at column lines */ PRT0DR|=0xF0;
}
/*
This is the port mapping for the keypad ports.
p0.4 p0.5 p0.6 p0.7 | | | |
p0.0 ---1----2----3----A
| | | |
p0.1 ---4----5----6----B
| | | |
p0.2 ---7----8----9----C
| | | |
p0.3 ---*----0----#----D
/* This function scan the keypad and identifies the key pressed */
unsigned char keypad_scan(void)
{
BYTE key_result; /* Drive rows */ PRT0DR = 0x0F; /* Read columns */ rows = PRT0DR; /* Drive columns */ PRT0DR = 0xF0; /* Read rows */ cols = PRT0DR; /* Combine results */ key_result = rows & cols; /* Get the key number from LUT */ return(keypad_LUT[key_result]);
}
/* This is the interrupt handler for the GPIO interrupt. Debounce timer is started on GPIO interrupt */
#pragma interrupt_handler GPIOInterrupt
void GPIOInterrupt(void)
{
/* Disable GPIO interrupt */ INT_MSK0&=~0x20; /* Start Timer */ Timer16_1_Start();
}
/* This is the interrupt handler for the timer. Scanning routine is called for key identification */
void TimerInterrupt(void)
{
/* Stop the timer and update the flag */ Timer16_1_Stop(); /* Get the key */ key[0] = keypad_scan(); /* Check if no key or multiple keys are pressed */ if(key[0] != 0x20) { /* Valid key. Take action if required */ /* Increment interrupt counter */ InterruptCounter++; } /* Clear GPIO posted interrupt */ INT_CLR0&=~0x20; /* Enable GPIO interrupt */ INT_MSK0|=0x20;
}
考察 [#ce7779b2]。
音階用の9個、録音開始、終了、録音の再生用の12個のボタンしか使っていないので、まだ機能の追加が可能である。
再生が最初の1音のみしかできないという原因不明のバグがまだ残っている。
おこる条件がわからないため,原因の特定をすることができなかった.
再生の1音の長さが一定なので1音の演奏時間も保存できるようにすると再生の幅が広がる。
- 最終更新:2019-01-08 16:32:55