2019-06-25 02:43:42 qq_36813844 阅读数 203

51单片机跳过冷启动的方式下载程序

#ifndef __DOWNLOAD_ISP_H_
#define __DOWNLOAD_ISP_H_
#include <STC89C5xRC.H>
/*██████████████████████████████████████████████████████████████████████████████████████████
   if(PCON&0x10)PCON &= 0xEF;           //如果POF位=1,将POF位清0。
   else {PCON |= 0x10; IAP_CONTR=0x60;} //如果POF位=0,将POF位置1。软复位从ISP监控区启动。  
	 说明:开始烧写程序时,按一下(等按下烧写程序按键时将近1秒后再按下复位键)单片机的“复位键”就可以下载程序。 
	 ██████████████████████████████████████████████████████████████████████████████████████
	 使用方法,在main函数初始化时加入[down_isp();]
	 "跳过了冷启动的方式"
 ██████████████████████████████████████████████████████████████████████████████████████████*/

void down_isp(void){
	if(PCON&0x10){//判断最高位是否为1
		PCON = PCON & 0xef;//将POF清0
	}else{
		PCON = PCON | 0x10;
		ISP_CONTR = 0x60;//从ISP区启动,复位
	}
}
#endif

2013-04-16 15:33:56 yueniaoshi 阅读数 4815

冷启动——是指在断电状态下重新上电。冷启动,是在下载程序开始时,为了是单片检测有无下载信号。若有则下载;若无则执行原来的程序。

热启动——是指已经处于上电状态,给复位端加复位信号(还有其他类型的复位),程序重新运行。

怎样判断是冷启动、热启动?

可通过查询PCON寄存器中的POF位来判断,单片机上电冷启动后,POF位变为1,可由软件清0


实际判断流程图:


怎样才能产生冷启动复位、热启动复位?


(更详细信息请参考STC12系列单片机数据手册)


2015-12-13 21:45:42 bill_boy1210 阅读数 374

第一次写博客,应该会有一些瑕疵,后续不断改进吧。以前只是分享别人的东西,现在希望把自己掌握知识分享给大家,希望能坚持下去~~

  1. 什么是处理器的冷启动 vs 热启动?
    冷启动:是处理器的一种启动方式,就是切断处理器的供电电源,重新启动,一旦冷启动,内存的东西全部丢失。
    热启动:热启动通常是由于系统复位造成的系统重启,如硬件看门狗复位、软件看门狗复位、内存越界访问造成的重启等。
  2. 为什么要区分冷启动 vs 热启动?意义何在?
    冷启动的主要工作及此时系统设计目标。通常情况下,对于嵌入式系统而言,冷启动需要对系统整体进行初始配置,包括但不限于硬件寄存器配置、软件变量初始化、上电自检(内存、NVRAM、通信总线、AD、IO……)、记录产品上电信息(上电次数、上电自检结果……)等,产品设计的第一目标是保证系统初次上电拥有一个良好的初始状态。即使有问题也要争取在初始阶段暴漏,而禁止产品“带病”运行。当然,执行这些操作需要耗费一定的启动时间,这是系统设计需要必须付出的代价。
    热启动通常是由于复位造成的系统重启、软件的重新运行,如硬件看门狗、软件看门狗等造成的复位。针对热启动,产品设计的第一目标是尽快使系统恢复到热启动之前的状态,并保持产品处于受控状态。因此,部分冷启动时所做的设计操作可能不需要或者也不允许再次进行,否则可能造成不必要的系统异常发生。这里举一个AD电压采集问题的简单例子,用以说明为什么要区分冷启动和热启动。
    (1)如果冷启动时电压采集变量初始化为0,热启动时电压采集变量也初始化为0。这样可能会产生以下的问题:物理连接的电压始终没有变化(如保持28VDC),仅仅由于处理器的复位造成采集的电压值产生跳变28VDC—>0—>28VDC。
    (2)冷启动时电压采集变量初始化为0,热启动时电压采集变量初始化为启动前的状态。这样就可以避免上述电压采样值的跳变问题。
    上述问题的解决方法可能不知一种,比如滤波、将数据记录在FLASH中等等,但实际应用情况可能比较复杂(比如电压数据记在FLASH中,那么是否需要实时记录电压数据?——耗费系统时间;产品下电后,第二次启动是否会误读该数据?),在此不展开讨论。
  3. 冷启动、热启动的区分方法有哪些?
    区分方法一:利用处理器内部RAM物理特性,采用软件编程方法
    实现原理:处理器内部RAM保存的数据掉电丢失,处理器复位时数据不会丢失,利用该特点进行冷启动、热启动的区分。
    实现步骤:(不能插入流程图,只能写伪代码了……)
void main (void)
{
    // 1.硬件初始化
    HardwareInit();

    // 2.获取启动方式:冷启动vs热启动
    const int StartupPasswordArray[] = "Magic Number";

    int GetArray[] = ReadMemory("指定的未使用的内存地址");

    if(GetArray!= StartupPasswordArray)
    {
        WriteMemory("指定的未使用的内存地址", StartupPasswordArray);

        return "冷启动";
     }
     else
     {
        return "热启动";
     }

    ......
}

优点:不需要额外的硬件资源,即可区分冷启动和热启动,实现方法简单。
缺点:可靠性取决于Magic Number的复杂度,在实际应用中,设置了32位长度数据,经实际应用暂未发现问题。
区分方法二:借助CPLD或者FPGA等逻辑器件实现
实现原理:在逻辑器件内部建立CPU可以读写的地址空间(例如Address = 0xA0000000),通过该地址空间的数值区分冷启动VS热启动。 编写CPLD逻辑实现,产品冷启动时Address 地址上锁存的数据为InitValue = 0x1111;热启动该值保持不变。
实现步骤:

const unsigned int InitValue = 0x1111;    // 默认逻辑地址数据

int SystemStartupMode = 0;                // 系统启动方式定义

void main(void)
{
    // 1.硬件初始化
    HardwareInit();

    // 2.判定系统启动方式:冷启动VS热启动
    unsigned int StartupValue = ReadCpldMemory(Address); 

    if(InitValue == StartupValue )
    {
        SystemStartupMode = "冷启动";

        WriteCpldMemory(Address, InitValue*2); 
    }
    else
    {
        SystemStartupMode = "热启动";
    }

    .......
}

优点:区分处理器的冷启动、热启动更加安全、可靠。
缺点:需要CPLD或者FPGA外围器件支持。

仅供参考,希望大家多多交流。

2013-08-04 16:06:33 itas109 阅读数 2929

        相信喜欢单片机的朋友都用过STC的单片机,用过STC单片机的朋友都有这种感受:实惠、易用、功能强大!就是每次下载都要冷启动特别恶心,相信很多朋友的开发板上的电源键都按烂了。

        其实STC单片机可以不用免掉电下载,想要知道怎样才能免掉电下载,我们先要了解STC单片机是怎样实现串口下载的,其实STC单片机出厂时就预置了一段ISP监控程序,我们称作ISP引导码,这段ISP监控程序就好比电脑硬盘的系统引导区。我们对STC单片机上电启动时,单片机首先执行ISP引导码检测串口是否下载程序的命令,如果上位机在对单片机下载程序时,单片机检测到下载数据流就启动ISP下载功能对单片机进行程序下载,这就是我们平时实验时点击下载后按开发板电源键的过程。
        STC单片机在进行冷启动时会从ISP引导码开始执行程序,而进行热启动或按复位键软启动时是从用户程序段开始执行的。然而熟悉STC单片机的朋友知道STC单片机增加了ISP/IAP控制寄存器ISP_CONTR,用来管理ISP/IAP功能和是否软启动,其各位功能大家可参照STC公司相关资料。当我们将ISP_CONTR置为0x60时单片机自动复位从ISP引导码开始执行。由此我们在需要下载程序时将ISP_CONTR置为0x60就可以完成下载了。
    下面来介绍怎样实现
            方法一:通过按复位键来实现,STC单片机上电复位时PCON的POF=1,在按复位键复位时POF=0。所以我们在程序中可以用POF来   控制ISP_CONTR。
            方法二:利用串口,STC下载软件中有个自定义下载,也就是下载前通过串口发送一段自定义代码,单片机收到该代码后来控制单片机
ISP_CONTR进行软复位下载。

 

/************************************************************************************
* 程序名称:STC单片机免掉电下载
* 程序作者:itas109
* 个人博客:http://blog.csdn.net/itas109
* 程序版本: V1.1
* 编制日期: 2013-08-05
* 编译器:Keil C uVision4
* 调试芯片:STC90C516RD+ 11.0592M晶振
* 占用资源:  1、自定义下载:串口,定时器T1,中断
              2、复位键下载:不占用资源
* 特别说明:  1、修改后的程序可以实现复位按键和自定义下载同时进行,也可以根据自己
				的需要选择,若用户所写程序用到定时器时,请只是用复位下载。
			  2、注意使用自定义下载时,尽量不要对P3口的低四位进行操作,否则可能
			     下载失败。
			  3、该头文件使用说明:
				使用时,将该头文件加入到所编写的程序当中(可以直接添加到Keil的库文件里面),
				在main开始调用Auto_Download()函数即可,例如:
				#include<xx.h>//你所需的头文件
				#include"download.h"//添加免掉电下载头文件
				void main()
				{
					Auto_Download();//调用免掉电下载函数
					while(1)
					{
						//添加你的代码
					}
				}
			  4、自定义下载时,波特率为9600,奇偶位为None,数据位为8,停止位为1,自定义
				下载指令为AB。以上设置可以自己在程序中修改。
			  5、程序可以根据自己的喜好修改,不过请标注原作者的信息,谢谢!


☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆原作者信息☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
*******源程序地址;http://www.51hei.com/mcu/1405.html*******************************
* 程序作者: 郭伟(QQ:495817787 ,Email:)
* 程序版本: V1.0
* 编制日期: 2012-01-19
* 编译器:Keil C uVision4
* 调试芯片:STC89C52 11.0592M晶振
* 占用资源:  1》自定义下载:串口,定时器T1,中断
                     2》复位键下载:不占用资源
* 特别说明:  1》使用本程序时需要用宏来选择条件编译程序段
                      2》使用复位键下载时,只需要在main函数开头调用ResetKey_Download();
                      3> 使用自定义下载时调用Auto_Download()对串口进行初始化,波特率9600
       
**************************************************************************************/
#ifndef _DOWNLOAD_H_   
#define _DOWNLOAD_H_

sfr ISP_CONTR  = 0xE7;//软复位寄存器声明

/***选择下载方式***/
//#define Serial_download//若用户所写程序没有用到定时器,可以去掉注释,使其有效 
#define ResetKey_download//使用条件编译选择下载方式,可以只使用一个。
/*****************/
#ifdef ResetKey_download
	//复位下载相关函数
	void ResetKey_Download()
	{   
		if ((PCON & 0x10) == 0)
		{    
			//POF位=0,单片机软件复位
			PCON = PCON | 0x10;     //将POF位置1,防止重复进入isp监控区
				ISP_CONTR = 0x60;       //软复位,从ISP监控区启动,如果没有isp下载流,则重新转向用户区引导
		}
	else
		{
			PCON = PCON & 0xef;   //将POF清零,以便下次下载
		}
	}
#endif	

#ifdef Serial_download	
	//延时函数
	void delay_ms(unsigned int ms) 
	{   
		unsigned int i,j;  
		for(i = ms;i > 0;i --)   
			for(j=110;j > 0;j --); 
	}

	//初始化串口
	void Serial_Download()
	{
		EA=1;        //开总中断
		ES=1;        //允许串口中断
		TMOD=0x20;   //定时器T1,在方式3中断产生波特率
		PCON=0x00;   //SMOD=0
		SCON=0x50;   
		TH1=0xfd;    //波特率设置为9600
		TL1=0xfd;
		TR1=1;       //开定时器T1运行控制位
	}
	
	//串行口中断
	void Serial_int(void) interrupt 4 using 0
	{
		unsigned char com_buff;
		RI=0;
		com_buff=SBUF;
		if(com_buff==0xAB)
		{   
			delay_ms(1000); 
			ISP_CONTR=0X60;       //软件复位后,从ISP程序区启动
		}
	}
#endif	
	//自动下载调用函数
	void Auto_Download()       
	{
		#ifdef Serial_download
			Serial_Download();
		#endif
		
		#ifdef ResetKey_download
			ResetKey_Download();
		#endif
	}
#endif


 

2011-03-14 13:19:00 zhzht19861011 阅读数 6708

微处理器:LPC2114

编译环境:Keil MDK V4.10

思路:

常把单片机系统的复位分为冷启动和热启动。所谓冷启动,也就是一般所说的上电复位冷启动后片内外RAM的内容是随机的;单片机的热启动是通过外部电路给运行中的单片机的复位端一复位电平而实现的,也就是所说的按键复位或看门狗复位。复位后,RAM的内容都没有改变。在某些场合,必须区分出设备的重启是热重启还是冷重启。常用的方法是:确定某内存单位为标志位(如0x40003FF4~0x40003FF7 RAM单元),启动时首先读该内存单元的内容,如果它等于一个特定的值(例如为0xAA55AA55),就认为是热启动,否则就是冷启动。

根据以上的设计思路思路定义一个变量:

uint32 unStartFlag;

在程序启动时判断:

if(unStartFlag==0xAA55AA55)

{

//热启动处理

}

else

{

//冷启动处理

unStartFlag=0xAA55AA55;

}

然而实际调试中发现,无论是热启动还是冷启动,开机后所有内存单元的值都被复位为0,当然也实现不了热启动的要求。通过看keil MDK自带的启动代码Startup.s,在这个启动代码中也并没有发现将整个RAM区域清零的语句。反汇编程序,发现从启动代码执行结束到跳转到main函数过程中,编译器还执行了很多库函数,其中__scatterload_zeroinit函数将所有W/R RAM都初始化为0(默认设置下)。为了判断冷、热启动,必须人为控制某些特定RAM在复位时不被编译器初始化为0。通过查找编译器手册,在为处理器的RAM中分出一块小片RAM,设置为NoInit格式(不对其初始化为0),如下图:

clip_image002

然后使用__at关键字将冷、热启动标志位定位到这个NoInit区域:

uint32 unStartFlag __at (0x40003FF4);

这样,当热启动时,变量unStartFlag所在的内存区域就不会被初始化为0,也实现了冷热启动的判断。

定义铁电0xFF7~0xFF8区域存储冷启动次数

0xFF9~0xFFA区域存储热启动次数

0xFFB~0xFFC区域存储总启动次数

STC单片机烧录

阅读数 54

没有更多推荐了,返回首页