无限循环并不是防止程序“跑飞”的,而是防止main()返回 您所在的位置:网站首页 FLASH编程挂起和擦除挂起 无限循环并不是防止程序“跑飞”的,而是防止main()返回

无限循环并不是防止程序“跑飞”的,而是防止main()返回

2024-06-09 11:36| 来源: 网络整理| 查看: 265

Flash存储器已成为嵌入式系统中数据和程序最主要的载体。但是在对Flash进行 编程或 擦除的操作过程中,如果 单片机需要处理一些紧急的情况(如中断、数据存储等等),就需要暂停相对比较消耗时间的Flash编程/擦写过程,优先处理这些紧急情况。这对Flash存储器的工艺水平及控制技术提出了更高的要求。

图1编程/擦除挂起操作时序

  瑞萨公司推出的R8C/1B单片机采用改进的Flash存储器工艺,大大缩短了编程/擦除挂起的时间,使其能够更加及时地响应中断或进行其他操作。

  Flash编程/擦除挂起功能   所谓挂起功能,是指当Flash模块正在执行编程或擦除操作时,CPU改写模式可以暂停当前的Flash操作,将编程或擦除挂起的功能。在编程/擦除挂起的过程中,用户ROM区的内容可通过程序来读取。   瑞萨R8C/Tiny单片机在R8C/18以后的产品中(如R8C/1B),较之以前的产品(如R8C/15),Flash存储器在编程/擦除挂起功能上有了很大改进,其具体功能的比较请参见表1,编程/擦除挂起操作时序请参见图1。   由表1可以看出,R8C/1B单片机所采用的Flash模块工艺在以下方面拥有明显的优势。

表1Flash存储器功能比较表

 

  挂起时间延迟最长为97μs+6个CPU时钟周期,最长的挂起重新启动时间延迟为3μs+4个CPU时钟周期;R8C/15单片机Flash模块只能在擦除时挂起,但改进Flash工艺的R8C/1B单片机在编程时也可以实现挂起功能;擦除时可以编程。   图1为编程/擦除挂起的简单示意图,在编程/擦除开始之后,如果发生了某个中断请求,在等待一段挂起延迟之后,CPU转向中断子程序的处理。中断处理子程序执行之后,Flash存储器继续执行编程或擦除过程,直至操作结束。

  Flash编程/擦除挂起功能的实现   ●  EW0模式与EW1模式   CPU改写模式是通过固化在单片机程序存储器中的软件命令对Flash存储器进行编程的形式,适合对单片机进行在应用中编程(IAP)的场合,即能够在不使用Flash编程器,且将单片机安装在电路板的状态下实现对Flash的改写。   CPU改写模式分为擦除/编程0模式(EW0模式)和擦除/编程1模式(EW1模式)。   这两种模式的根本区别在于改写控制程序的执行区域不同。如图2所示,EW0模式中,改写控制程序在Flash存储器以外的区域执行,因此在这种模式下可以改写所有的用户ROM区。EW1模式中,改写控制程序依然存放在用户ROM区的某一个块中,并在此区域执行,因此在这种模式下,除了存有改写控制程序的块以外,其他的用户ROM区都可以被改写。

图2EW0模式与EW1模式

  在执行擦除/编程的过程中,在EW0模式下CPU处于正常运行的状态,而在EW1模式下CPU处于保持状态。

  ●  Flash编程/擦除挂起的设定   相关的寄存器   与Flash编程/擦除挂起相关的寄存器是闪存控制寄存器4(FMR4),FMR4有6个位均与编程/擦除挂起功能相关,请参见表2。

表2闪存控制寄存器4

  EW0模式的擦除挂起设定   对于EW0模式转移到擦除挂起时,首先需要将FMR40位置“1”(允许挂起)、FMR41位置“1”(请求擦除挂起),然后延迟一段时间(97μs+CPU时钟周期×6),在确认FMR46位为“1”(允许读)后才能对用户ROM区进行存取。如果将FMR41位置“0”(重新启动擦除),就重新开始自动擦除。设定过程如图3所示。注意,在EW0模式,请将所使用中断的中断向量表和中断程序存储在RAM区中。

  EW1模式的擦除挂起设定

图3EW0模式的擦除挂起设定

  对于EW1模式,首先需要将擦除挂起功能设定为有效,即将FMR40位置“1”(允许挂起),并预先将需要响应的可屏蔽中断设定为中断允许状态。这样在执行块擦除命令后,如果该中断产生,经过一段时间延迟后(电气特性推荐值为:97μs+CPU时钟周期×6),就能执行擦除挂起,并接受中断请求。如果发生中断请求,FMR41位就自动变为“1”,执行擦除挂起。在结束中断处理后,如果自动擦除还没有结束(FMR00位为“0”),就必须将FMR41位置“0”,重新开始自动擦除。设定过程如图4所示。

图4EW1模式的擦除挂起设定

  在EW1模式下执行擦除指令进行Flash擦除时(典型值为200ms/1K字节块),CPU虽处于HOLD状态,但可以接受中断响应,实现分时擦除。利用这个工作原理,下面给出一个R8C/1B单片机的应用实例,利用Timer(定时器)中断和Flash擦除挂起功能实现对擦除时间的估算。   使用TimerX定时1ms,Flash擦除过程中每1ms挂起一次,进入中断处理程序并调整计时变量g_Timers。在擦除结束后,g_Timers所存储的就是擦除时间的估算值。   例程如下。   #include "sfr_r81b.h"   unsigned int g_Timers;//总擦除时间计数变量 

       /* 定时器X中断处理函数 */   #pragma interrupt timerX_ISR   void timerX_ISR(){   g_Timers++;   }   /* 检查Data Flash状态寄存器 */   unsigned char checkStatusRegister(){   return fmr07|fmr06;   }   /* 清除DataFlash状态寄存器  */   void clearStatusRegister(){    *((unsigned char *)0x2400) = 0x50;//执行清除状态寄存器软件命令   }   /* 块擦除 */   unsigned char eraseBlock(unsigned int adr){   unsigned char   result="1";   asm("FCLR I");//关中断   fmr01 = 0;   fmr01 = 1;//进入CPU改写模式   fmr11 = 0;   fmr11 = 1;//设置为EW1模式&nb  

sp;   fmr40 = 0;   fmr40 = 1;//允许中断擦除挂起    asm("FSET I");//开中断   g_Timers = 0;//计数值清零   prex=0x32-1;tx=0x32-1;//定时值1ms   txs=1;//定时器X开始计数   *((unsigned char *)adr) = 0x20;//执行块擦除软件命令   *((unsigned char *)adr) = 0xD0;   while(fmr00 != 1){//判断擦除是否结束   fmr41 = 0;//中断返回后继续擦除   }   txs=0;//定时器X停止计数   fmr01 = 0;//退出CPU改写模式   if(!checkStatusRegister()){//查看状态寄存器   result = 0;//擦除成功   }   else //擦除失败   clearStatusRegister();//清除状态寄存器   return result;   }   /* 对MCU进行初始化 */   void initMCU(){   unsigned char i="0";   asm("FCLR I");//关中断   //将CPU时钟切换为主时钟20MHz   prcr = 1;//解除对cm0,cm1,ocd寄存器的写保护   cm13 = 1;//接通 Xin-Xout   cm15 = 1;//Xin-Xout驱动能力:高   cm05 = 0;//Xin-Xout启动   cm16 = 0;//无分频模式   cm17 = 0;   cm06 = 0;//使CM16,CM17有效   while(1){//等待主时钟振荡稳定   if(!ocd3){   if(i>=10) break;   else ++i;   }   }   ocd2 = 0;//选择主时钟   prcr = 0;//设定对cm0,cm1,ocd寄存器的写保护   //设置定时器   txmr=0x00;//定时器X设为定时器模式   tcss=0x11;//选择计数源为f8   txic=0x07;//定时器X中断优先级为7   asm("FSET I");//开中断   }

  /* 主函数 */   void main(void)   {   unsigned char flag;    initMCU();//对MCU进行初始化    flag = eraseBlock(0x2400);//擦除大小为1kB的块A,块首地址为2400H    while (1);   }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有