チーム1655
課題名
PASSWORD
研究者名
2-14-26 Yasuyuki Kobayashi
2-14-36 Takahito Suzuki
概要
4ケタの数字によるパスワードを設定できる。
認証成功すると"Cancellation!!"、失敗すると"Failure"とLCDに表示される。
5回失敗すると"Too Wrong"と表示され、入力を受け付けなくなる。
"####"と入力するとパスワード設定モードに移行でき、"####"以外の任意の4ケタのパスワードに変更可能。
数値の入力にはMatrixKeypadを使用。
使用機器
- PSoC本体 1台
- LCD 1個
- PSoC MiniProg 1個
- MatrixKeypad 1個
設計
ソースコード
#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,
'E', 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[4]; char num[4]; char sel2; int count; int count1; int s; int i; num[0] = rand() % 10 + '0'; num[1] = rand() % 10 + '0'; num[2] = rand() % 10 + '0'; num[3] = rand() % 10 + '0'; sel[0] = '0'; sel[1] = '0'; sel[2] = '0'; sel[3] = '0'; sel2 = '9'; count = 0; count1 = 0; s = 0; i=0; InitModules(); M8C_EnableGInt; while(1) {
if(key[0] != 0x20) { if(count1 == 5){ LCD_1_Position(1,0); LCD_1_PrCString("Too wrong!!"); break; } LCD_1_Position(0, 10+count); LCD_1_PrString((char *)key); if(count == 0){ LCD_1_PrCString(" "); } LCD_1_Position(1,0); LCD_1_PrCString(" "); if(s == 2){ sel2 = *key; } else{ sel[count] = *key; } count++; key[0]=0x20; } if(count == 4){ if(sel[0] == num[0] && sel[1] == num[1] && sel[2] == num[2] && sel[3] == num[3] && s == 0){ LCD_1_Position(1, 7); LCD_1_Position(1,0); LCD_1_PrCString("Cancellation!!"); break; } else{ count = 0; LCD_1_Position(1,0); LCD_1_PrCString("Failure"); count1++; } if(s == 1){ s = 2; count = 3; LCD_1_Position(1,0); LCD_1_PrCString("Yes(1) No(0)"); } if(s == 2 && sel2 == '1'){ LCD_1_Position(0,10); LCD_1_PrCString(" "); for(i=0;i<4;i++) num[i]=sel[i]; LCD_1_Position(1,0); LCD_1_PrCString("Password changed"); sel2 = '9'; count1 = 0; s = 0; LCD_1_Position(0,10); LCD_1_PrCString(" "); } if(s == 2 && sel2 == '0'){ LCD_1_Position(0,10); LCD_1_PrCString(" "); LCD_1_Position(1,0); LCD_1_PrCString("Did not change"); sel2 = '9'; s = 0; count1 = 0; LCD_1_Position(0,10); LCD_1_PrCString(" "); } if(sel[0] == '#' && sel[1] == '#' && sel[2] == '#' && sel[3] == '#'){ LCD_1_Position(1,0); LCD_1_PrCString("Password setting"); count = 0; count1 = 0; s = 1; } } }
}
void InitModules(void)
{
LCD_1_Start(); LCD_1_Position(0,0); LCD_1_PrCString("Password:"); Timer16_1_WritePeriod(320); Timer16_1_EnableInt(); INT_MSK0|=0x20; 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----#----E----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;
}
考察
MatrixKeypadの使い方が難しく、苦労した。入力を一定回数間違えると入力を受け付けなくなる機能を実装したが、当初はこれを時間制御して、一定時間入力を受け付けなくする機能を作るつもりだった。しかし、Keypad内にあるタイマー機能の使い方が分からず、時間もなかったので断念。初期のパスワードを乱数で4ケタ用意してこれを当てるゲームを作るつもりで、ヒントをLCD内に表示する機能をつけるつもりだったが、4ケタでは数が多すぎて出来なかった。なぜか"A"が反応しにくいが原因は分からず…パスワード設定画面で1でも0でもない数字を押すと設定画面に戻れなくなってしまうがこれも解消出来なかった。
MatrixKeypadを二つ使うことを目指していたが、他のportへの割り振りが出来ず、苦戦したためあきらめた。
- 最終更新:2016-11-22 16:33:34