⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex6-1.c

📁 < 嵌入式C语言程序设计>>一书的源代码
💻 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 + -