单片机实验
在复位电路中,按键复位的原理及其程序你知道是什么吗?本文主要介绍就是关于按键复位及其程序的讲解,为了方便大家更好的理解,我们首先来看一下什么是复位电路。
复位电路是一种用来使电路恢复到起始状态的电路设备,它的操作原理与计算器有着异曲同工之妙,只是启动原理和手段有所不同。复位电路,就是利用它把电路恢复到起始状态。就像计算器的清零按钮的作用一样,以便回到原始状态,重新进行计算。
1:因为微处理器(如我们常说的电脑CPU芯片和高端ARM)和微控制器(单片机、低端ARM什么的)芯片都是数字电路芯片,其正常工作是只有0低电平和1高电平这两个电平状态,属于离散系统。而供给芯片的电源输入却是模拟电路,属于连续线性系统。合上开关,芯片的VDD和VSS之间的电压要达到数字芯片可正常工作的电压是需要几毫秒到十几毫秒的过程的。
2:而也因为微处理器和微控制器是数字电路芯片,其是需要时钟信号才能工作。不管是内部芯片自带的低频RC振荡器还是外接晶振或者其他时钟电路,从上电到时钟电路正常起振也是需要时间的。可以看下图我用示波器测到的:ARM9上电那几百毫秒内,电源输入VCC对地电压(黄线)、及18.492M时钟(绿线)引脚对地电压发生的情况。可以看到芯片在给电的10毫秒内电源开始升到正常供电水平,但至少500毫秒后晶振才开始正常输出时钟(之前的虽然有时钟信号,也可以让CPU工作,但波形不稳定,按此状态运行的CPU容易出错)
所以,需要在芯片上电的时候给复位端一个复位信号让微处理器和微控制器内部的CPU在刚上电那段时间不要工作。
51的按键复位则是在阻容复位的基础上增加了一个人工干预复位端的按钮和一个限流电阻。如下图,当正常工作的时候,复位端RST和+5V,等同于断开,通过R7接地。当复位按钮按下,复位端RST和+5V几乎连起来,高电平使能芯片复位。并且释放电容C的电能。
R6的作用是不让电源+5直接冲击芯片的复位端(直接冲击可能会损害芯片,特别是8051这种IO驱动能力较弱的芯片),并且防止电容C因短路放电过快而被损坏。
按键复位电路的目的一般是为了开发者在调试电路或程序时候使用,也有在成型的产品使用过程中使其硬复位的功能,比如一些电脑还带有复位按钮,按一下机器强行复位,就是这个原理,当然电脑的复位按键后面的电路远复杂于这个,不仅仅是复位一个芯片,主板上的其他芯片也会被强行复位)
(而且ARM和电脑CPU芯片一般不会直接用类似这种按键复位电路,使用专用复位芯片有自带的按键接口引脚接按键)
void main(void)
{
unsigned char code rst[]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32}; // 复位代码
(*((void (*)())(rst)))(); // 执行上一行代码,将rst数组当函数调用
}第一句定义一个数组rst[],数组内数据就是完成复位功能的汇编机器码,具体对应关系为:
clr a == 0xe4、push acc == 0xc0,0xe0、reti ==0x32
可以看出其程序起到复位的作用,完全就是汇编机器码的功劳。
而单片机复位的更好方法
clr a //清除ACC=0
push acc //压0到堆栈——8位
push acc //再压0到堆栈——再8位
reti //返回到0地址,从新执行。
看过上面更简单的复位方法,让我们多加考虑一下,为什么要写成0?别的不行吗?换成别的后会是什么样的效果呢?抱着这个想法,我亲自经过KEIL V2.4.0编译后的汇编程序:
可以看出若将( * ( void (*)( ) )0 ) ( );
改成( * ( void (*)( ) )3 ) ( );
则程序会跳转到main()函数开始,避开startup文件的初始化……
只所以我说的是会从main()开始,是因为我看过编译后的汇编文件,找到main的实际物理地址而已,否则我也不会写成3了。呵呵……下面就是编译后的汇编结果
C:0x0003 E4 CLR A
C:0x0004 F508 MOV 0x08,A
C:0x0006 F509 MOV 0x09,A
14: while(1) {
15: if(i == 10) {
16: //( *( ( void (*)( ) ) (rst) ) )(); // 执行上一行代码,将rst数组当函数调用
C:0x0008 E509 MOV A,0x09
C:0x000A 640A XRL A,#0x0A
C:0x000C 4508 ORL A,0x08
C:0x000E 7005 JNZ C:0015
17: ( *( ( void (*)( ) ) (3) ) )(); // 执行上一行代码,将rst数组当函数调用
C:0x0010 120003 LCALL main(C:0003)
18: } else {
C:0x0013 80F3 SJMP C:0008
19: i++;
C:0x0015 0509 INC 0x09
C:0x0017 E509 MOV A,0x09
C:0x0019 70ED JNZ C:0008
C:0x001B 0508 INC 0x08
20: }
为了进行给大家一个很好的比较,从视觉上得到一定的感觉,我又再次将3改回成0,大家看看编译后的汇编结果是什么样子的;
下面的代码是函数( * ( void (*)( ) )0 ) ( ); 这个编译后的结果
C:0x0003 E4 CLR A
C:0x0004 F508 MOV 0x08,A
C:0x0006 F509 MOV 0x09,A
14: while(1) {
15: if(i == 10) {
16: //( *( ( void (*)( ) ) (rst) ) )(); // 执行上一行代码,将rst数组当函数调用
C:0x0008 E509 MOV A,0x09
C:0x000A 640A XRL A,#0x0A
C:0x000C 4508 ORL A,0x08
C:0x000E 7005 JNZ C:0015
17: ( *( ( void (*)( ) ) (0) ) )(); // 执行上一行代码,将rst数组当函数调用
C:0x0010 120000 LCALL C_STARTUP(C:0000)
18: } else {
C:0x0013 80F3 SJMP C:0008
19: i++;
C:0x0015 0509 INC 0x09
C:0x0017 E509 MOV A,0x09
C:0x0019 70ED JNZ C:0008
C:0x001B 0508 INC 0x08
20: }
简而言之,复位电路的目的就是在上电的瞬间提供一个与正常工作状态下相反的电平。一般利用电容电压不能突变的原理,将电容与电阻串联,上电时刻,电容没有充电,两端电压为零,此时,提供复位脉冲,电源不断的给电容充电,直至电容两端电压为电源电压,电路进入正常工作状态。
关于复位电路以及按键复位的介绍就到这了,希望通过本文能让你对复位电路以及按键复位有更深的理解。
全部0条评论
快来发表一下你的评论吧 !