?? ex6-1.c
字號:
/*
標題:范例 6-1
版本:1.0
Target:89S51
程序描述: 這個范例說明如何使用8051, LCD顯示器和4ⅹ4的小鍵盤,制作一個密碼鎖。PORT 1 連接到LCD顯示器的數據線。PORT 3 的P3.3,P3.4和P3.5分別連接到LCD顯示器的控制線。PORT 2連接到4ⅹ4的小鍵盤,可以輸入密碼。執行修改密碼或是時間的程序時,首先讓LCD顯示器顯示出時間和日期。
當用戶按下4ⅹ4小鍵盤的按鈕 A 時,可以輸入密碼。如果密碼正確時,就會讓 P3.6的 LED 閃爍,表示打開鎖。如果密碼不正確時,LCD顯示器就會顯示出
"PASSWORD WRONG"。
當用戶按下4ⅹ4小鍵盤的按鈕 B時,可以修改時間。
當用戶按下4ⅹ4小鍵盤的按鈕 C時,可以修改密碼。*/
/* ***************************************************** */
#include <REGX51.H>
#include <lcd.h>
#define XTAL 11059200
#define TIMER0_COUNT 0xD8F0 /* 10000h-(12,000,000/(12*100)) *
/
/* 數字時鐘的工作模式 */
#define DEFAULT 0
#define UNLOCK 1
#define INPUT_PASSWORD 10
#define SET_TIME 11
#define SET_PASSWORD 12
#define TRUE 1
#define FALSE 0
#define putchar write_LCD_data
#define LOCK P3_7
//
typedef struct {
char hour;
char minute;
char second;
} time;
typedef struct {
char year;
char month;
char day;
} date;
time now={23,59,0},display;
date today={04,12,15},tmpday;
static unsigned timer0_tick=100,mode=0,operation;
char code dayofmonth[]={31,28,31,30,31,30,31,31,30,31,30,31};
char code
weekday[7][4]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
char code int2char[]="0123456789ABCDEF";
unsigned char password[4]={1,2,3,4};
unsigned char code always[4]={1,2,2,7};
char code prompt[]="Input Password:";
char code old_password[]="Old Password:";
char code new_password[]="New Password:";
char code confirm[]="Confirm Again:";
unsigned char guess[4]={0,0,0,0};
unsigned char temp[4]={0,0,0,0};
unsigned char txOK,c,unlock=0,address;
char gotkey();
unsigned char read_byte(int);
void write_byte(int,unsigned char);
void write_LCD_data(unsigned);
void display_time(void)
{
gotoxy(1,0);
display_LCD_number(display.hour);
display_LCD_string(":");
display_LCD_number(display.minute);
display_LCD_string(":");
display_LCD_number(display.second);
}
void display_date()
{
char i,days=4;
gotoxy(2,2);
display_LCD_number(today.year);
display_LCD_string("/");
display_LCD_number(today.month);
display_LCD_string("/");
display_LCD_number(today.day);
display_LCD_string(" ");
if(today.month > 1)
for(i=0;i<=today.month-2;i++)
days+=(dayofmonth[i]%7);
if( today.year !=0 ) days+=((today.year-1)/4)+today.year+1;
if (today.year%4==0 && today.month >2) days++;
days=(days+today.day) % 7;
display_LCD_string(&weekday[days][0]);
}
int getdigit(unsigned char x,unsigned char y)
{
char keys;
do {
gotoxy(x,y);
putchar('_');
keys=gotkey();
gotoxy(x,y);
putchar(int2char[keys]);
} while(keys>9);
return(keys);
}
int getsecret(unsigned char x,unsigned char y)
{
char keys;
do {
gotoxy(x,y);
putchar('_');
keys=gotkey();
gotoxy(x,y);
putchar('*');
} while(keys>9);
return(keys);
}
void get_password()
{
char i;
for(i=0;i<4;i++)
guess[i]=getsecret(2,i);
}
int check_password()
{
char i;
i=0;
while ((guess[i]==always[i]) && (i < 4)) i++;
if (i==4)return(TRUE);
while ((guess[i]==password[i]) && (i < 4)) i++;
if (i==4)return(TRUE);
else return(FALSE);
}
int input_new_password()
{
unsigned char i,j;
clear_LCD();
gotoxy(1,0);
display_LCD_string(new_password);
for(i=0;i<4;i++)
temp[i]=getsecret(2,i);
clear_LCD();
gotoxy(1,0);
display_LCD_string(confirm);
for(i=0;i<4;i++)
guess[i]=getsecret(2,i);
i=0;
while ((guess[i]==temp[i]) && (i < 4)) i++;
if (i==4) {
for(j=0;j<4;j++) {
password[j]=temp[j];
write_byte(j,password[j] );
}
return(TRUE);
}
else return(FALSE);
}
int gettime()
{
char temp;
do {
while((temp=getdigit(1,0))>2); //時的十位數不能大于2
temp=temp*10+getdigit(1,1);
if (temp > 23) display_time();
} while (temp > 23);
display.hour=temp;
while((temp=getdigit(1,3))>5);
display.minute=temp*10+getdigit(1,4);
return(TRUE);
}
char monthday(char year,char month)
{
if(month==2 && year%4==0) //潤年的2月有29天
return(29);
else
return(dayofmonth[month-1]); //非閏年時的該月份天數
}
int getdate()
{
char temp,days;
temp=getdigit(2,2);
tmpday.year=temp*10+getdigit(2,3);
do {
while((temp=getdigit(2,5))>1); //月的十位數不能大于1
temp=temp*10+getdigit(2,6);
if (temp > 12) display_date(); //月份的數字不能大于12
} while (temp > 12);
tmpday.month=temp;
do {
while((temp=getdigit(2,8))>3); //日的十位數不能大于3
temp=temp*10+getdigit(2,9);
days=monthday(tmpday.year,tmpday.month);
if(temp > days || temp==0) display_date();
//如果輸入的日期大于該月份的日期就重新輸入
} while (temp > days || temp==0);
tmpday.day=temp;
return(TRUE);
}
static void timer0_isr(void) interrupt TF0_VECTOR using 1
{
TR0=0;
TL0=(TIMER0_COUNT & 0x00FF);
TH0=(TIMER0_COUNT >> 8);
TR0=1;
if(--timer0_tick) return;
timer0_tick=100;
if(unlock==1) P3_5=!P3_5;
now.second++; //秒加1
if (now.second==60) { //如果秒等于60
now.second=0; //秒恢復為0
now.minute++; //分加1
if (now.minute==60) { //如果分等于60
now.minute=0; //分恢復為0
now.hour++; //時加1
if (now.hour==24) { //如果時等于24
now.hour=0; //時恢復為0
today.day++; //日加1
//如果日超過當月最大日數,就變成1
if (today.day>monthday(today.year,today.month)) {
today.day=1;
today.month++; //月加1
if(today.month==13) { //如果月等于13
today.month=1; //月恢復為1
today.year++; //年加1
}
}
if(operation==DEFAULT)display_date();
}
}
}
if (operation==SET_TIME ) return;
display=now;
if(operation==DEFAULT) display_time();
}
static void timer0_initialize(void)
{
EA=0;
TR0=0;
TMOD &= 0XF0;
TMOD |=0x01;
TL0=(TIMER0_COUNT & 0x00FF);
TH0=(TIMER0_COUNT >> 8);
PT0=0;
ET0=1;
TR0=1;
EA=1;
}
void main (void) {
char keys;
int i;
LOCK=1;
txOK=1;
init_LCD();
clear_LCD();
gotoxy(2,0);
display_LCD_string("20");
display=now;
display_time();
display_date();
EA=1;
timer0_initialize();
IT0=1;
EX0=1;
read_byte(0);
gotoxy(1,8);
for(i=0;i<4;i++)
password[i]=read_byte(i);
do {
keys=gotkey();
switch (keys) {
case SET_TIME :
operation=SET_TIME;
if ( gettime()) now=display;
if ( getdate()) {
today=tmpday;
display_date();
}
operation=0;
break;
case INPUT_PASSWORD :
clear_LCD();
gotoxy(1,0);
display_LCD_string(prompt);
operation=INPUT_PASSWORD;
get_password();
clear_LCD();
gotoxy(1,10);
if ( check_password() )
{
LOCK=0;
display_LCD_string("Right");
}
else
display_LCD_string("Wrong");
operation=0;
gotoxy(2,0);
display_LCD_string("20");
display_time();
display_date();
break;
case SET_PASSWORD :
clear_LCD();
gotoxy(1,0);
display_LCD_string(old_password);
operation=SET_PASSWORD;
get_password();
if ( check_password() )
if( input_new_password() ){
clear_LCD();
gotoxy(1,10);
display_LCD_string("OK");
}
else {
clear_LCD();
gotoxy(1,10);
display_LCD_string("Fail");
}
else clear_LCD();
operation=0;
gotoxy(2,0);
display_LCD_string("20");
display_time();
display_date();
break;
}
} while(1);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -