找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1568|回复: 0
收起左侧

C51单片机

[复制链接]
ID:271617 发表于 2018-1-4 20:57 | 显示全部楼层 |阅读模式
#include <reg51.h>
typedef unsigned char uchar;
typedef unsigned int uint;


#define BLANKCHAR 10         
#define PCHAR 11                  
#define OPENCHAR 12                  
#define ALARMCHAR 13         
#define LINECHAR 14                  
#define BACKKEY 0X0D         
#define ENTERKEY 0X0F         
#define LOCKKEY 0X0E         
#define NO_KEY 20                 



uchar code KEYCODE[] = {0XEE,0XDE,0XBE,0X7E,0XED,0XDD,0XBD,0X7D,0XEB,0XDB,0XBB,0X7B,0XE7,0XD7,0XB7,0X77};


uchar KeyPre;                          
uchar KeyUp;      

#define LEDPORT P0                  
#define LEDCON P1                  
#define KEYPORT P2                 

sbit ALARMCON = P3^3;     
sbit LOCKCON = P3^5;      

uchar code SEGCODE[] ={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90, 0XFF,0X8C,0X8F,0X88,0XBF,0X9f, };




uchar code BITCODE[6] = {0XC1,0XC2,0XC4,0XC8,0XD0,0XE0};
uchar DispBuf[6];                  
bit DispNormal;                          
uchar DispCnt;                          
#define SHORT_TIME 10         
#define LONG_TIME 100         
#define LONGER_TIME 9000  

bit AlarmEnable;         
uint AlarmTime;           

uchar code PassWord[] = {1,2,3,4,5,6};
uchar PassInBuf[5];      
uchar PassPosi;         
bit TimerBit;            
uchar SysMode;            
uchar ErrorCnt;           

void Delay(int z)
{
        uchar y;
        int x;
        for(x=z; x>0; x--)
                for(y=255; y>0; y--);
}


void Fill_Buf(uchar FillChar)
{
        uchar i;
        for (i=0; i<6; i++)
        {
                DispBuf[i] = FillChar;
                PassInBuf[i] = FillChar;
        }
}

void  Fill_Buf_P()
{
        Fill_Buf(BLANKCHAR);
        DispBuf[0] = PCHAR;
        LEDPORT = SEGCODE[PCHAR];
        LEDCON = BITCODE[5];

}

void  Fill_Buf_O()
{
        Fill_Buf(BLANKCHAR);
        DispBuf[0] = OPENCHAR;
        LEDPORT = SEGCODE[OPENCHAR];
        LEDCON = BITCODE[5];
}

void  Fill_Buf_A()
{
        Fill_Buf(BLANKCHAR);
        DispBuf[0] = ALARMCHAR;
        LEDPORT = SEGCODE[ALARMCHAR];
        LEDCON = BITCODE[5];

}


void  Disp_Led_Sin(uchar DispChar, uchar DispPosi)
{
        LEDPORT = SEGCODE[DispChar];//输出显示段码
        LEDCON = BITCODE[DispPosi];//输出显示位码
        Delay(500);
        LEDCON = 0X00;//关闭显示器
}


void Sys_Speaker(uint stime)
{
        AlarmEnable = 1;//允许报警
        AlarmTime = stime;//报警时间长短
}

/*********系统报警函数**********/
void Sys_Alarm()
{
        if (AlarmEnable == 1)  //允许报警
        {
                ALARMCON = 0;//报警
                AlarmTime--;
                if (AlarmTime == 0)        //停止报警时间到
                {
                        AlarmEnable = 0;
                        ALARMCON = 1;
                        if (SysMode == 1) //报警发生在模式1.要返回模式0
                        {
                                SysMode = 0;
                                Fill_Buf_P();//显示P
                        }               
                }

        }
}


uchar Find_Key()
{
        uchar KeyTOP, i;
        KEYPORT = 0XF0;//行线输出全0,列线输出全1
        KeyTOP = KEYPORT;//读按键端口值
        if(KeyTOP == 0XF0)
                return NO_KEY;
        KEYPORT = KeyTOP | 0X0F;//列线输出,行线输入
        KeyTOP = KEYPORT;
        for (i=0; i<16; i++)
        {
                if(KeyTOP == KEYCODE[i])//根据按键端口扫描值,查找按键值
                        return i;//返回按键值
                else if(i >= 15)
                        {        
                                i = NO_KEY;
                                return i;
                        }        
        }
}


uchar Scan_Key()
{
        uchar KeyTOP;
        KeyTOP = Find_Key();//接收按键检测的返回值
        if (KeyTOP != NO_KEY)
        {
                Delay(100);
                if (KeyTOP != NO_KEY)
                        KeyPre = KeyTOP;
                while(KeyTOP == Find_Key());
                return KeyPre;
        }
        else
                return NO_KEY;
}


void Key_Process(uchar Key)
{
        uchar i;
        if (Key == NO_KEY)
                return;//无按键,不处理
        switch(SysMode)
        {
                case 0://输入密码
                        switch(Key)
                        {
                                case 0:
                                case 1:
                                case 2:
                                case 3:
                                case 4:
                                case 5:
                                case 6:
                                case 7:
                                case 8:
                                case 9:
                                        Disp_Led_Sin(Key,PassPosi);
                                        PassInBuf[PassPosi] = Key;//保存用户输入的密码
                                        if (PassPosi<5)
                                                PassPosi++;//调整密码输入位置
                                        Sys_Speaker(SHORT_TIME);//发按键提示音
                                        break;
                                case 20:break;
                                case BACKKEY:
                                        DispBuf[PassPosi] =  BLANKCHAR;//显示空键
                                        PassInBuf[PassPosi] = BLANKCHAR;//清除当前位置的密码
                                        if (PassPosi>0)
                                        {
                                                PassPosi--;//调整显示位置
                                                Disp_Led_Sin(15,5);
                                        }
                                        Sys_Speaker(SHORT_TIME);//发按键提示音
                                        break;
                                case ENTERKEY:
                                        for (i=0; i<5; i++)//比较用户密码是否与预设密码一致
                                        {
                                                if (PassInBuf[i] != PassWord[i])
                                                        break;
                                        }
                                        if (i>=5)//输入密码正确
                                        {
                                                 Fill_Buf_O();//显示开锁状态
                                                 PassPosi = 0;
                                                 LOCKCON = 1;//开锁
                                                 ErrorCnt = 0;
                                                 Sys_Speaker(LONG_TIME);//发长提示音
                                                 SysMode = 2;//转模式2
                                        }
                                        else
                                        {
                                                 ErrorCnt++;
                                                 if(ErrorCnt>2)//超过3次
                                                 {
                                                         ErrorCnt = 0;
                                                        Fill_Buf_A();//显示报警状态
                                                        PassPosi = 0;
                                                        Sys_Speaker(LONGER_TIME);//发报警音
                                                        SysMode = 1;        
                                                 }
                                                 else //少于3次,重新输入
                                                 {
                                                          Fill_Buf_P();
                                                         PassPosi = 0;
                                                         Sys_Speaker(LONG_TIME);//发长提示音
                                                 }
                                        }
                                        break;
                                        case LOCKKEY://闭锁键
                                                Fill_Buf_P();
                                                PassPosi = 0;
                                                 Sys_Speaker(SHORT_TIME);//发短提示音
                                                break;
                        }
                        break;
                        case 2://开锁状态
                                if (Key == LOCKKEY)//用户按动闭锁按键
                                {
                                        Fill_Buf_P();
                                        SysMode = 0;
                                        LOCKCON = 0;//闭锁
                                        Sys_Speaker(SHORT_TIME);
                                }
                                break;
        }
}

void Init_Timer()
{
        TMOD &= 0XF0;
        TMOD |= 0X01;
        TR0 = 0;
        TH0 = (65536-20000) / 256;
        TL0 = (65536-20000) % 256;
        TR0 = 1;
        ET0 = 1;
}

void Timer0() interrupt 1
{        
        TR0 = 0;
        TH0 = (65536-20000) / 256;
        TL0 = (65536-20000) % 256;
        TR0 = 1;
        TimerBit = 1;//20ms定时时间到
}

void Init_System()
{
        PassPosi = 1;
        LOCKCON = 0; //闭锁
        Init_Timer();
        Fill_Buf_P();
        EA = 1;
}
void main()
{               
        uchar KeyTemp;
        Init_System();
        PassPosi = 0;
        while(1)
        {
                if(TimerBit == 1)
                {
                        Sys_Alarm();//报警函数
                        KeyTemp = Scan_Key();//按键扫描
                        Key_Process(KeyTemp);//按键处理
                        TimerBit = 0;
                }
        }
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表