2703|0

940

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

【R7F0C809】简易电子锁密码校验与时间显示功能已实现 [复制链接]

本帖最后由 wgsxsm 于 2015-11-15 22:47 编辑

接上贴:https://bbs.eeworld.com.cn/thread-476175-1-1.html在添加完AD按键和OLED显示功能的情况下,现在加入了RTC时钟显示和EEPROM存储电子锁密码的功能。
通过模拟IIC来实现,在一组IIC线上外挂一个PCF8563和一个AT24C02,通过设定PCF8563每秒一次的中断来更新时间;
通过对AT24C02进行数据的读取与存储来进行密码的管理。

~~~~~~~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1.硬件部分
IIC_SCL--P02
IIC_SDA--P03
PCF_INT--P00





R7F0C809主控板通过杜邦线与各模块相连。
需要说明的是:PCF8563通过配置寄存器0E和0F来产生每秒钟进行INT pin一次中断,
由于模块电路忘记对该PIN进行加上拉电阻,软件里不得不配置该PIN脚P00为上拉输入。

2.软件部分
贴上来部分代码并给予说明
  1. static        void IIC_SW_IO_Config(void)
  2. {
  3.     PMC0 &= 0xf3;       /* P0.2&P0.3:Digital I/O */   
  4.     POM0 &= 0xf3;       /* P0.2&P0.3:Normal output mode.*/   
  5.     P0 |= 0x0c;         /* P0.2&P0.3:set 1*/   
  6.     PM0 &= 0xf3;        /* P0.2&P0.3:Output mode */
  7. }

  8. void  IIC_Init(void)
  9. {
  10.         IIC_SW_IO_Config();
  11. }
复制代码
更新INTC_Create函数,因为PCF_INF采用了外部中断方式.
  1. void INTC_Create(void)
  2. {        
  3.     PMK0 = 1U;  /* disable INTP0 operation */
  4.     PIF0 = 0U;  /* clear INTP0 interrupt flag */
  5.     PMK1 = 1U;  /* disable INTP1 operation */
  6.     PIF1 = 0U;  /* clear INTP1 interrupt flag */
  7.     PMK2 = 1U;  /* disable INTP2 operation */
  8.     PIF2 = 0U;  /* clear INTP2 interrupt flag */
  9.     PMK3 = 1U;  /* disable INTP3 operation */
  10.     PIF3 = 0U;  /* clear INTP3 interrupt flag */
  11.     PMK4 = 1U;  /* disable INTP4 operation */
  12.     PIF4 = 0U;  /* clear INTP4 interrupt flag */
  13.     PMK5 = 1U;  /* disable INTP5 operation */
  14.     PIF5 = 0U;  /* clear INTP5 interrupt flag */
  15.    
  16.     /* Set INTP1/5 priority */
  17.     PPR11 = 0U;                //priority-->0
  18.     PPR01 = 0U;        
  19.     PPR15 = 0U;                //priority-->1
  20.     PPR05 = 1U;        
  21.         
  22.     EGN0 = 0x22U;        //INTP1/5--Falling edge.
  23.         EGP0 = 0x02U;        //INTP1--Rising edge.
  24. }
复制代码
另外说明的是,K1按键也即是P11-INTP1脚采用的是双边沿检测,
其功能是按下后,蜂鸣器叫,一直到松开按键后,蜂鸣器停止发声。

这样按键K1也即是起到了门铃作用。
  1. __interrupt void INTC1_Interrupt(void)
  2. {
  3.     /* Waiting about 10ms for rejection */
  4.     while (!TMIF00)
  5.     {
  6.         HALT();             /* Waiting of TM00 interrupt request */
  7.     }
  8.     TMIF00 = 0U;            /* INTTM00 interrupt request clear */
  9.         LED_Toggle();

  10.     /* After 10ms or more from when the SW is turned ON */
  11.     /*                 check the status of the SW again */
  12.     if (P1.1==0) /* Is SW really ON ? */
  13.     {               
  14.                 BUZ_On();
  15.     }
  16.         else if (P1.1==1)
  17.         {
  18.                 BUZ_Off();
  19.         }
  20.         
  21.         PIF0 = 0U;              /* INTP0 interrupt request clear */

  22.     /* End user code. Do not edit comment generated here */
  23. }
复制代码
PCF_INT PIN每秒产生一次中断,通过该中断告知设置的定时器到了,将更新时间标志位置位。
  1. __interrupt void INTC5_Interrupt(void)
  2. {
  3.         if (P0.0==0)
  4.         {
  5.                 time_Refresh=1;
  6.                 PCF8563_WriteAdress(CTRL_BUF2,0x01);        //TF-->0,w to clear:timer flag is cleared
  7.         }
  8.         PIF5 = 0U;              /* INTP5 interrupt request clear */
  9. }
复制代码
为了得到更好的体验,将MCU的TAU0_Channel0配置为间隔时间为4ms的定时器,这样对模拟输入引脚的电压进行 6 次 A/D 采集,去掉最大、最小值并求平均。重复上述操作,如果两次获得的平均值相同,即确认当前按键。因此按键按下的确认时间为 4×6×2=48ms.此时的AD按键输入性能才能达到最佳。
  1. void TAU0_Create(void)
  2. {
  3.     TAU0EN = 1U;        /* supplies input clock */
  4.     TPS0 |= 0x04U;                /* 1.25MHz */
  5.     /* Stop all channels */
  6.     TT0 |= 0x0FU;
  7.     /* Mask channel 0 interrupt */
  8.     TMMK00 = 1U;        /* disable INTTM00 interrupt */
  9.     TMIF00 = 0U;        /* clear INTTM00 interrupt flag */
  10.    
  11.     /* Set INTTM00 low priority */
  12.     TMPR100 = 1U;
  13.     TMPR000 = 1U;
  14.    
  15.     /* Channel 0 used as interval timer */
  16.     TMR00H = 0x00U;
  17.     TMR00L = 0x00U;
  18.     /* 4ms interval compare value */
  19.     TDR00H = 0x13U;                //1250*4-1=4999
  20.     TDR00L = 0x87U;
  21.         
  22.     TO0  &= 0x0EU;
  23.     TOE0 &= 0x0EU;
  24. }
复制代码
EEPROM操作部分在上电时会进行检测,是否为新的AT24C02,如果是,将对该新器件进行写入密码初始值(151122--作品最晚提交日期),并将给密码进行打包,包头为0x55,包尾为0xAA,以进行下次开机时读取判定。
  1. void EEReadPassword(void)
  2. {
  3.         uint8_t        i;
  4.         for(i=0;i<8;i++)
  5.         {
  6.                 EEBuffer[i]= AT24CXX_ReadOneByte(i);
  7.         }
  8.         /*The flag of valid password*/
  9.         if(EEBuffer[0]==0x55 && EEBuffer[7]==0xAA)
  10.         {
  11.                 NewDevice_Sign=0;
  12.                 for(i=0;i<8;i++)
  13.                 {
  14.                         PassWords[i]= EEBuffer[i];
  15.                 }                        
  16.         }
  17.         else
  18.         {
  19.                 NewDevice_Sign=1;        
  20.         }
  21. }

  22. void EEWritePassword(void)
  23. {
  24.         uint8_t        i;
  25.         for(i=0;i<8;i++)
  26.         {
  27.             AT24CXX_WriteOneByte( i, PassWords[i]);
  28.         }
  29. }
复制代码
AD按键操作处,处于实时进行检测,密码输入完毕后,以#为结尾进行通知进行校验,检测到第七位为#则进行比对密码,其余则认为密码无效,即便输入了正确密码;密码比对成功,则提示“密码正确”;否则,则表示密码错误。
  1. if(g_Last_AD_Key_Code != g_Live_AD_Key_Code)     /* Current key update? */
  2.         {
  3.                 g_Last_AD_Key_Code = g_Live_AD_Key_Code;
  4.                
  5.                 if(g_Live_AD_Key_Code!=13)                /*valid key*/
  6.                 {
  7.                         if(NoticeTimeDelay!=0) return;
  8.                         if(KeyWordShowPosition==6)
  9.                         {
  10.                                 if(g_Live_AD_Key_Code==12)
  11.                                 {
  12.                                         /*compare*/
  13.                                         if( KeyWords[0]==PassWords[1] && KeyWords[1]== PassWords[2]
  14.                                                 &&KeyWords[2]==PassWords[3] && KeyWords[3]==PassWords[4]
  15.                                                 &&KeyWords[4]==PassWords[5] && KeyWords[5]==PassWords[6] )        /* correct key */
  16.                                         {                                                
  17.                                                 NoticeKeywordStatus(STATUS_OK);
  18.                                                 
  19.                                                 /*
  20.                                                         OPEN THE DOOR!
  21.                                                 */
  22.                                                 
  23.                                                 BUZ_Call_Long(1500);                                        /*1.5s*/
  24.                                         }
  25.                                         else        /* error key */
  26.                                         {                                                
  27.                                                 NoticeKeywordStatus(STATUS_ERROR);
  28.                                                 
  29.                                                 BUZ_Call(2);                                                        /*call 2 times*/
  30.                                         }                                       
  31.                                         NoticeTimeDelay=500;
  32.                                 }
  33.                                 else
  34.                                 {
  35.                                         /* invalid key */                                       
  36.                                         NoticeKeywordStatus(STATUS_INVALID);                                       
  37.                                         NoticeTimeDelay=300;
  38.                                        
  39.                                         BUZ_Call(2);                                                        /*call 2 times*/
  40.                                 }
  41.                                 KeyWordShowPosition=0;
  42.                         }
  43.                         else
  44.                         {
  45.                                 KeyWords[KeyWordShowPosition]=g_Live_AD_Key_Code;
  46.                                 KeyValue_Display(40+KeyWordShowPosition*8,2,g_Live_AD_Key_Code);
  47.                                 KeyWordShowPosition++;
  48.                         }
  49.                 }
  50.         }
复制代码


由于硬件上AD按键没有给出各按键的标识“123456789*0#”,因此在OLED上显示出按键值来进行录像,否则无法观看处效果。
3.操作演示
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表