找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1530|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

電子密碼鎖設(shè)計(jì)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:315926 發(fā)表于 2018-4-25 09:06 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
/*****************************************************************************
**                         電子密碼鎖設(shè)計(jì)
**文件名稱:main.c
**by 追夢(mèng)2011-5-12
**功能:支持3~20位的密碼設(shè)置,初始密碼為123456;若要重設(shè)密碼,需先輸入正確密碼開鎖。
**      正常顯示情況下,按下確認(rèn)鍵上鎖;按下密碼鍵,開始輸入密碼。
**接線:PE[0..3]----4*4鍵盤的行線,均用中斷方式,上拉輸入,下降沿觸發(fā)
**     PE[4..7]----4*4鍵盤的列線,下拉輸入,在中斷內(nèi)臨時(shí)改為上拉輸入,用于讀鍵值
**     PD[0..7]----LCD12864  D0~D7
**     PD[13..15]--LCD12864  RS,RW,E
**      PA.1 連接繼電器,低電平時(shí)合上,高電平時(shí)斷開相當(dāng)于開鎖與上鎖
*****************************************************************************/
#include "stm32f10x.h"
#include "LCD12864.h"
extern __IO uint16_t keyval;
extern __IO uint16_t keyflag;
uint16_t password[21]={1,2,3,4,5,6,'
};  //初始密碼為123456
uint16_t passwordtmp[21];
#define OPEN_DOOR GPIOA->BRR  = GPIO_Pin_1
#define CLOSE_DOOR GPIOA->BSRR = GPIO_Pin_1
//數(shù)組中存放各個(gè)備份數(shù)據(jù)寄存器基于BKP基地址的偏移地址,用于存儲(chǔ)密碼
uint16_t BKPDataReg[21] =
  {
    BKP_DR2,  BKP_DR3, BKP_DR4,  BKP_DR5,  BKP_DR6, BKP_DR7, BKP_DR8, BKP_DR9,
        BKP_DR10,BKP_DR11, BKP_DR12, BKP_DR13, BKP_DR14, BKP_DR15,BKP_DR16,BKP_DR17,
        BKP_DR18,BKP_DR19, BKP_DR20, BKP_DR21, BKP_DR22
  };
/**
  * 寫密碼到備份寄存器,掉電不丟失,電源復(fù)位不丟失
  */
void WritePasswordToBackupReg(uint16_t passwordarray[])
{
  uint32_t index = 0;
  /* 使能寫入BKP */
PWR_BackupAccessCmd(ENABLE);
  /* 清除事件掛起位 pin Event(TE) */
  BKP_ClearFlag();
  for (index = 0;passwordarray[index]!='
; index++)
  {                                                        //偏移地址    數(shù)據(jù)
    BKP_WriteBackupRegister(BKPDataReg[index],passwordarray[index]);
  }
BKP_WriteBackupRegister(BKPDataReg[index], passwordarray[index]); //寫入密碼結(jié)尾符  
}
/**
  * 上電或復(fù)位后讀出備份區(qū)里保存的密碼
  */
void Load_Password(void)
{
    uint32_t index =0;
   for(index = 0; BKP_ReadBackupRegister(BKPDataReg[index])!='
; index++)
   {                                                      
     password[index]=BKP_ReadBackupRegister(BKPDataReg[index]);
   }
   password[index]='
;        
}
/*************************************************************
**時(shí)鐘配置函數(shù)  系統(tǒng)時(shí)鐘為72MHz
*************************************************************/
void RCC_Configuration()
{
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC|\
                           RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE,ENABLE);//使能所有GPIO的時(shí)鐘
}
//GPIO配置函數(shù)
void GPIO_Configuration(void)
{
  GPIO_InitTypeDefGPIO_InitStructure;//定義GPIO的模式設(shè)置結(jié)構(gòu)體變量
  // PA1 接繼電器 模擬開鎖功能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  
  GPIO_Init(GPIOA,&GPIO_InitStructure);
  CLOSE_DOOR; // 初始鎖上
}
// 矩陣鍵盤接口配置
void KeyBoard_Config(void)
{
       GPIO_InitTypeDef GPIO_InitStructure;
        // 行線上拉輸入
       GPIO_InitStructure.GPIO_Pin = 0x000f;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(GPIOE, &GPIO_InitStructure);
        // 列線下拉輸入
       GPIO_InitStructure.GPIO_Pin = 0x00f0;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
       GPIO_Init(GPIOE, &GPIO_InitStructure);
}
// 列線轉(zhuǎn)換為浮空輸入
void KeyBoard_Conv(uint16_t GPIO_Pin)
{
    GPIO_InitTypeDefGPIO_InitStructure;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(GPIOE, &GPIO_InitStructure);
        // 列線浮空輸入
       GPIO_InitStructure.GPIO_Pin = 0x00f0;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(GPIOE, &GPIO_InitStructure);
}
/********************************************************************
*   : EXTI_Configuration
*   能:外部中斷配置函數(shù)
*   明:PE.0~PE.3 鍵盤中斷
*********************************************************************/
void EXTI_Configuration(void)
{
  EXTI_InitTypeDefEXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);         //復(fù)用功能使能
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource1);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);
EXTI_ClearITPendingBit(EXTI_Line0); //清除掛起/請(qǐng)求標(biāo)志
EXTI_ClearITPendingBit(EXTI_Line1); //清除掛起/請(qǐng)求標(biāo)志
EXTI_ClearITPendingBit(EXTI_Line2);
EXTI_ClearITPendingBit(EXTI_Line3);
  // PE.0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中斷模式
  EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
  // PE.1
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中斷模式
  EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
  // PE.2
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中斷模式
  EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
  // PE.3
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中斷模式
  EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/********************************************************************
*   : NVIC_Configuration
*   能:中斷配置
*   明:PE.0~PE.3 鍵盤中斷,均為下降沿觸發(fā)
*********************************************************************/
void NVIC_Configuration(void)
{
  NVIC_InitTypeDefNVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  // PE.0
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
  // PE.1
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
  // PE.2
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&NVIC_InitStructure);
  // PE.3
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_Init(&NVIC_InitStructure);
}
//延時(shí)nus
void delay_nus(unsigned long n)
{
        unsigned longj;
        while(n--)
        { j=15;
          while(j--);
        }
}
//延時(shí)nms
void delay_nms(unsigned long n)
{
        while(n--)
          delay_nus(1075);
}
/********************************************************************
*   : Change_Password
*   能:更改密碼
*   明:直到新密碼設(shè)定完成才退出此函數(shù)
*********************************************************************/
void Change_Password(void)
{
        uint16_ti,index=0;
        uint16_tflag=0;
        uint16_tpasswordtmp2[21]={'
};
        LCD_Clear();
        delay_nms(2);
        for(i=0;i<21;i++)
          passwordtmp = '
;
       LCD_Setpos_DispString(1,1,"請(qǐng)輸入新密碼:");
        delay_nms(2);
       LCD_Setpos(2,1);
        delay_nms(1);
        while(1)
        {
               keyflag = 0;
               while(keyflag < 1)
                { }
               keyflag = 0;
               if(keyval<=9)
                {
                 LCD_DispChar(keyval+'0');
                 delay_nms(1);
                 if(flag==0)
                    passwordtmp[index++] = keyval;
              elsepasswordtmp2[index++] = keyval;
                }
                elseif((keyval == 'e')&&(flag == 0))
                {
                   passwordtmp[index] = '
;
                       LCD_Clear();
                        delay_nms(1);
                       LCD_Setpos_DispString(1,1,"請(qǐng)?jiān)俅屋斎胄旅艽a");
                       delay_nms(2);
                       LCD_Setpos(2,1);
               delay_nms(1);
                       flag  = 1;
                       index = 0;
                }
                elseif((keyval == 'e')&&(flag == 1))
                {
                       for(i=0;passwordtmp!='
;i++)
                       {
                               if(passwordtmp != passwordtmp2)
                                {
                                       LCD_Clear();
                                       delay_nms(1);
                                       LCD_Setpos_DispString(1,1,"兩次輸入密碼不同");
                                        delay_nms(2);
                                       LCD_Setpos_DispString(2,1,"請(qǐng)重新設(shè)定密碼!");
                                       delay_nms(1000);
                                       LCD_Clear();
                                        delay_nms(1);
                                       LCD_Setpos_DispString(1,1,"請(qǐng)?jiān)俅屋斎胄旅艽a");
                                       delay_nms(2);
                                       LCD_Setpos(2,1);
                                delay_nms(1);
                                       flag  = 0;
                                        index =0;
                                        break;
                                }
                       }
                       if(passwordtmp=='
)
                       {
                               for(i=0;passwordtmp!='
;i++)
                                {
                                       password = passwordtmp;
                                }
                                password = '
;
                                LCD_Clear();
                                delay_nms(1);
                               LCD_Setpos_DispString(2,1,"新密碼設(shè)定成功!");
                                delay_nms(2);
                               LCD_Setpos_DispString(3,1,"請(qǐng)牢記新密碼!");
                                delay_nms(1);
                               WritePasswordToBackupReg(password);        //保存新密碼
                                delay_nms(3000);
                                break;
                       }
                }
        }
}
/********************************************************************
*   : Input_Password()
*   能:輸入密碼
*   明:直到密碼輸入正確或新密碼設(shè)定完成才退出此函數(shù)
*********************************************************************/
void Input_Password()
{
        __IO uint16_ti,index=0;
        __IO uint16_tfaultcount = 0;
        LCD_Clear();
        delay_nms(1);
       LCD_Setpos_DispString(1,1,"請(qǐng)輸入密碼:");
        delay_nms(2);
       LCD_Setpos(2,1);
        delay_nms(1);
        while(1)
        {
               keyflag = 0;
               while(keyflag < 1)
                { }
               keyflag = 0;
               if(keyval<=9)
                {
                  LCD_DispChar(keyval+'0');
                 delay_nms(1);
                 passwordtmp[index++] = keyval;
                }
                elseif(keyval == 'c')                   //按下取消鍵
                {
                       index--;
                        passwordtmp[index]='
;
                       LCD_Clear();
                       delay_nms(1);
                       LCD_Setpos_DispString(1,1,"請(qǐng)輸入密碼:");
               delay_nms(2);
               LCD_Setpos(2,1);
                delay_nms(1);
                       for(i=0;passwordtmp!='
;i++)
                       {
                               LCD_DispChar(passwordtmp+'0');
                       }
                       delay_nms(1);
                }
                elseif(keyval=='e')                   //按下確認(rèn)鍵
                {
                   passwordtmp[index] = '
;  //密碼結(jié)束標(biāo)記
                       for(i=0;password!='
;i++)
                       {
                               if(passwordtmp !=password)
                                {
                                       faultcount ++;
                                        break;
                                }
                       }
                        if(faultcount == 3)
                       {
                                faultcount = 0;
                                CLOSE_DOOR;
                                LCD_Clear();
                                delay_nms(1);
                                LCD_Setpos_DispString(2,1,"密碼已經(jīng)錯(cuò)誤 3");
                                delay_nms(2);
                               LCD_Setpos_DispString(3,1,"等待 1分鐘后再試");
                           delay_nms(60000); //密碼錯(cuò)誤3次以后,等待1分鐘才可再次輸入
                                LCD_Clear();
                                delay_nms(1);
                               LCD_Setpos_DispString(1,1,"請(qǐng)?jiān)俅屋斎朊艽a:");
                   delay_nms(2);
                               LCD_Setpos(2,1);
                    delay_nms(2);
                                index = 0;
                       }
                       else if((faultcount >0) && (password!='
))
                       {
                                CLOSE_DOOR;
                                LCD_Clear();
                                delay_nms(2);
                               LCD_Setpos_DispString(2,2,"密碼錯(cuò)誤!");
                               delay_nms(1000);
                                LCD_Clear();
                                delay_nms(1);
                               LCD_Setpos_DispString(1,1,"請(qǐng)?jiān)俅屋斎朊艽a:");
                   delay_nms(2);
                               LCD_Setpos(2,1);
                   delay_nms(2);
                                index = 0;
                       }
                       if((password=='
)&&(passwordtmp=='
))//輸入密碼正確
                       {
                         LCD_Clear();
                         delay_nms(1);
                         LCD_Setpos_DispString(2,3,"密碼正確!");
                         delay_nms(2);
                         LCD_Setpos_DispString(3,3,"鎖已打開!");
…………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………

評(píng)分

參與人數(shù) 1黑幣 +4 收起 理由
落葉慌 + 4 贊一個(gè)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表