チーム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

このWIKIを編集するにはパスワード入力が必要です

認証パスワード