チーム156A
課題名
パスワード認証
研究者名
Akiteru Handa
Shogo Maeda
Takanori Sakamoto
概要
3つの数字の入力による、パスワード認証ゲームである。
認証が成功すると"Success!"、失敗すると"Error..."を表示する。
4096(16x16x16)通りの数字の組み合わせで様々なパスワードを設定できる。
設定の仕方は"###"と"#"を三回入力することで設定モードに進むことができる。
この時、"Setting Mode"と表示されるので続けて3つ数字を入力し、設定する。
入力した数値でよいときは"1"、変更したくないときは"0"を入力する。
使用装置
PSoCEval1
LCD
PSoC MiniProg
MatrixKeypad
ソースコード
ソース・・
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>
/*****************Variables***************************/
/* LUT for storing keys. The size of the LUT should be equal to 2 ^ (NUMBER OF ROWS + COLUMNS).
Row and column information from Scanning function is used as index to this LUT for finding the key.
Value 0x20 indicates invalid key. */
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', '5', 0x20, '9', 0x20, 0x20, 0x20,
'D', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*2*/0x20, '2', '6', 0x20, 'A', 0x20, 0x20, 0x20,
'*', 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', '7', 0x20, 'B', 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, '4', '8', 0x20, 'C', 0x20, 0x20, 0x20,
'0', 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};
/*****************************************************/
/****************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 main(void)
{
char sel[3]; char num[3]; char sel2[1]; int count; int count1; int s; int i; num[0] = rand() % 10 + '0'; num[1] = rand() % 10 + '0'; num[2] = rand() % 10 + '0'; sel[0] = '0'; sel[1] = '0'; sel[2] = '0'; sel2[0] = '9'; count = 0; count1 = 0; s = 0; i=0; /* Initialize variables and user modules */ InitModules(); /* Enable Global Interrupt */ M8C_EnableGInt; while(1) { /* Check the Keypad status and update on LCD if any key is pressed */
if(key[0] != 0x20) { if(count1 == 5){ for(i=0;i<3;i++){ LCD_1_Position(0,13+i); LCD_1_PrString(&num[i]); } } /* Valid key */ /* Set LCD cursor position */ LCD_1_Position(0, 7+count); /* Display pressed keypad button */ LCD_1_PrString((char *)key); if(count == 0){ LCD_1_PrCString(" "); } LCD_1_Position(1,0); LCD_1_PrCString(" "); if(s == 2){ sel2[0] = *key; } else{ sel[count] = *key; } count++; /* Invalidate key */ key[0]=0x20; } if(count == 3){ if(sel[0] == num[0] && sel[1] == num[1] && sel[2] == num[2] && s == 0){ LCD_1_Position(1, 7); LCD_1_Position(1,0); LCD_1_PrCString("Success!!"); break; } else{ count = 0; LCD_1_Position(1,0); LCD_1_PrCString("Error..."); count1++; } if(s == 1){ s = 2; count = 2; LCD_1_Position(1,0); LCD_1_PrCString("Yes(1) No(0)"); } if(s == 2 && sel2[0] == '1'){ LCD_1_Position(0,7); LCD_1_PrCString(" "); for(i=0;i<3;i++) num[i]=sel[i]; LCD_1_Position(1,0); LCD_1_PrCString("Changing"); sel2[0] = '9'; count1 = 0; s = 0; LCD_1_Position(0,13); LCD_1_PrCString(" "); } if(s == 2 && sel2[0] == '0'){ LCD_1_Position(0,7); LCD_1_PrCString(" "); LCD_1_Position(1,0); LCD_1_PrCString("Steady"); sel2[0] = '9'; s = 0; count1 = 0; LCD_1_Position(0,13); LCD_1_PrCString(" "); } if(sel[0] == '#' && sel[1] == '#' && sel[2] == '#'){ LCD_1_Position(1,0); LCD_1_PrCString("Setting Mode"); count = 0; s = 1; } } }
}
/* 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("Number:"); /* 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 ---4----3----2----1
| | | |
p0.1 ---8----7----6----5
| | | |
p0.2 ---C----B----A----9
| | | |
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;
}
考察
matrix keypadの使い方がわからず、LCDに押したボタンの値を出力するだけでもとても時間がかかった。原因として、押したボタンの信号を数値として制御することがプログラムでできなかったためと思われる。追加したかった要素として5回以上間違えると、matrix keypadにもともと実装されていたチャタリング用のタイマーを使って、入力そのものを1分間ロックする機能(スマホのロック機能のようなもの)があったがうまくいかなかった。また、正解だった場合に正解音を出したかったが、表示される文字がおかしくなったことと時間が足りなかったこともあり、断念した。
- 最終更新:2015-12-22 16:56:40