最近在做一个项目,其中电路板部分功能原理是,STC MCU直接连接ULN2003,再驱动ULN2003控制继电器。本来一切正常的,后面在细调的时候发现有一个问题,就是在电路板上电瞬间或MCU复位瞬间,所有的继电器都会闭合一下,这个误动作是很有问题的,必须避免。该现象的原因我很清楚,即STC MCU上电默认所有管脚都会输出高电平,而我在初始化程序中,将继电器对应的控制IO初始化为低电平,但这之间还是存在一小段时间,管脚输出的是高电平。
通过参看STC器件的使用手册,上面提供了一种方法可以使管脚上电输出低电平,在此一并说下:即在需要上电保持低电平的管脚上,加一个较小阻值的下拉电阻(如1K/2K/3K)。因为STC MCU上电时,所有的管脚的属性都会默认恢复为普通GPIO,该模式下的弱上拉电阻不足以在接了较小的下拉电阻时,将管脚电平拉高,从而避免了上电时输出高电平。而在之后的程序初始化中,再设置对应管脚电平,并设置管脚模式为推挽输出,推挽输出模式下的电流 可以即便在较小的下拉电阻时,仍将管脚电平拉至高电平。从原理上来说,这样是没错的,但唯一的问题是
这意味着要重新制板。所以我实验了很多种其它方法,以期在不改动现有硬件电路的前提下,实现MCU的管脚上电输出低电平。当然,最后我成功了 ;) 在介绍具体的做法之前先介绍两个事实:
第一、STC MCU或者说51单片机,在上电时,都会先执行一个名为STARTUP.A51的文件里的汇编程序的,在该段汇编程序中,MCU会进行最初的初始化,包括一些堆栈参数设置,工作区选定,数据初始化等。而我们平时所写的程序,是在该段汇编程序执行完了之后,才会跳过来的,所以从系统上电到执行初始化应用程序之间是有一定的时间间隔的。
第二,STC MCU的管脚有四种模式:1,准双向口,传统8051的I/O模式,灌电流可达20mA,拉电流270uA,即可以接受较大的输入电流,和输出较小的电流;2、推挽输出,具有较大的拉电流,可达20mA,和准双向口的区别就是具有较大输出电流;3、高阻输入,该模式下,管脚既不能输出电流,也不能接受输入电流;4,开漏模式,和准双向口的区别就是不能输出拉电流,即对外不能输出高电平。而我解决 MCU上电输出高电平,就需要设置管脚模式为高阻或开漏。
STC MCU管脚模式以及设置方法
最后,具体的做法思路是这样的:在STARTUP.A51中,使用汇编语言 对需要上电输出低电平的管脚,设置其管脚属性为高阻或开漏,然后在应用程序中,先将控制管脚的电平初始化后,再重新设置这些控制管脚的模式。这样,在MCU上电后,运行到汇编程序中的管脚属性初始化这点时间就很短,并且STC MCU在下载程序时,ISP软件设置 不需要使用额外复位延时。最后上图上程序上真相:
ISP下载时的设置,不勾选上电复位使用较长延时
另还要注意的第一点是:该段管脚属性初始化程序应该加载STARTUP1段中,并且在该汇编程序文件的开头部分声明这些寄存器:
eg.
P2M1 DATA 095H
P2M0 DATA 096H
P4M1 DATA 0b3H
P4M0 DATA 0b4H
第二点是,在使用Keil建立工程时,应该选择不使用默认的STARTUP.A51,并从Keil的安装目录下,找到这个STARTUP.A51(这个相信不难了),把它放到自己的应用程序目录下,然后添加到Keil中,再进行此项修改,如下图所示:
最后,没改动任何硬件线路,即实现了MCU上电或复位后,既定管脚输出低电平,防止控制的后级误动作。
贴出startup.a51下载地址,仅供参考,慎用。
http://download.csdn.net/detail/firestarway/9349829