密碼鎖已經編寫號,但有一個功能求助 我想實現這么一個功能:就是輸入密碼全是 * ,然后如果一直按下仿真中那個按鈕A,所有*號顯示成相應的數字,這個功能一直沒實現,求助應該如何c寫程序?
以下是我的仿真附件和代碼,望能幫忙說一下如何修改?
項目設計-密碼鎖.zip
(1.36 MB, 下載次數: 8)
2018-5-3 19:11 上傳
點擊文件名下載附件
I@7UOT8`)4B9CP4M7PRQN}P.png (121.94 KB, 下載次數: 47)
下載附件
2018-5-3 19:12 上傳
#include <REG52.h>
#include<intrins.h>
sbit K1=P1^2;
sbit ALAM = P2^5; //報警
sbit open_led=P2^3; //開鎖指示燈
/*LCD接口定義*/
sbit LcdRS = P2^0; //lcd數據/命令選擇端 數據1命令0
sbit LcdRW = P2^1; //lcd讀/寫選擇端 讀1寫0
sbit LcdEn = P2^2; //lcd使能控制端 1有效
sfr LcdIO = 0x80; //lcd數據接口 P0=0x80
unsigned char code a[]={0xFE,0xFD,0xFB,0xF7}; //控盤掃描控制表
unsigned char countt0,second; //t0中斷計數器,秒計數器
unsigned char code start_line[] = {"password: "};
unsigned char code name[] = {"===Coded Lock==="}; //顯示名稱
unsigned char code Error[] = {" error "}; //輸入錯誤
unsigned char code codepass[] = {" pass "};
unsigned char code LockOpen[] = {" open "}; //OPEN
char InputData[6]; //輸入密碼暫存區
unsigned char CurrentPassword[6]={6,5,4,3,2,1}; //當前密碼值
unsigned char N=0; //密碼輸入位數記數
unsigned char ErrorCont; //錯誤次數計數
unsigned char KEY_SCAN,NUM;
/****向LCD寫入命令或數據部分****/
#define LCD_COMMAND 0 // 輸出指令
#define LCD_DATA 1 // 輸出數據
#define LCD_CLEAR_SCREEN 0x01 // 清屏指令
#define LCD_HOME 0x02 // 光標返回原點指令
//=====================16us短延時==============================
void Delay_short(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)
{;}
}
//=====================長延時==============================
void Delay_long(unsigned char N)
{
unsigned char i;
unsigned int j;
for(i=0;i<N;i++)
{
for(j=0;j<315;j++) //一個循環16us,共5ms
{;}
}
}
//=====================5ms延時==============================
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//===================400ms延時==============================
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
}
}
/*寫LCD子程序 */
/*入口參數:數據style=1 指令, style=0 input:寫入的內容*/
void LCD_Write(bit style, unsigned char input)
{
LcdRS=style; //數據style=1 指令style=0
LcdRW=0; //寫
LcdIO=input; //P0口輸出
Delay_short(10); //延時
LcdEn=1; //lcd使能
Delay_short(10); //延時
LcdEn=0; //停止
}
/****初始化LCD程序****/
void LCD_Initial()
{
Delay_long(6); //延遲5*6=30ms
LCD_Write(LCD_COMMAND,0x38); //8位數據端口,2行顯示,5*7點陣
LCD_Write(LCD_COMMAND,0x38);
LCD_Write(LCD_COMMAND,0x38); //發送三遍
Delay_short(2); //延遲大于39us
LCD_Write(LCD_COMMAND,0x0c); //顯示模式設置:開啟顯示, 無光標 0x0c
Delay_short(2); //延遲大于39us
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏 0x01
Delay_short(100); //延遲大于1.53ms
LCD_Write(LCD_COMMAND,0x06); //輸入模式設置:AC遞增, 畫面不動 0x06
}
/*液晶字符輸入的位置定位程序*/
/*入口參數:x范圍:0-15 y范圍:1,2*/
void GotoXY(unsigned char x, unsigned char y)
{
unsigned char address;
if(y==1)
{
address=0x80+x; //y=1顯示在第一行
}
else
{
address=0xc0+x; //y=2顯示在第二行
}
LCD_Write(LCD_COMMAND, address);
}
/*將字符串輸出到液晶顯示函數*/
/*入口參數:字符串指針 */
void Print(unsigned char *str)
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
//*********************************************************************
//==============將按鍵值編碼為數值=========================
unsigned char coding(unsigned char m)
{
unsigned char k;
switch(m)
{
// case (0x18): k=3;break;
// case (0x28): k=7;break;
// case (0x48): k='#';break;
// case (0x88): k='D';break;
case (0x14): k=3;break;
case (0x24): k=6;break;
case (0x44): k=9;break;
case (0x84): k='#';break;
case (0x12): k=2;break;
case (0x22): k=5;break;
case (0x42): k=8;break;
case (0x82): k=0;break;
case (0x11): k=1;break;
case (0x21): k=4;break;
case (0x41): k=7;break;
case (0x81): k='*';break;
}
return(k);
}
//=====================按鍵檢測并返回按鍵值===============================
unsigned char keynum(void)
{
unsigned char row,col,i;
P3=0xf0;
if((P3&0xf0)!=0xf0)
{
Delay5Ms();
Delay5Ms();
if((P3&0xf0)!=0xf0)
{
row=P3^0xf0; //確定行線
i=0;
P3=a; //精確定位
while(i<4)
{
if((P3&0xf0)!=0xf0)
{
col=~(P3&0xff); //確定列線
break; //已定位后提前退出
}
else
{
i++;
P3=a;
}
}
}
else
{
return 0xff;
}
while((P3&0xf0)!=0xf0);
return (row|col); //行線與列線組合后返回
}
else
{
return 0xff; //無鍵按下時返回0xff
}
}
//***************************************************************************************/
//=======================一聲提示音,表示有效輸入========================
void OneAlam(void)
{
unsigned char y;
for(y=0;y<30;y++)
{
ALAM=0;
Delay_short(50);
ALAM=1;
Delay_short(50);
}
}
//========================二聲提示音,表示操作成功========================
void TwoAlam(void)
{
OneAlam();
Delay5Ms();
ALAM=1;
Delay5Ms();
OneAlam();
Delay5Ms();
ALAM=1;
}
//========================三聲提示音,表示錯誤========================
void ThreeAlam(void)
{
OneAlam();
Delay5Ms();
ALAM=1;
Delay5Ms();
OneAlam();
Delay5Ms();
ALAM=1;
Delay5Ms();
OneAlam();
Delay5Ms();
ALAM=1;
}
//=======================輸入密碼錯誤超過三過,報警并鎖死鍵盤======================
void Alam_KeyUnable(void)
{
P3=0x00;
{
OneAlam();
Delay5Ms();
ALAM=1;
Delay5Ms();
}
}
//=======================取消所有操作============================================
void Cancel(void)
{
unsigned char i;
GotoXY(0,2);
Print(start_line);
TwoAlam(); //提示音
for(i=0;i<6;i++)
{
InputData=0;
}
ALAM=1; //報警關
ErrorCont=0; //密碼錯誤輸入次數清零
open_led=1; //指示燈關閉
N=0; //輸入位數計數器清零
}
//==========================確認鍵,并通過相應標志位執行相應功能===============================
void Ensure(void)
{
unsigned char i,j;
for(i=0;i<6;)
{
if(CurrentPassword==InputData)
{
i++;
}
else
{
ErrorCont++;
if(ErrorCont==3) //錯誤輸入計數達三次時,報警并鎖定鍵盤
{
GotoXY(0,2);
Print(" KeypadLocked! ");
TR0=1;
do
Alam_KeyUnable();
while(TR0);
return ;
}
break;
}
}
if(i==6) //密碼正確輸入
{
GotoXY(0,2);
Print(codepass);
Delay400Ms();
Delay400Ms();
GotoXY(0,2);
Print(LockOpen);
TwoAlam(); //操作成功提示音
//KEY_CLOCK=0; //開鎖
//pass=1; //置正確標志位
open_led=0; //開鎖指示燈亮
for(j=0;j<6;j++) //將輸入清除
{
InputData=0;
}
while(1);
}
else
{
GotoXY(0,2);
Print(Error);
ThreeAlam(); //錯誤提示音
Delay400Ms();
GotoXY(0,2);
Print(start_line);
for(j=0;j<6;j++) //將輸入清除
{
InputData=0;
}
}
N=0; //將輸入數據計數器清零,為下一次輸入作準備
}
void test_led()
{
while(1)
{
open_led=0;
Delay400Ms();
open_led=1;
Delay400Ms();
}
}
void test_alarm()
{
while(1)
{
ALAM=1;
Delay_short(60);
ALAM=0;
Delay_short(60);
}
}
void timer_init()
{
TMOD=0x11;
TL0=0xB0;
TH0=0x3C;
EA=1;
ET0=1;
TR0=0;
}
void test_key()
{
unsigned char code ascii[]={"0123456789ABCDEF"};
KEY_SCAN=keynum();
if(KEY_SCAN!=0xff)
{
GotoXY(0,1);
Print("key_code:0x");
LCD_Write(LCD_DATA, ascii[KEY_SCAN/16]);
LCD_Write(LCD_DATA, ascii[KEY_SCAN%16]);
}
}
//==============================主函數===============================
void main(void)
{
unsigned char j;
// test_led();
// test_alarm();
Delay400Ms(); //啟動等待,等LCM講入工作狀態
LCD_Initial(); //LCD初始化
// while(1)
// {
// test_key();
// }
GotoXY(0,1);//日歷顯示固定符號從第一行第0個位置之后開始顯示
Print(name);//向液晶屏寫日歷顯示的固定符號部分
GotoXY(0,2);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
Print(start_line);//寫顯示時間固定符號,兩個冒號
GotoXY(9,2); //設置光標位置
LCD_Write(LCD_COMMAND,0x0f); //設置光標為閃爍
// while(1);
P3=0xFF;
timer_init();
Delay5Ms(); //延時片刻(可不要)
N=0; //初始化數據輸入位數
while(1)
{
if (!TR0)
{
KEY_SCAN=keynum();
}
else
{
KEY_SCAN = 0xff;
}
if(KEY_SCAN!=0xff)
{
NUM=coding(KEY_SCAN);
switch(NUM)
{
case 'A': ; break;
case 'B': ; break;
case 'C': ; break;
case 'D': ; break;
case '*': Cancel(); break; //取消當前輸入
case '#': Ensure(); break; //確認鍵,
default:
{
if(N<6) //當輸入的密碼少于6位時,接受輸入并保存,大于6位時則無效。
{ unsigned char temp;
OneAlam(); //按鍵提示音
for(j=N;j<=N;j++)
{
GotoXY(9+j,2);
LCD_Write(LCD_DATA,'*');
}
if(K1==0)
{
GotoXY(9+N,2);
temp=NUM+0x30 ;
LCD_Write(LCD_DATA,temp);
}
InputData[N]=NUM;
N++;
}
else //輸入數據位數大于6后,忽略輸入
{
N=6;
}
break;
}
}
}
}
}
//*********************************中斷服務函數**************************************
void time0_int(void) interrupt 1
{
TL0=0xB0;
TH0=0x3C;
countt0++;
if(countt0==20)
{
countt0=0;
second++;
if(second==10)
{
P3=0xf0;
TL0=0xB0;
TH0=0x3C;
second=0;
ErrorCont=0; //密碼錯誤輸入次數清零
GotoXY(0,2);
Print(start_line);
TR0=0; //關定時器
}
}
}
|