Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* ###################################################################
- ** Filename : main.c
- ** Project : 3
- ** Processor : MKL46Z256VLL4
- ** Version : Driver 01.01
- ** Compiler : GNU C Compiler
- ** Date/Time : 2019-05-30, 13:41, # CodeGen: 0
- ** Abstract :
- ** Main module.
- ** This module contains user's application code.
- ** Settings :
- ** Contents :
- ** No public methods
- **
- ** ###################################################################*/
- /*!
- ** @file main.c
- ** @version 01.01
- ** @brief
- ** Main module.
- ** This module contains user's application code.
- */
- /*!
- ** @addtogroup main_module main module documentation
- ** @{
- */
- /* MODULE main */
- /* Including needed modules to compile this module/procedure */
- #include "Cpu.h"
- #include "Events.h"
- /* Including shared modules, which are used for whole project */
- #include "PE_Types.h"
- #include "PE_Error.h"
- #include "PE_Const.h"
- #include "IO_Map.h"
- #define NOTERATIO 1.05 // 正弦波の値を変えるタイミングを変える倍率
- #define INTERVAL 1500 // 音と音のインターバル
- #define SCORESIZE 82
- #define SCORE2SIZE 66
- /* User includes (#include below this line is not maintained by Processor Expert) */
- void convert8bit(int i) {
- //上位ビットから順に B0, B1, B2, B3, A14, A15, A16, A17
- if (i & 1) {GPIOB_PSOR = (1 << 0);} else {GPIOB_PCOR = (1 << 0);}
- if ((i >> 1) & 1) {GPIOB_PSOR = (1 << 1);} else {GPIOB_PCOR = (1 << 1);}
- if ((i >> 2) & 1) {GPIOB_PSOR = (1 << 2);} else {GPIOB_PCOR = (1 << 2);}
- if ((i >> 3) & 1) {GPIOB_PSOR = (1 << 3);} else {GPIOB_PCOR = (1 << 3);}
- if ((i >> 4) & 1) {GPIOA_PSOR = (1 << 14);} else {GPIOA_PCOR = (1 << 14);}
- if ((i >> 5) & 1) {GPIOA_PSOR = (1 << 15);} else {GPIOA_PCOR = (1 << 15);}
- if ((i >> 6) & 1) {GPIOA_PSOR = (1 << 16);} else {GPIOA_PCOR = (1 << 16);}
- if ((i >> 7) & 1) {GPIOA_PSOR = (1 << 17);} else {GPIOA_PCOR = (1 << 17);}
- }
- typedef struct noteinfo {
- double length; // 音の長さ
- char pitch; //音の高さ(-1なら休符)
- int octave; //オクターブ
- } note;
- int notes[12][4] =
- {
- {1222, 611, 305, 152}, // C 0
- {1153, 576, 288, 143}, // C# 1
- {1089, 544, 271, 135}, // D 2
- {1028, 513, 256, 127}, // D# 3
- {970, 484, 242, 120}, // E 4
- {915, 457, 228, 114}, // F 5
- {864, 431, 215, 107}, // F# 6
- {815, 407, 203, 101}, // G 7
- {770, 384, 192, 95}, // G# 8
- {726, 363, 181, 90}, // A 9
- {685, 342, 171, 85}, // A#(a) 10
- {647, 323, 161, 80} // B 11
- };
- int getPitchNumber(char pitch) { // break...?
- switch (pitch) {
- case 'C': return 0; break;
- case 'c': return 1; break;
- case 'D': return 2; break;
- case 'd': return 3; break;
- case 'E': return 4; break;
- case 'F': return 5; break;
- case 'f': return 6; break;
- case 'G': return 7; break;
- case 'g': return 8; break;
- case 'A': return 9; break;
- case 'a': return 10; break;
- case 'B': return 11; break;
- case 'R': return -1; break;
- }
- }
- int getOctave(){
- int octave;
- if(GPIOE_PDIR & (1 << 2)){
- if(GPIOE_PDIR & (1 << 3)){
- octave = 2; //どっちも5Vなら1オクターブ高く
- }else{
- octave = 1; //両方が違う値をとればそのままの値を
- }
- }else{
- if(GPIOE_PDIR & (1 << 3)){
- octave = 1; //両方が違う値をとればそのままの値を
- }else{
- octave = 0; //どっちも0Vなら1オクターブ低く
- }
- }
- return octave;
- }
- int getSpeed(){
- int speed;
- if(GPIOE_PDIR & (1 << 6)){speed = 2;}else{speed = 1;}
- return speed;
- }
- int changeSong(){
- // 1ならscore[]を、0ならscore2[]を与える
- int score;
- if(GPIOE_PDIR & (1 << 1)) {
- score = 1;
- }else{
- score = 2;
- }
- return score;
- }
- int restflag;
- void setNote(note note) {
- // note->length : 音の長さ
- // note->pitch : 音の高さ
- // note->octave : オクターブ
- // カウンタを止める -> 設定変更 -> increment開始
- int pitch = getPitchNumber(note.pitch); // 音の高さに対応する数字を取得
- int octave = note.octave + getOctave();
- int speed = getSpeed();
- int tempo;
- if(changeSong() == 1){tempo = 116;} else {tempo = 82;}
- TPM0_SC &= ~TPM_SC_CMOD(0b11); // Stop TPM0 (Set CMOD to 0)
- TPM1_SC &= ~TPM_SC_CMOD(0b11); // Stop TPM1 (Set CMOD to 0)
- if (pitch == -1) { // 休符
- TPM1_MOD = TPM_MOD_MOD((7499760 / tempo * note.length - INTERVAL) / speed); //31249(1秒)* (60/116) * note->length - 音と音の切れ目
- restflag = 1;
- } else {
- TPM0_MOD = TPM_MOD_MOD(notes[pitch][octave]);
- TPM1_MOD = TPM_MOD_MOD((7499760 / tempo * note.length - INTERVAL) / speed); //31249(1秒)* (60/116) * note->length - 音と音の切れ目
- restflag = 0;
- }
- TPM0_SC |= TPM_SC_CMOD(0b01); // Start TPM0
- TPM1_SC |= TPM_SC_CMOD(0b01); // Start TPM1
- }
- void determineNoteByTSI(int touch){
- TPM0_SC &= ~TPM_SC_CMOD(0b11); // Stop TPM0 (Set CMOD to 0)
- TPM0_MOD = TPM_MOD_MOD(touch / 64);
- TPM0_SC |= TPM_SC_CMOD(0b01); // Start TPM0
- }
- /*lint -save -e970 Disable MISRA rule (6.3) checking. */
- int main(void)
- /*lint -restore Enable MISRA rule (6.3) checking. */
- {
- /* Write your local variable definition here */
- /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
- PE_low_level_init();
- /*** End of Processor Expert internal initialization. ***/
- /* Write your code here */
- /* For example: for(;;) { } */
- /* 正弦波となるように電圧のデータを組む */
- int sin_wave[] =
- {
- 0x80, 0x9F, 0xBD, 0xD7, 0xEC,
- 0xF9, 0xFF, 0xFD, 0xF3, 0xE2,
- 0xCB, 0xAF, 0x90, 0x6F, 0x50,
- 0x32, 0x1D, 0x0C, 0x02, 0x00,
- 0x06, 0x13, 0x28, 0x42, 0x60
- };
- // 体裁として、1行あたり1小節 R=rest(休符)
- note score[] = {
- // 体裁として、1行あたり1小節 R=rest(休符)
- {0.1875, 'C', 0}, {0.0625, 'F', 0},
- {0.25, 'A', 0}, {0.25, 'G', 0}, {0.25, 'F', 0}, {0.1875, 'F', 0}, {0.0625, 'F', 0},
- {0.75, 'C', 1}, {0.25, 'A', 0},
- {0.5, 'A', 0}, {0.25, 'F', 0}, {0.25, 'A', 0},
- {0.75, 'G', 0}, {0.1875, 'C', 0}, {0.0625, 'F', 0},
- {0.25, 'A', 0}, {0.25, 'G', 0}, {0.25, 'F', 0}, {0.1875, 'F', 0}, {0.0625, 'A', 0},
- {0.75, 'D', 1}, {0.25, 'D', 1},
- {0.375, 'C', 1}, {0.125, 'A', 0}, {0.25, 'G', 0}, {0.1875, 'G', 0}, {0.0625, 'A', 0},
- {0.75, 'F', 0}, {0.25, 'R', 0},
- {0.25, 'G', 0}, {0.125, 'G', 0}, {0.125, 'A', 0}, {0.1875, 'a', 0}, {0.0625, 'a', 0}, {0.125, 'a', 0}, {0.125, 'a', 0},
- {0.25, 'A', 0}, {0.125, 'A', 0}, {0.125, 'a', 0}, {0.5, 'C', 1},
- {0.1875, 'D', 1}, {0.0625, 'D', 1}, {0.125, 'D', 1}, {0.125, 'D', 1}, {0.25, 'C', 1}, {0.125, 'A', 0}, {0.125, 'F', 0},
- {0.1875, 'G', 0}, {0.0625, 'G', 0}, {0.125, 'F', 0}, {0.125, 'D', 0}, {0.25, 'C', 0}, {0.25, 'R', 0},
- {0.25, 'D', 0}, {0.125, 'D', 0}, {0.125, 'C', 0}, {0.1875, 'F', 0}, {0.0625, 'F', 0}, {0.125, 'G', 0}, {0.125, 'C', 1},
- {0.25, 'A', 0}, {0.125, 'G', 0}, {0.125, 'G', 0}, {0.125, 'F', 0}, {0.125, 'R', 0}, {0.1875, 'C', 1}, {0.0625, 'C', 1},
- {0.25, 'D', 1}, {0.25, 'C', 1}, {0.25, 'A', 0}, {0.1875, 'F', 0}, {0.0625, 'A', 0},
- {0.75, 'C', 1}, {0.25, 'D', 1},
- {0.5, 'C', 1}, {0.25, 'A', 0}, {0.25, 'G', 0},
- {0.25, 'F', 0}, {0.1875, 'F', 1}, {0.0625, 'F', 1}, {0.5, 'F', 1},
- {1.0, 'R', 0}
- };
- note score2[] = {
- {0.0625, 'C', 1}, {0.0625, 'G', 0}, {0.0625, 'A', 0}, {0.0625, 'G', 0}, {0.125, 'A', 0}, {0.125, 'G', 0}, {0.125, 'E', 1}, {0.0625, 'G', 1}, {0.0625, 'E', 1}, {0.0625, 'D', 1}, {0.1875, 'C', 1},
- {0.0625, 'C', 1}, {0.0625, 'G', 0}, {0.0625, 'A', 0}, {0.0625, 'G', 0}, {0.125, 'A', 0}, {0.125, 'G', 0}, {0.125, 'E', 1}, {0.0625, 'G', 1}, {0.0625, 'E', 1}, {0.0625, 'D', 1}, {0.1875, 'C', 1},
- {0.25, 'A', 0}, {0.0625, 'R', 0}, {0.0625, 'A', 0}, {0.0625, 'B', 0}, {0.0625, 'C', 1}, {0.25, 'E', 1}, {0.25, 'C', 1},
- {0.125, 'F', 1}, {0.125, 'E', 1}, {0.125, 'C', 1}, {0.125, 'A', 0}, {0.125, 'G', 0}, {0.0625, 'E', 1}, {0.1875, 'E', 1},
- {0.0625, 'C', 1}, {0.0625, 'G', 0}, {0.0625, 'A', 0}, {0.0625, 'G', 0}, {0.125, 'A', 0}, {0.125, 'G', 0}, {0.125, 'E', 1}, {0.0625, 'G', 1}, {0.0625, 'E', 1}, {0.0625, 'D', 1}, {0.1875, 'C', 1},
- {0.0625, 'C', 1}, {0.0625, 'G', 0}, {0.0625, 'A', 0}, {0.0625, 'G', 0}, {0.125, 'A', 0}, {0.125, 'G', 0}, {0.125, 'E', 1}, {0.0625, 'G', 1}, {0.0625, 'E', 1}, {0.0625, 'D', 1}, {0.1875, 'C', 1},
- {0.25, 'G', 1}, {0.25, 'C', 1}, {0.125, 'F', 1}, {0.125, 'E', 1}, {0.125, 'D', 1}, {0.0625, 'C', 1}, {1.0625, 'C', 1},
- {1, 'R', 0}
- };
- /* クロックの設定 */
- SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; // PTA のクロックを有効にする
- PORTA_PCR2 = PORT_PCR_MUX(1); // PTA2 を GPIO に設定する
- GPIOA_PDDR &= ~(1 << 2); // PTA2 を入力に設定する(for debug)
- PORTA_PCR14 = PORT_PCR_MUX(1); // PTA14をGPIOに設定する
- PORTA_PCR15 = PORT_PCR_MUX(1); // PTA15をGPIOに設定する
- PORTA_PCR16 = PORT_PCR_MUX(1); // PTA16をGPIOに設定する
- PORTA_PCR17 = PORT_PCR_MUX(1); // PTA17をGPIOに設定する
- GPIOA_PDDR |= (0b1111 << 14); //PTA14-17を出力に設定する
- SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;
- PORTB_PCR0 = PORT_PCR_MUX(1); // PTB0をGPIOに設定する
- PORTB_PCR1 = PORT_PCR_MUX(1); // PTB1をGPIOに設定する
- PORTB_PCR2 = PORT_PCR_MUX(1); // PTB2をGPIOに設定する
- PORTB_PCR3 = PORT_PCR_MUX(1); // PTB3をGPIOに設定する
- GPIOB_PDDR |= (0b1111 << 0); //PTB0-3を出力に設定する
- SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK; // PTDのクロックを有効にする
- PORTD_PCR5 = PORT_PCR_MUX(1);
- GPIOD_PDDR |= (1 << 5); //(debug)
- SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK; // PTEのクロックを有効にする
- PORTE_PCR29 = PORT_PCR_MUX(1);
- GPIOE_PDDR |= (1 << 29); // (debug)
- PORTE_PCR1 = PORT_PCR_MUX(1);
- PORTE_PCR2 = PORT_PCR_MUX(1);
- PORTE_PCR3 = PORT_PCR_MUX(1);
- PORTE_PCR6 = PORT_PCR_MUX(1);
- GPIOE_PDDR &= ~(0b111 << 1); // PTE1-3のクロックを有効にする(音程の変更)
- GPIOE_PDDR &= ~(1 << 6);
- //Enable clock gates
- SIM_SCGC5 |= (SIM_SCGC5_TSI_MASK) | (SIM_SCGC5_PORTA_MASK);
- PORTA_PCR1 = PORT_PCR_MUX(0); //Enable ALT0 for portA1 -> Ch 2
- //Configure the TSI module and enable the interrupt
- TSI0_GENCS |= (TSI_GENCS_ESOR_MASK
- | TSI_GENCS_REFCHRG(4)
- | TSI_GENCS_DVOLT(0)
- | TSI_GENCS_EXTCHRG(6)
- | TSI_GENCS_PS(4)
- | TSI_GENCS_NSCN(11)
- | TSI_GENCS_TSIIEN_MASK
- | TSI_GENCS_STPE_MASK
- //| TSI_GENCS_STM_MASK //Trigger for the module 0=Software
- );
- // Clear End of scan and Out of Range Flags
- TSI0_GENCS |= (TSI_GENCS_OUTRGF_MASK) | (TSI_GENCS_EOSF_MASK);
- //Select Desired Channel to Scan
- TSI0_DATA |= (TSI_DATA_TSICH(2)); // Choose channel 2
- // Enables TSI
- TSI0_GENCS |= (TSI_GENCS_TSIEN_MASK);
- int i; // for sin_wave[]
- int j=0; // for score[]
- int state = 0;
- int counter = 0;
- int song = 1; // 1ならscore[], 2ならscore2[]を演奏
- bool pta2_val;
- int pta2_pushing = 0;
- int scorenumber;
- int touch;
- // スイッチが離されるまで待つ
- while (1) {
- pta2_val = GPIOA_PDIR & (1 << 2) ? 1 : 0;
- if (pta2_val == 0) break;
- }
- while(1){
- switch (state) {
- case 0: // 初期状態
- // 変数の値を設定
- i = 0; j = 1;
- GPIOD_PCOR = (1 << 5);
- GPIOE_PCOR = (1 << 29);
- while(1){
- pta2_val = GPIOA_PDIR & (1 << 2) ? 1 : 0;
- if (pta2_val) {
- if (pta2_pushing == 0) {
- pta2_pushing = 1; //押下モードに移行
- }
- } else {
- if (pta2_pushing == 1) { //おしてたら
- pta2_pushing = 0;
- state = 1;
- break;
- } else {
- pta2_pushing = 0;
- }
- }
- }
- break;
- case 1: // 演奏状態
- //タイマーを設定する
- GPIOD_PSOR = (1 << 5);
- GPIOE_PCOR = (1 << 29);
- SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;
- SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK;
- SIM_SOPT2 |= SIM_SOPT2_TPMSRC(0b11); // MCGIRCLKをセットする
- MCG_C2 |= MCG_C2_IRCS_MASK; // 4MHzをクロックソースとして指定
- MCG_SC &= ~MCG_SC_FCRDIV(0b111); // Divide by 1を設定
- TPM0_SC &= ~TPM_SC_PS(0b111); //divide by 1;
- TPM1_SC |= TPM_SC_PS(0b111); // divide by 128
- TSI0_DATA |= TSI_DATA_SWTS_MASK; // TSI0のscanを開始する
- scorenumber = changeSong();
- /* if(scorenumber == 1){
- if(j<SCORESIZE) {setNote(score[j]);} else {j=0;}
- }else{
- if(j<SCORE2SIZE) {setNote(score2[j]);} else {j=0;}
- }
- j++;*/
- while (1) {
- pta2_val = GPIOA_PDIR & (1 << 2) ? 1 : 0;
- if(TPM0_SC & TPM_SC_TOF_MASK){
- TPM0_SC |= TPM_SC_TOF_MASK;
- if(i==24) i=0;
- if(counter % 2 == 0 || restflag == 0){
- // インターバルor休符なら電圧を一定にしておく
- TPM0_SC &= ~TPM_SC_CMOD(0b11); // Stop TPM0 (Set CMOD to 0)
- TPM0_MOD = TPM_MOD_MOD(notes[9][0]);
- convert8bit(sin_wave[i]);
- TPM0_SC |= TPM_SC_CMOD(0b01); // Start TPM0
- i++;
- }
- }
- if(TSI0_GENCS & TSI_GENCS_EOSF_MASK){ // スキャンがおわったら
- TSI0_GENCS &= ~TSI_GENCS_EOSF_MASK; // タイマーをリセットする
- TSI0_DATA &= ~TSI_DATA_SWTS_MASK; // スタートを0にしとく(?)
- // TSI0_TSICNTを読み込んでみる
- touch = TSI0_DATA & TSI_DATA_TSICNT_MASK;
- // touchの値に応じて音を流す
- determineNoteByTSI(touch);
- // クロックを再開する
- TSI0_DATA |= TSI_DATA_SWTS_MASK;
- }
- /*if(TPM1_SC & TPM_SC_TOF_MASK){
- TPM1_SC |= TPM_SC_TOF_MASK;
- restflag = 0;
- if(counter % 2 == 1){
- // 音の間のインターバル
- TPM0_SC &= ~TPM_SC_CMOD(0b11);
- TPM1_SC &= ~TPM_SC_CMOD(0b11); // Stop TPM0 (Set CMOD to 0)
- TPM1_MOD = TPM_MOD_MOD(INTERVAL);
- TPM0_SC |= TPM_SC_CMOD(0b01); // Start TPM0
- TPM1_SC |= TPM_SC_CMOD(0b01);
- restflag = 1;
- }else{
- // 音を鳴らす
- if(scorenumber == 1){
- if(j<SCORESIZE) {setNote(score[0]);} else {j=0;}
- }else{
- if(j<SCORE2SIZE) {setNote(score2[0]);} else {j=0;}
- }
- j++;
- }
- counter++;
- }*/
- if (pta2_val) {
- if (pta2_pushing == 0) {
- pta2_pushing = 1; //押下モードに移行
- }
- } else {
- if (pta2_pushing == 1) { //おしてたら
- pta2_pushing = 0;
- i = 0; j = 0; restflag = 0;
- TPM0_SC &= ~TPM_SC_CMOD(0b11); // Stop TPM0 (Set CMOD to 0)
- TPM1_SC &= ~TPM_SC_CMOD(0b11); // Stop TPM1 (Set CMOD to 0)
- state = 2;
- break;
- } else {
- pta2_pushing = 0;
- }
- }
- }
- break;
- case 2: // 演奏終了状態
- GPIOD_PCOR = (1 << 5);
- GPIOE_PSOR = (1 << 29);
- while(1){
- pta2_val = GPIOA_PDIR & (1 << 2) ? 1 : 0;
- if (pta2_val) {
- if (pta2_pushing == 0) {
- pta2_pushing = 1; //押下モードに移行
- }
- } else {
- if (pta2_pushing == 1) { //おしてたら
- pta2_pushing = 0;
- state = 1; // 離したらループ先頭に
- break;
- } else {
- pta2_pushing = 0;
- }
- }
- }
- break;
- default:
- break;
- }
- }
- /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
- /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
- #ifdef PEX_RTOS_START
- PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
- #endif
- /*** End of RTOS startup code. ***/
- /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
- for(;;){}
- /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
- } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
- /* END main */
- /*!
- ** @}
- */
- /*
- ** ###################################################################
- **
- ** This file was created by Processor Expert 10.5 [05.21]
- ** for the Freescale Kinetis series of microcontrollers.
- **
- ** ###################################################################
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement