单片机按键程序中如何实现通过按键更改密码?

查看: 24015|回复: 5
关于单片机按键处理的程序 100%保证可用
最近在网上看见一个不错的单片机按键处理程序。所以就和大家分享一下。这个处理程序,对长按和短按都处理的比较细腻。大家在这块不懂的都有可以参照这个程序模板进行修改,本人已经试验,100%保证可用。
单片机按键处理技巧及编程方式
141347_eG4Q_266979.jpg (2.02 KB, 下载次数: 46)
19:12 上传
& &在基于单片机为核心构成的应用系统中,用户输入是必不可少的一部分。输入可以分很多种情况,譬如有的系统支持PS2键盘的接口,有的系统输入是基于编码器,有的系统输入是基于串口或者USB或者其它输入通道等等。在各种输入途径中,更常见的是,基于单个按键或者由单个键盘按照一定排列构成的矩阵键盘(行列键盘)。我们这一篇章主要讨论的对象就是基于单个按键的程序设计,以及矩阵键盘的程序编写。
& & 按键检测的原理:& &它们和我们的单片机系统的I/O口连接一般如下:
b141c.jpg (28.93 KB, 下载次数: 57)
19:12 上传
& &&&对于单片机I/O内部有上拉电阻的微控制器而言,还可以省掉外部的那个上拉电阻。简单分析一下按键检测的原理。当按键没有按下的时候,单片机I/O通过上拉电阻R接到VCC,我们在程序中读取该I/O的电平的时候,其值为1(高电平);当按键S按下的时候,该I/O被短接到GND,在程序中读取该I/O的电平的时候,其值为0(低电平) 。这样,按键的按下与否,就和与该按键相连的I/O的电平的变化相对应起来。结论:我们在程序中通过检测到该I/O口电平的变化与否,即可以知道按键是否被按下,从而做出相应的响应。一切看起来很美好,是这样的吗?
df1.jpg (5.47 KB, 下载次数: 45)
19:12 上传
& &&&在我们通过上面的按键检测原理得出上述的结论的时候,那就是现实中按键按下时候的电平变化状态。我们的结论是基于理想的情况得出来的,而实际中,由于按键的弹片接触的时候,并不是一接触就紧紧的闭合,它还存在一定的抖动,尽管这个时间非常的短暂,但是对于我们执行时间以us为计算单位的微控制器来说,
它太漫长了。因而,实际的波形图应该如下面这幅示意图一样。
a6b43.jpg (5.11 KB, 下载次数: 50)
19:12 上传
这样便存在这样一个问题。假设我们的系统有这样功能需求:在检测到按键按下的时候,将某个I/O的状态取反。由于这种抖动的存在,使得我们的微控制器误以为是多次按键的按下,从而将某个I/O的状态不断取反,这并不是我们想要的效果,假如该I/O控制着系统中某个重要的执行的部件,那结果更不是我们所期待的。于是乎有人便提出了软件消除抖动的思想,道理很简单:抖动的时间长度是一定的,只要我们避开这段抖动时期,检测稳定的时候的电平不就可以了吗?听起来确实不错,而且实际应用起来效果也还可以。于是就像下面的伪代码所描述的一样。(假设按键按下时候,低电平有效)
If(0 ==io_KeyEnter)& && && && &//如果有键按下了
& &&&Delayms(20);& && && && & //先延时20ms避开抖动时期
& &&&If(0 ==io_KeyEnter)& && && &//然后再检测,如果还是检测到有键按下
& && && &return KeyV& && && &&&//是真的按下了,返回键值
& &&&returnKEY_NULL& && && &//是抖动,返回空的键值
& &&&while(0 == io_KeyEnter) ;& &&&//等待按键释放
乍看上去,确实挺不错,在实际的系统中,一般是不允许这么样做的。为什么呢?首先,这里的Delayms(20) ,让微控制器在这里白白等待了20 ms 的时间,啥也没干,考虑我在《学会释放CPU》一章中所提及的几点,这是不可取的。其次while(0 ==io_KeyEnter) 所以合理的分配好微控制的处理时间,是编写按键程序的基础。原本是等待按键释放,结果CPU就一直死死的盯住该按键,其它事情都不管了,那其它事情不干了吗?
消除抖动有必要吗?
& & 的确,软件上的消抖确实可以保证按键的有效检测。但是,这种消抖确实有必要吗?抖动的出现即意味着按键已经按下,尽管这个电平还没有稳定。所以只要我们检测到按键按下,即可以返回键值,问题的关键是,在你执行完其它任务的时候,再次执行我们的按键任务的时候,抖动过程还没有结束,这样便有可能造成重复检测。所以,如何在返回键值后,避免重复检测,或者在按键一按下就执行功能函数,当功能函数的执行时间小于抖动时间时候,如何避免再次执行功能函数,就成为我们要考虑的问题了。所以消除抖动的目的是:防止按键一次按下,多次响应。
&&基于状态转移的独立按键程序设计
& &&&本章所描述的按键程序要达到的目的:检测按键按下,短按,长按,释放。即通过按键的返回值我们可以获取到如下的信息:按键按下(短按),按键长按,按键连_发,按键释放。这样的功能到底是如何实现的呢,今天就让我们来剖析它的原理吧。下面让我们来简单的描绘一下它的状态流程转移图。
141543_CBa1_266979.jpg (30.33 KB, 下载次数: 94)
19:12 上传
& &下面对上面的流程图进行简要的分析。
首先按键程序进入初始状态S1,在这个状态下,检测按键是否按下,如果有按下,则进入按键消抖状态2,在下一次执行按键程序时候,直接由按键消抖状态进入按键按下状态3,在此状态下检测按键是否按下,如果没有按键按下,则返回初始状态S1,如果有则可以返回键值,同时进入长按状态S4,在长按状态下每次进入按键程序时候对按键时间计数,当计数值超过设定阈值时候,则表明长按事件发生,同时进入按键连_发状态S5。如果按键键值为空键,则返回按键释放状态S6,否则继续停留在本状态。在按键连_发状态下,如果按键键值为空键则返回按键释放状态S6,如果按键时间计数超过连_发阈值,则返回连_发按键值,清零时间计数后继续停留在本状态。 下面让我们一起来编写按键驱动程序吧。&&下面是我使用的硬件的连接图。
141603_qOd8_266979.jpg (5.42 KB, 下载次数: 68)
19:12 上传
& &硬件连接很简单,四个独立按键分别接在P3^0------P3^3四个I/O上面。
因为51单片机I/O口内部结构的限制,在读取外部引脚状态的时候,需要向端口写1.在51单片机复位后,不需要进行此操作也可以进行读取外部引脚的操作。因此,在按键的端口没有复用的情况下,可以省略此步骤。而对于其它一些真正双向I/O口的单片机来说,将引脚设置成输入状态,是必不可少的一个步骤。
下面的程序代码初始化引脚为输入。
void KeyInit(void)
& &&&io_key_1 = 1 ;
& &&&io_key_2 = 1 ;
& &&&io_key_3 = 1 ;
& &&&io_key_4 = 1;& && && && &
根据按键硬件连接定义按键键值
#defineKEY_VALUE_1& && && && &&&0x0e
#define KEY_VALUE_2& && && && &&&0x0d
#defineKEY_VALUE_3& && && && && & 0x0b
#defineKEY_VALUE_4& && && && && & 0x07
#defineKEY_NULL& && && && && && &&&0x0f
下面我们来编写按键的硬件驱动程序。
根据第一章所描述的按键检测原理,我们可以很容易的得出如下的代码:
static uint8 KeyScan(void)
& &&&if(io_key_1 == 0)return KEY_VALUE_1 ;
& &&&if(io_key_2 == 0)return KEY_VALUE_2 ;
& &&&if(io_key_3 == 0)return KEY_VALUE_3 ;
& &&&if(io_key_4 == 0)return KEY_VALUE_4 ;
& &&&return KEY_NULL ;
其中io_key_1等是我们按键端口的定义,如下所示:
sbit io_key_1 = P3^0 ;
sbit io_key_2 = P3^1 ;
sbit io_key_3 = P3^2 ;
sbit io_key_4 = P3^3 ;
KeyScan()作为底层按键的驱动程序,为上层按键扫描提供一个接口,这样我们编写的上层按键扫描函数可以几乎不用修改就可以拿到我们的其它程序中去使用,使得程序复用性大大提高。同时,通过有意识的将与底层硬件连接紧密的程序和与硬件无关的代码分开写,使得程序结构层次清晰,可移植性也更好。对于单片机类的程序而言,能够做到函数级别的代码重用已经足够了。
在编写我们的上层按键扫描函数之前,需要先完成一些宏定义。
//定义长按键的TICK数,以及连_发间隔的TICK数
#define KEY_LONG_PERIOD& && && &100
#define KEY_CONTINUE_PERIOD& &&&25
//定义按键返回值状态(按下,长按,连_发,释放)
#defineKEY_DOWN& && && && && & 0x80
#defineKEY_LONG& && && && && && &&&0x40
#defineKEY_CONTINUE& && && && &0x20
#define KEY_UP& &&&0x10& && &&&//定义按键状态
#defineKEY_STATE_INIT& && && && &0
#defineKEY_STATE_WOBBLE& && && && &1
#defineKEY_STATE_PRESS& && && && &2
#defineKEY_STATE_LONG& && && && &3
#define KEY_STATE_CONTINUE& && & 4
#define KEY_STATE_RELEASE& && && &5
接着我们开始编写完整的上层按键扫描函数,按键的短按,长按,连按,释放等等状态的判断均是在此函数中完成。对照状态流程转移图,然后再看下面的函数代码,可以更容易的去理解函数的执行流程。完整的函数代码如下:
void GetKey(uint8 *pKeyValue)
& &&&static uint8 s_u8KeyState = KEY_STATE_INIT ;
& &&&static uint8 s_u8KeyTimeCount = 0 ;
& &&&static uint8 s_u8LastKey = KEY_NULL ;& &//保存按键释放时候的键值
& &&&uint8 KeyTemp = KEY_NULL ;
& &&&KeyTemp = KeyScan();& && && &//获取键值
& &&&switch(s_u8KeyState)
& && && &case KEY_STATE_INIT :
& && && && && & {
& && && && && && &&&if(KEY_NULL != (KeyTemp))
& && && && && && &&&{
& && && && && && && && &s_u8KeyState = KEY_STATE_WOBBLE ;
& && && && && && &&&}
& && && && && & }
& && && &case KEY_STATE_WOBBLE:& && & //消抖
& && && && && & {
& && && && && && &&&s_u8KeyState = KEY_STATE_PRESS ;& &&&
& && && && && & }
& && && &case KEY_STATE_PRESS :
& && && && && & {
& && && && && && &&&if(KEY_NULL != (KeyTemp))
& && && && && && &&&{
& && && && && && && && &s_u8LastKey = KeyT //保存键值,以便在释放按键状态返回键值
& && && && && && && && &KeyTemp |= KEY_DOWN ;& &//按键按下
& && && && && && && && &s_u8KeyState = KEY_STATE_LONG ;
& && && && && && &&&}
& && && && && && &&&else
& && && && && && &&&{
& && && && && && && && &s_u8KeyState = KEY_STATE_INIT ;
& && && && && && &&&}
& && && && && & }
& && && &case KEY_STATE_LONG :
& && && && && & {
& && && && && && &&&if(KEY_NULL != (KeyTemp))
& && && && && && &&&{
& && && && && && && && &if(++s_u8KeyTimeCount & KEY_LONG_PERIOD)
& && && && && && && && &{
& && && && && && && && && & s_u8KeyTimeCount = 0 ;
& && && && && && && && && & KeyTemp |= KEY_LONG ;& &//长按键事件发生
& && && && && && && && && & s_u8KeyState = KEY_STATE_CONTINUE ;
& && && && && && && && &}
& && && && && && &&&}
& && && && && && &&&else
& && && && && && &&&{
& && && && && && && && &s_u8KeyState = KEY_STATE_RELEASE ;
& && && && && && &&&}
& && && && && & }
& && && &case KEY_STATE_CONTINUE :
& && && && && & {
& && && && && && &&&if(KEY_NULL != (KeyTemp))
& && && && && && &&&{
& && && && && && && && &if(++s_u8KeyTimeCount & KEY_CONTINUE_PERIOD)
& && && && && && && && &{
& && && && && && && && && & s_u8KeyTimeCount = 0 ;
& && && && && && && && && & KeyTemp |= KEY_CONTINUE ;
& && && && && && && && &}
& && && && && && &&&}
& && && && && && &&&else
& && && && && && &&&{
& && && && && && && && &s_u8KeyState = KEY_STATE_RELEASE ;
& && && && && && &&&}
& && && && && & }
& && && &case KEY_STATE_RELEASE :
& && && && && & {
& && && && && && &&&s_u8LastKey |= KEY_UP ;
& && && && && && &&&KeyTemp = s_u8LastK
& && && && && && &&&s_u8KeyState = KEY_STATE_INIT ;
& && && && && & }
& && && &default :
& &&&*pKeyValue = KeyT //返回键值& &
关于这个函数内部的细节我并不打算花过多笔墨去讲解。对照着按键状态流程转移图,然后去看程序代码,你会发现其实思路非常清晰。最能让人理解透彻的,莫非就是将整个程序自己看懂,然后想象为什么这个地方要这样写,抱着思考的态度去阅读程序,你会发现自己的程序水平会慢慢的提高。不管怎么样,这样的一个程序已经完成了本章开始时候要求的功能:按下,长按,连按,释放。事实上,如果掌握了这种基于状态转移的思想,你会发现要求实现其它按键功能,譬如,多键按下,功能键等等,亦相当简单,在下一章,我们就去实现它。
在主程序中我编写了这样的一段代码,来演示我实现的按键功能。
void main(void)
& &&&uint8 KeyValue = KEY_NULL;
& &&&uint8 temp = 0 ;
& && & LED_CS11 = 1 ; //流水灯输出允许
& &&&LED_SEG = 0 ;
& &&&LED_DIG = 0 ;
& &&&Timer0Init() ;
& &&&KeyInit() ;
& &&&EA = 1 ;
& &&&while(1)
& && && &Timer0MainLoop() ;
& && && &KeyMainLoop(&KeyValue) ;
& && && &if(KeyValue == (KEY_VALUE_1 |KEY_DOWN)) P0 = ~1 ;
& && && &if(KeyValue == (KEY_VALUE_1 |KEY_LONG)) P0 = ~2 ;
& && && &if(KeyValue == (KEY_VALUE_1 |KEY_CONTINUE)) { P0 ^= 0xf0;}
& && && &if(KeyValue == (KEY_VALUE_1 |KEY_UP)) P0 = 0xa5 ;
& &&&按住第一个键,可以清晰的看到P0口所接的LED的状态的变化。当按键按下时候,第一个LED灯亮,等待2 S后第二个LED亮,第一个熄灭,表示长按事件发生。再过500 ms 第5~8个LED闪烁,表示连按事件发生。当释放按键时候,P0口所接的LED的状态为:& &灭亮灭亮亮灭亮灭,这也正是P0 =0xa5这条语句的功能。
真的很有用啊!
为嘛我用就编译不通过
为嘛我用就编译不通过
把KeyMainLoop(&KeyValue) ;换成GetKey(&KeyValue);即可。
汇编程序,怎么利用键值跳转到子程序呢?
这个看起来不是很理解,可以发一下楼主自己改过以后的源码吗?
Powered by基于51单片机的密码锁设计_百度文库
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
基于51单片机的密码锁设计
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩14页未读,
定制HR最喜欢的简历
你可能喜欢如何用按键实现单片机中两个不同功能的切换。 - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
如何用按键实现单片机中两个不同功能的切换。
19:40:24  
本帖最后由 eehome 于
10:00 编辑
我是分别写了两个程序,然后怎样使这两个程序在一个工程里分别调用,怎样写一个程序调用不同的文件???我现在分别写好了时钟和日期两个程序,在不变化这两个程序的前提下如何用按键实现两个功能的切换。
20:17:27  
你把这两种程序写成子函数不就得了。一个工程里只能有1个main函数,将两种程序的main函数都写成子程序,再写一个main函数进行调用。注意两个程序间的变量定义等问题,相同定义的变量或声明只要1次就可以了。不过这样的程序组织性太差,没什么实用价值
17:45:02  
我也遇到这们的事了& &&&求解答
20:02:54  
楼主这个问题解决了吗
15:27:58  
你这个问题解答了吗&&楼主 我也需要类似的答案啊&&O(∩_∩)O~
11:47:58  
都是神马意思啊???不懂不懂不懂
高级工程师
10:10:12  
用操作系统读取任务
23:37:51  
状态机区别调用
20:40:38  
我是分别写了两个main函数,如果改的话就麻烦了
高级工程师
20:34:02  
在同一个工程里面调用相关的子函数,
您需要登录后才可以回帖
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司单片机、电路板
连接器、接插件
其他元器件
用单片机做电子密码锁
用单片机做电子密码锁
电子密码锁按照输入密码方式的不同可分为好多种,其中最常用的一种是用数字键盘输入密码的电子密码锁。这一讲主要介绍用ATmega8和LCD1602液晶显示器等组成的电子密码锁,这个电子密码锁能够由用户自行修改密码,掉电后密码不丢失。通过实验和学习使大家掌握电子密码锁的工作原理和ATmega8中EEPROM存储器的使用方法。
  一,EEPROM数据存储器简介ATmega8的存储器由可分别独立寻址的程序
  电子密码锁按照输入密码方式的不同可分为好多种,其中最常用的一种是用数字键盘输入密码的电子密码锁。这一讲主要介绍用ATmega8和LCD1602液晶显示器等组成的电子密码锁,这个电子密码锁能够由用户自行修改密码,掉电后密码不丢失。通过实验和学习使大家掌握电子密码锁的工作原理和ATmega8中EEPROM存储器的使用方法。
  一,EEPROM数据存储器简介ATmega8的存储器由可分别独立寻址的程序存储器Flash、片内数据存储器SRAM和EEPROM三部分组成。
  ATmega8包含512字节的EEPROM数据存储器,可用于保存系统的设定参数、掉电后数据保存等。EEPROM可以按字节为单位进行读写,至少可进行100000次擦写操作。EEPROM的访问由地址寄存器、数据寄存器和控制寄存器决定。
  在程序中EEPROM的访问是通过I/O空间的寄存器来实现的,EEPROM的编程时间典型值为8.5ms。
  为了防止无意的EEPROM写入,必须遵照规范的写入顺序。当读取EEPROM时,单片机将暂停4个时钟周期再执行下一条指令;当写EEPROM时,单片机将暂停2个时钟周期再执行下一条指令。
  下面介绍与EEPROM相关的几个寄存器。
  1.EEPROM地址寄存器
& & & &EEARH、EEARL因为ATmega8有512(2的9次方)字节的EEPROM,所以要用两个8位寄存器来作地址寄存器,编址为0xFF。地址寄存器EEAR可读可写,EEAR的初始值没有定义,在访问EEPROM之前必须写入一个正确的地址值。
  EEAR的定义见下表。
&  2.EEPROM数据寄存器
& & & EEDR数据寄存器EEDR用来存放即将写入EEPROM或者从EEPROM读出的某个单元的数据,写入或读出的地址由地址寄存器EEAR给出。EEDR的初始值为0x00。
  3.EEPROM控制寄存器EECREECR的定义见下表。
&  EERIE位为EEPROM中断准备好使能位,当EERIE置位而且SREG寄存器中的全局中断位I置位时,若EEWE为0,则单片机产生一个中断。
  EEMWE位为EEPROM主机写入使能位,EEMWE决定了EEWE置位是否可以启动EEPROM写操作。当EEMWE为置位时,在4个时钟周期内EEWE置位将把数据写入EEPROM的指定地址;若EEMWE为0,则操作EEWE不起作用。EEMWE置位后4个周期,硬件对其清零。
  EEWE位为EEPROM写使能位,当EEPROM数据和地址设置好之后,需置位EEWE以便将数据写入EEPROM。此时EEMWE必须置位,否则EEPROM写操作将不会发生。写时序如下:
  (1)等待EEWE位变为零。
  (2)将新的EEPROM地址写入EEAR(可选)。
  (3)将新的EEPROM数据写入EEDR(可选)。
  (4)置位EEMWE。
  (5)在置位EEMWE的4个周期内,置位EEWE。
  EERE位为EEPROM读使能位,当EEPROM地址设置好之后,需置位EERE以便将数据读入EEDR。
  EEPROM数据的读取只需要一条指令。读取EEPROM后CPU要停止4个时钟周期才可以执行下一条指令。
  二、电子密码锁实验
  1.实验电路
& & &电子密码锁主要由单片机ATmega8、液晶显示器LCD1602和电磁铁锁芯等部分组成。实验板上与电子密码锁有关的电路部分见下图。图中SB1、SB2、SB3为输入按键,用于输入数字密码。VD6、R7、VT4等组成电磁铁驱动电路,由ATmega8的PD7脚进行控制,实际使用时只要将VT4的负载由继电器换成电子密码锁的电磁铁吸合线圈即可,当然也可以用继电器的常开触点去控制电磁铁吸合线圈。
  2.程序设计
  程序有主函数、初始化函数、LCD显示函数、键盘扫描函数、密码设置函数、EEPROM读写函数和延时函数等部分组成。
  程序中共使用了6个数组,其中数组Datal[]用来存储按键值,它存储在SRAM数据存储区,用来记录输入的。
  按键值。其中数组a[]用来存储密码值,为了防止密码值掉电丢失,a[]存储在EEPROM数据存储区,a[]的初始值为a[]={0,0,0,0,0,0,0,0,0,0,0,0},即初始密码为。
  实验板上的SB1、SB2两个按钮作数字输入键,SB1输入数字0,SB2输人数字1。SB3为确认键。由于只有两个数字输入按钮,因此密码只能采用二进制数,密码长度为12位。输入的12位密码存储在数组Datal口中,按一下确认键SB3后,程序将数组Datal口的各元素和数组a[]的对应元素进行比较,如果两个数组相等,说明密码正确,LCD显示屏显示:RIGHT,PD7输出高电平,由VT4推动电磁铁吸合打开电子密码锁;反之,如果密码错误,LCD显示屏显示:ERROR,打不开电子密码锁。输入密码时输入几个数字LCD显示屏就显示几个&号。
  为了程序设计方便,引入了一个特征值Key,没有任何键按下时,令Key=0;当SBl、SB2有键按下时,令Key=1;当SB3按下时,令Key=2;当密码不正确时,令Key=3。特征值Key作为主函数和按键扫描函数之间联系的一条纽带。
  输入密码由按键扫描函数完成,按键扫描函数的流程图见下图。
  密码设置函数用来重新设置密码,新的密码仍然保存在EEPROM数据存储区,这样掉电后新设置的密码就不会丢失了。密码设置函数的流程图见下图。
  在验证密码和重新设置密码时要对EEPROM进行读写,这可以用EEPROM读写函数来完成,两个函数的语句如下。
  写EEPROM数据函数:
  VOidWrite-EEPROM(ucharData,uintAddress)
  (if(EECR&0x20)//判断写使能是否为0
  DelayMs(10);//延时10ms
  EEARH=Address&&8;//送高地址
  EEARL=Address&OxOO00ff;//送低地址
  EEDR=Data;//送数据
  EECR=EECR|Ox04;//主写使能置位
  EECR=EECR|0x02;//写使能置位
  DelayMs(10);//延时10ms
  读EEPROM数据函数:
  ucharRead_EEPROM(uint
  Address)
  {uchari;
  if(EECR&0x01)//判断读使能是否为O
  DelayMs(10);//延时1Oms
  EEARH=Address&&8;//送高地址
  EEARL=Address&0x00ff;//送高地址
  EECR=EECR|Ox01;//读使能置位
  DelayMs(10);//延时10ms
  i=EEDR;//读数据
  return(i);//返回数据
  上面只对几个主要的函数作了介绍,详细的源程序见本期配刊光盘。
  3.电子密码锁实验首先将程序目标文件写入单片机,为了防止密码掉电后丢失,同时使密码能够重新修改,必须将密码写入EEPROM数据存储器。由于程序中使用了EEPROM数据存储器,因此程序在编译时除了生成HEX目标文件外,还会产生EEP目标文件。HEX目标文件写入Flash程序存储器,EEP目标文件写入EEPROM数据存储器。所以用PonyProg2000写芯片时,在打开目标文件时要分别打开目标文件LOCk.hex和lock.eep,具体操作过程是:
  (1)对芯片进行擦除;(2)用工具栏上的&OpenPro&gramMemory(FLASH)File按钮打开lock.hex文件;(3)用工具栏上的&OpenDataMemory(EEPROM)File&按钮打开lock.eep文件;(4)单击工具栏中的&写器件&按钮即可把两个目标文件分别写入Flash程序存储器和EEPROM数据存储器。操作过程如下图所示。
  接下来接通实验板的电源,通过SB1、SB2输入12位密码,按一下确认键SB3,如果密码正确的话,LCD显示屏会显示&RIGHT&,同时PD7输出5秒钟的高电平,使发光二极管VD6点亮,电磁铁吸合,电子密码锁被打开,如下图所示。如果密码不正确,LCD显示屏会显示&ERROR&,PD7输出仍为低电平,电子密码锁不能被打开。
&  如果要修改密码,必须先输入正确的密码,在VD7没有熄灭前按下SB3,并在VD7熄灭后再保持3秒钟,到时LCD显示屏会显示&SET_PASSWORD&,这时即可用SB1、SB2输入新的12位密码。下次使用时必须输入新的密码才能打开锁,这样经常变更密码可提高锁的安全性。
  由于受按键数量的限制,密码采用了二进制,12位密码的组合也只有4096种,为了提高破解的难度,有两种方法:一种方法是修改程序使得连续输入几次密码错误后将电路锁定一段时间,延长破解的时间;另一种方法是密码采用十进制数,但这就要使用更多的按键,从而使用较多的I/0接口,电路必须进行调整。上述两种方法如何实施留给读者自己思考。
型号/产品名
深圳市艾尔迅科技有限公司
荣声电子有限公司
深圳市泽盛美电子科技有限公司#include&reg51.h&
unsigned char mykey,i;
sbit LED=P1^3;
void main()
{
SCON = 0x50;
TMOD = 0x20;
PCON = 0x00;
#include&reg51.h&
unsigned char mykey,i;
sbit LED=P1^3;
void main()
{
SCON = 0x50;
TMOD = 0x20;
PCON = 0x00;
if(mykey == 'y' || mykey == 'Y')
// for(i=0;i&200;i++);
void inter(void) interrupt 4 using 1
{
//while(RI=0);
if(RI = 1)
mykey = SBUF;
}
这是程序。
下面是截图
全部答案(共1个回答)
= 1;
for(i = 0; i < 0xffff, i ++);
led = 0; // 检查 LED
2。检查interrupt是否工作.
3。在while里加:
if(mykey == 'n' || mykey == 'N')
LED = 1;
如果是USB接口,那么你要懂USB协议,而且单片机的速度要足够快,一般的51怕是做不了,得用USB芯片,比如南京沁恒的CH375,单片机做主机,USB键盘做从机...
数据和指令都是存放在内存单元中的,从一个内存单元读出0-1码,计算机能够判断是指令还是数据,用一个时钟控制信号使程序计数(IP)不断加1,从而读下一个内存单元,...
1.把立即数53H放在地址为20H的存储空间里
2.把立即数20H放在寄存器R0里
3.把立即数10H放在寄存器A里
4.把以寄存器R0里的数(20H)为地址,...
怎么会是可执行文件呢?你使用交叉编译器了吗?
x86的程序不能工作在其他CPU中。
烧录需要的是二进制.bin文件。
如果你是基于Linux操作系统的程序,那么...
设个定时器中断,1s钟中断一次,中断里对蜂鸣器引脚进行取反就行了啊
答: 二手的HD7750就可以了,玩游戏的话内存最好有4G吧,现在电脑入门的内存已经4G了,你的CPU也有点老,可以升级E8200
答: 一些厂商开支支持多跳网络技术,或者用几个小路由器组成无线网络,以求覆盖到整个家庭
答: 开始,运行,cmd回车,输入ipconfig回画,看一下网关是多少,假设是192.168.0.1打开浏览器,在地址栏那边输入192.168.0.1回车,提示输入...
嫌麻烦就把你洗衣机的型号或断皮带,拿到维修点去买1个,自己装上就可以了(要有个小扳手把螺丝放松,装上皮带,拉紧再紧固螺丝)。
关于三国武将的排名在玩家中颇有争论,其实真正熟读三国的人应该知道关于三国武将的排名早有定论,头十位依次为:
头吕(吕布)二赵(赵云)三典韦,四关(关羽)五许(许楮)六张飞,七马(马超)八颜(颜良)九文丑,老将黄忠排末位。
关于这个排名大家最具疑问的恐怕是关羽了,这里我给大家细细道来。赵云就不用多说了,魏军中七进七出不说武功,体力也是超强了。而枪法有六和之说,赵云占了个气,也就是枪法的鼻祖了,其武学造诣可见一斑。至于典韦,单凭他和许楮两人就能战住吕布,武功应该比三英中的关羽要强吧。
其实单论武功除吕布外大家都差不多。论战功关羽斩颜良是因为颜良抢军马已经得手正在后撤,并不想与人交手,没想到赤兔马快,被从后背赶上斩之;文丑就更冤了,他是受了委托来招降关羽的,并没想着交手,结果话没说完关羽的刀就到了。只是由于过去封建统治者的需要后来将关羽神话化了,就连日本人也很崇拜他,只不过在日本的关公形象是扎着日式头巾的。
张飞、许楮、马超的排名比较有意思,按理说他们斗得势均力敌都没分出上下,而古人的解释是按照他们谁先脱的衣服谁就厉害!有点搞笑呦。十名以后的排名笔者忘记了,好象第11个是张辽。最后需要说明的是我们现在通常看到的《三国演义》已是多次修改过的版本,笔者看过一套更早的版本,有些细节不太一样。
销售额:指企业在销售商品、提供劳务及让渡资产使用权等日常活动中所形成的经济利益的总流入。税法上这一概念是不含任何税金的收入。销售额适用于制造业、商业等。
营业额会计上指的是营业收入,税法指的是应税营业收入。营业额属于含税收入,适用于饮食业、运输业、广告业、娱乐业、建筑安装业等 。
做鲫鱼汤很重要的一点是注意火候的把握。
步骤如下:
买新鲜现杀的鲫鱼两条,个头要适中。洗的时候要把鱼鳞全部弄干净,鱼肚里也要洗净,免得汤有腥味;
洗好后,在鱼身上涂抹适当食盐,腌放十分钟;
准备好香葱三根,洗净,打结备用;
切好姜片若干(根据鱼的大小和量);
均匀涂抹姜汁于锅内(防止鱼皮粘锅),倒入色拉油,点火;
油不宜太热,将火旋小,轻轻放鱼入锅,同时放入姜片,把火调大;
煎至鱼皮微露金黄色,将鱼轻轻翻身,直至也微呈金黄色;
煎的过程中,注意转动锅,使鱼均匀煎透;
把火调小,加冷水至淹没鱼为止,放入备好的葱结,开大火,煮沸;
把鱼翻身,再煮五分钟,放入适量的盐,继续煮,直至汤呈现奶白色;
加味精,煮两分钟。
同时准备好吃鱼的料:蘸鱼的陈醋少许倒入碗中,放少许盐,糖,味精,搅拌均匀。
将鱼单独盛在大碗里,鲫鱼汤盛在汤碗里;鱼蘸着料吃,汤即喝。
^_^,美味的鲫鱼汤呈现在你的眼前了,还有香喷喷的鱼肉……
艾滋病初期的时候会出现发烧、头晕、无力、咽痛、关节疼痛、皮疹、全身浅表淋巴结肿大等问题,有些人还可能会发生拉肚子的情况。这些情况大概一两个星期后就会消失,然后就转入了无症状的潜伏期。这时候是要注意起来的。
有的刚开始的时候会经常咳嗽,或者是胸部疼,还有的呼吸都困难,更严重的话有可能咳嗽的时候痰中有血。还有的人是出汗特别多,身体特别虚弱,而且会瘦的特别厉害
然后就是食欲下降,什么也不想吃,甚至已经到了厌食的程度,吃东西的话会恶心然后呕吐,甚至拉肚子,严重的话还可能带血。像我们普通人吃的治拉肚子的药已经对艾滋病人没有效果了。
不要盲目的害怕,恐惧艾滋病,其实它并不可怕,只是大多数人并不了解它,要正确的认识艾滋病。关爱艾滋病人。
第三方理财可以通过向银监会申请基金代理牌照,目前只有四家公司拿到这个牌照
支付业务许可证》的申请人应当具备下列条件:
(一)在中华人民共和国境内依法设立的有限责任公司或股份有限公司,且为非金融机构法人;
(二)有符合本办法规定的注册资本最低限额;
(三)有符合本办法规定的出资人;
(四)有5名以上熟悉支付业务的高级管理人员;
(五)有符合要求的反洗钱措施;
(六)有符合要求的支付业务设施;
(七)有健全的组织机构、内部控制制度和风险管理措施;
(八)有符合要求的营业场所和安全保障措施;
(九)申请人及其高级管理人员最近3年内未因利用支付业务实施违法犯罪活动或为违法犯罪活动办理支付业务等受过处罚。
其他还有些条件,详细的可以去查看《非金融机构支付服务管理办法》~~
在医院住院13天了,有医保卡,由于不知道住院可用医保卡,已全额垫付住院费了。怎样去找社保中心报销?寻找社保中心,方式有多种:(一)你可以咨询用人单位其社保中心的具体地址,(二)登陆当地社保网查询电话和地址,(三)拨打社保服务电话12333查询。
现金流量贴现法在网络企业价值评估中的应用不管一个公司生产什么样的产品,提供什么样的服务,对投资者来说,最终只生产一种产品———现金。投资者之所以持有该公司的证券,是希望这些证券未来为他们产生自由现金流。
  因此,评价网络企业最佳的方式还是应该回到这样一个最基本的经济因素上来,完全以绩效预测为依据,采用贴现现金流量(DCF)分析方法。
  由于贴现现金流量的基础———根据企业未来的风险贴现企业未来的现金流———在全世界各地都是一样的,本文将主要探讨如何将网络企业特有的风险因素包含到评估模型中来,如技术风险、通货膨胀率、国家有关政策的变动、资本控制、经济不稳定等等。在此之前,可以采用两个技巧:
  a.从未来的某个特定时间开始预测,并回溯到目前的绩效情况;
  b.采用传统的分析技巧,了解公司的潜在经济效益,预测它们未来的绩效。
  在现金流量贴现法中,有两种方法可以把网络企业特有的额外风险考虑进去:反映在对未来现金流量的预测过程中,即包括在DCF公式的分子上;以额外的风险溢价加到贴现率中,即包括在DCF公式的分母里。本文认为,利用概率加权的情景分析(将风险反映到现金流量的预测中)将会为企业的价值评估提供更为坚实的理论基础和更加透彻的理解,这主要是因为以下三个原因:
  a.投资者可以事先分散网络行业特有的风险,如技术风险、行业政策风险等,尽管这些风险不可能彻底分散。经典的资本资产定价模型(CAPM)明确指出,贴现率和资本成本只应反映不可分散风险,那么可分散的风险通过现金流量来反映就更加科学,而通过将风险溢价加到贴现率中的做法就有待商榷。
  b.即使在同一个国家同一个行业里,各种风险对不同企业的影响不同。如果采用调整贴现率的方法,将行业风险溢价并入到贴现率中,就意味着对所有的企业采用同样的风险溢价水平,会高估或低估企业价值。
  c.网络这一新兴行业中的竞争规则正在发生巨大的变化,技术/运作标准之间的竞争将更多地体现在“企业网”之间的竞争。在不久的将来,网络行业之间的竞争将更多反映在结构上的竞争、总体价值之间的竞争。“企业网”可以产生一个公司,也可以毁灭一个公司,尽管它并非垄断,但和垄断一样威力强大。在不久的将来,可以预料网络行业将被企业网重塑,这些企业网将相互对抗,并无情地蚕食或吞并对方。这种风险通过加权情景分析,将更好地体现网络企业的竞争规则,并将网络企业可能面临的风险清楚地勾勒出来,而这是简单地使用一个综合各种风险的“风险溢价”参数所无法比拟的。
  4注意要点
  现金流量折现法应注意的两点:
  第一,由于未来收益存在不确定性,发行价格通常要对上述每股净现值折让20%-30%。
  第二,用现金流量折现法定价的公司,其市盈率往往高于市场平均水平,但这类公司发行上市时套算出来的市盈率与一般公司发行的市盈率之间不具可比性。
玻璃隔断的款式不同,价格也不同。还有设计要求不同,面积多少不同,价格也不同。代格玻璃隔断的价格,一般从400----1200元左右。具体要看这些要求而定。可部分拆装、多次重复使用,安装latal高隔间系统材料比安装其它形式隔断材料更廉价、更为合算。使用过程中材料经过拆装后,其损伤极小,而且可以大大降低办公室经常搬迁所产生的费用。内部结构可方便地进行电缆铺设。安装比普通隔墙快。设计趋势。平面设计应与客户的建筑结构相呼应,有机地结合起来。合理而有效地利用空间,使办公空间的效益zui大化,因地制宜,量体裁衣,整个平面的设计感很强。
钢化玻璃隔断有几种不同类型: 无框10mm钢化玻璃隔断180元/平方米 钛合金框6毫米钢化玻璃隔断520元*平方米 在日常使用中,要保持隔断的干净整洁,不要往隔断上面乱挂物品,要定期或者不定期清理隔断墙面。避免用重物挤压或者撞击隔断,防止隔断墙固定不稳动摇。以下关于办公玻璃隔断的保养的几点更是要注意:勿以利器在高隔间墙体外表直接切、割、击打、避免在外表留下刮痕、裂缝及沟孔。
这些主要还是看自己以及当地的消费水准,一般之间比较多 个性的惊喜对细节的把握能够提升整个婚礼的品质,原木色调的餐桌铺上淡紫色镶嵌亮片的薄纱桌布,提高梦幻感。薰衣草色调的桌花完美呼应了婚礼布置的紫色主题,把龙胆、桔梗、飞燕草等薰衣草色花放置在香槟酒杯的花器中,轻松传达出浪漫浓郁的情调。这样的花饰既可以作为主桌花,也可以装饰在签到台,无论放在何处,都能成为婚礼上zui亮丽的一笔。
这个要看是什么样的保洁了,扫扫地、擦擦东西的便宜些,拓荒保洁就贵一些。 一般普通保洁3元人民币每平米。不同的地区价格也是有差异的。 保洁工作决不是yi块抹布yi把扫帚那么简单,各种不同的建筑材料需要使用各种不同的清洁剂,各种现代化清洁设备(多功能洗地机、吸水吸尘器、高压射流机、高温蒸气机、烘干机等)的操作使用,使现代化清洁工作有了相当程度的科学性和专业性。家中的新旧家具经历了时间的考验,问题也随之而来,脏污、划痕、开裂、甚至变形,会让人看了很不舒服。
小规模代理记账200元/月 一般纳税人代理记账500元/月 一般纳税人代理记账(工业类)1000元/月
只是由于种种原因没有坚持下来;再有就是现有的shui务师事务所可以马上开展这项业务。当然,代理记账仅仅靠shui务部门yi家是不够的,其他符合法律要求的中介组织和机构,也应当积极开展这方面的业务,为代理记账创造必要的条件。尽快明确在代理记账过程中受托人的法律地位问题。我们认为,代理记账本身只是yi项单纯的账务处理工作,受托代理记账人员既非委托人内部会计人员,也不是财务会计报告的审计人员,因此,受托代理人不应当同时履行会计监督职能或审计职能。
正在加载...
Copyright &
Corporation, All Rights Reserved
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区
相关问答:123456789101112131415}

我要回帖

更多关于 单片机按键程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信