×
单片机 > 单片机程序设计 > 详情

EFM32片内外设--MSC之不关总中断

发布时间:2020-07-08 发布时间:
|

在上一次对Flash的操作,是在关闭总中断的情况下完成的。但是关闭总中断终归会造成系统响应时间延迟,而且在某些特殊的场合下,关闭总中断也容易造成丢失UART数据,或则SPI数据等现象。


解决的方法就是:既然在擦写Flash时不能进行Flash读操作,因此可以将NVIC的向量表重新映射到RAM,并且将中断响应函数也一并放入RAM中,这样的话,即使在擦写flash操作时有中断需要响应,因此也不会去读取Flash。原则上这样就避免了Flash擦写失败的情况。


硬件环境:G/TG STK


软件环境:将NVIC重新映射到RAM,并且将中断函数也映射到RAM中。由于以下的例子是基于IAR的,因此将函数映射到RAM的关键字是__ramfunc . 在例程中我们将systick的中断函数定义成了__ramfunc void SysTick_Handler(void)。 另外,需要注意一点的是,MSC_ErasePage() ,MSC_WriteWord()等函数在efm32_msc.h中也被定义成了__ramfuc类型。因此,在擦写Flash的时候,就不会再读取Flash的内容了。


例程:


#include

#include

#include

#include "efm32.h"

#include "efm32_chip.h"

#include "efm32_cmu.h"

#include "efm32_msc.h"


//定义NVIC中断向量表,但是需要512字节对齐。ICCARM为IAR的编译器

#if defined (__ICCARM__)

#pragma location=0x20000000

__no_init uint32_t vectorTable[47];

#elif defined (__CC_ARM)

uint32_t vectorTable[47] __attribute__((at(0x20000000)));

#elif defined (__GNUC__)

uint32_t vectorTable[47] __attribute__((aligned(512)));

#else

#error Undefined toolkit, need to define alignment

#endif



volatile uint32_t msTicks;

const unsigned char ucWriteIn[8] = {'a','b','c','d','e','f','g','h',};

unsigned char ucReadOut[8];



__ramfunc void SysTick_Handler(void)

{

    msTicks++;

}


/**************************************************************************

在RAM中创建一张NVIC的表格

*****************************************************************************/

void generateVectorTable(void)

{

    vectorTable[SysTick_IRQn + 16]     = (uint32_t) SysTick_Handler;

    //vectorTable[RTC_IRQn + 16]            = (uint32_t) RTC_IRQHandler;

    SCB->VTOR                             = (uint32_t) vectorTable;

}


void main(void)

{

    CHIP_Init();

    /* Ensure core frequency has been updated */

    SystemCoreClockUpdate();

    

    generateVectorTable();//update the Vector table

    

    //add a timer

    if (SysTick_Config(SystemCoreClock / 1000)) while (1) ;

    

    MSC_Init();//初始化MSC,并使能AUXHFRCO

    

    //__disable_irq();

    

    if(MSC_ErasePage((uint32_t *)0x0fe00000) == mscReturnOk)

    {

        MSC_WriteWord((uint32_t *)0x0fe00000,ucWriteIn,8);

    }

    

    MSC_Deinit();

    

    unsigned char *Point = (unsigned char *)0x0fe00000;

    for(unsigned char i = 0; i < 8; i++)

    {

        if(*(Point + i) == ucWriteIn[i])continue;

        else

        {

            while(1); // error occur

        }

    }

    

    //__enable_irq();

    

    while(1);

}


截图如下:






『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多