This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/MSP430FR5994:作为LPM中的非易失性存储写入FRAM

Guru**** 2583225 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/615583/ccs-msp430fr5994-writing-to-fram-as-non-volatile-storage-in-lpm

部件号:MSP430FR5994

工具/软件:Code Composer Studio

尊敬的先生:

   我一直在测试使用非易失性存储到FRAM的LPM。  休眠模式可以工作,但调试器无法读回存储的正确FRAM值。  示例的操作已记录在案

在main()之上。  代码如下:

//************************************************************************************************
// MSP430G2xx演示- WDT,低功耗模式,间隔溢出ISR,DCO SMCLK
//
//说明:使用WDT ISR定时的软件进入LowPowerMode。 LED
//休眠时将关闭,端口1中断将唤醒MCU并打开
// LED。 根据默认值,MCU将在大约250 * 32ms的时间休眠
//本示例中用于WDT的DCO/SMCLK时钟源。
// ACLK = N/A,MCLK = SMCLK =默认值

// 6秒后,WDT中断设置为低功耗模式。
//通过使用WFP 1.3 上的低到高输入进行唤醒,它会使端口1中断
返回到正常模式。 因为这是一个上升的边缘,所以需要在中下拉
示波器探测器的形式等
在进入睡眠模式之前,它会将0到10的10个值写入0x4000的帧内存中。
已使用向导和“持久性”关键字。

如果调试器启动程序,它会将FRAM数据重新设置为0,并且将丢失。
程序
设置为在启动时读取fram loc 1和2。 如果这两个位置分别为1和0,则会打开
绿色LED。 这样,您就不必从调试器开始检查fram位置。

//使用3.2ma和.22ma (睡眠)
//必须卸下所有跳线并测量3.3V跳线的电流

// MSP430G2xxx
//-----------
///|\\| Xin|-
//||||
//--|RST XOUT|-
//||
//| WFP 1.0 |-->LED
//
// Aldo Briano
//德州仪器(TI)
// 2010年7月
//************************************************************************************************
#include <MSP4S.h>
//#include "driverlib.h"

静态int wdtCounter =0;

#pragma persistent(FRAM_ARr)
unsigned long * frm_arr;


/************************************************************************
* Pre_init()
***************** /
int _system_pre_init(void)

//停止监视计时器
WDT_A_HOLD (__MSP430_BASEADDRESS_WDT_A_);//停止WDT

// gPIO_setOutputHighOnPin (gPIO_PORT_P4,gPIO_PIN0);
// gPIO_setAsOutputPin (gPIO_PORT_P4,gPIO_PIN0);

/*=========================================== */
/*如果段初始化,请选择*/
/*是否应执行。 */
/* return: 0忽略初始化*/
/* 1运行初始化*/
/*=========================================== */
返回1;
}

********************

*
******************* /
Void主(void)

INT A;

PM5CTL0 &=~LCKLPM5;//禁用GPIO开机默认高阻抗模式
frm_arr=(unsigned Long*) 0x4000;

//为1.0 LED1开发的WFP:
P1SEL0 &=~BIT0;//为WFP 1.0 选择GPIO
P1SEL1 &=~BIT0;
P1DIR || BIT0;//将WFP 1.0 设置为输出方向
P1OUT || BIT0;//在1.0 处打开红色LED1

//为1.1 LED2开发的WFP:
P1SEL0 &=~BIT0;//为WFP 1.0 选择GPIO
P1SEL1 &=~BIT0;
P1DIR || BIT1;//将WFP 1.0 设置为输出方向
P1OUT |= BIT1;//打开grn LED

IF ((FRAM_ARr[1]== 1)&&(FRAM_ARr[2]== 2))
P1OUT || BIT1;//打开1.1 处的绿色LED指示灯
否则
P1OUT &=~BIT1;//关闭1.1 处的绿色LED


//在WFP 1.3 上设置上升边缘中断:
P1SEL0 &=~BIT3;//为WFP 1.3 选择GPIO
P1SEL1 &=~BIT3;//select1
P1DIR &=~BIT3;//将目录设置为输入(0)
//P1REN |=(BIT3);//pullup
P1IES &=~BIT3;//上升边缘0->1.
//P1IE |= BIT3 //启用WFP 1.3

//在WFP 5.6 上设置下降边缘中断:(未使用)
/*P5SEL0 &=~BIT6;//为WFP 5.6 选择GPIO
P5SEL1 &=~BIT6;
P5DIR &=~BIT6;//将dir设置为输入
P5REN |=(BIT6);//pullup
P5IES |= BIT6;//下降边缘1->0
//P5IE |= 6 l 3//启用P5,6
*/

WDTCTL = WDT_MDLY_32;//将看门狗计时器时间间隔设置为~32ms
SFRIE1 || WTIE;//启用WDT中断

P1IE |= BIT3;//启用WFP 1.3 中断
__enable_interrupit();

对于(;;)

A=A+1;
}
}

/***************************************************************************
看门狗计时器中断服务例程
***************** /
#pragma vector=WDT_vector
__interrupt void watchdog计时器(void)

int i;

IF (wdtCounter == 200)//现在为6秒而不是8秒

P1OUT = 0x00;// WFP 1.0 关闭
WdtCounter =0;

//存储FRAM数据:
frm_arr=(unsigned long *) 0x4000;
对于(i=0;i<10;i++)
*(frm_arr++)= i;

_BIS_SR (LPM3_Bits + GIE);//输入带中断的LPM3
//enterLPM35();//输入3.5
}
否则

WdtCounter++;
}

}
/*******************************************************************************
端口1中断服务
***************** /
#pragma vector=Port1_vector
__interrupt void Port_1 (void)

wdtCounter =0;//重置看门狗计时器计数器
P1OUT |= 0x01;//打开LED
P1IFG = 0x0;
_BIC_SR (LPM3_EXIT);//从低功率模式唤醒

}

/*******************************************************************************
按钮S1的端口5中断服务例程
***************** /
#pragma vector=PORT5_vector
__interrupt void Port_5 (void)

wdtCounter =0;//重置看门狗计时器计数器
P1OUT |= 0x01;//打开LED
P5IFG = 0x0;
_BIC_SR (LPM3_EXIT);//从低功率模式唤醒

}

/*******************************************************************************
*进入低功率模式3.5
***************** /
Void enterLPM35()

//配置按钮S2 (WFP 5.5)中断
// gPIO_selectInterruptEdge (gPIO_PORT_P5,gPIO_PIN5,gPIO_HIGH TO LOW _Transition);
// gPIO_setAsInputPinWithPullUp阻 抗器(GPIO_PORT_P5, gPIO_PIN5);
// gPIO_clearInterrupt (gPIO_PORT_P5,gPIO_PIN5);
// gPIO_enableInterrupt (gPIO_PORT_P5,gPIO_PIN5);

//设备进入时,请求禁用内核电压调节器
// LPM3 (或LPM4),这样我们就可以有效地进入3.5 (或4.5)。
//PMM_turnOffRegulator();

PMMCTL0 &=~BIT4;//关闭电脑控制器
//在启用中断的情况下进入LPM3模式
__bis_sr_register (LPM3_bits + GIE);
//___之二_SR_REGISTER (LPM4_BITS + GIE);
__no_operation();
}

谢谢!

John

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,John:

    我看到了一些我认为需要更改以正确使用FRAM的事情:

    1.使用#pragma persistent时,变量或数组需要有显式初始化的值(如果需要,可以为0)。

    2.为frm_arr使用指定大小的数组,以便编译器和链接器为要存储的内容保留正确数量的FRAM。

    #pragma persistent(FRAM_ARr)
    unsigned int fRAM_arr[10]={0}; 

    3. 此部件存在问题:

    //store FRAM data:
    frm_arr=(unsigned long *) 0x4000;
    for (i=0;i<10;i++)
    *(frm_arr++)=i; 

    我们不应该将FRAM设置为绝对地址-当我们使用#pragma persistent和MPU工具进行自动分区时,我们不知道放置了哪个地址的FRAM_ARr。 但它的优点是我们不需要知道-我们可以像常规数组一样访问FRAM_ARr。

    #pragma persistent(FRAM_ARr)
    unsigned int fRAM_arr[10]={0};
    
    ...
    
    for (I=0; I<10; I++)
    frm_arr[i]= i; 

     检查FRAM值的提示-您实际上可以使用调试器执行此操作,而不会擦除它们-单击CCS中调试图标旁边的小下拉菜单,然后选择“调试配置...” 确保在左侧选择了您的项目,然后选择"程序"选项卡。 通过选择“仅加载符号”,您可以使其在调试时不加载代码,这意味着FRAM不会被擦除。 但是,请记住,当您更改某些内容并希望加载新代码时,您需要将此设置反转回“加载程序”。

    此致,

    Katie

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢Katie,你是救星:

    我们会尽快来这里看看的。 可能是“NOINIT”对我很有效,因为这样调试程序就不会重新定义变量。



    谢谢!

    John
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢,Katie

    一切都很好。

    John