大家好、
我正在使用 FR2311进行一个项目。 要求比较简单。 按键将系统置于 LPM4.5中、
再次按下 EXIT LPM4.5..... 就像这样。
我认为一个小时就足够完成这项工作了。 但是,这花费了我将近一整天的时间,问题是
仍在等待中 ( 所以,我来这里寻求帮助。
以下代码在 MSP_EXP430FR2311 LaunchPad 上运行、存在2个问题:
1) 1)它仅在 IDE 的调试模式下工作。
2)它可以从 LPM4.5退出、而无需按键。 因为键充当电源开关,
无意中退出/进入 LPM4.5是无法忍受的。
问题很容易重现、希望有些人能提供一些线索。
此外,我还有一个问题:进入中断服务程序中的 LPMx.5,它是否可以?
提前感谢。
Seafesse
/*********
用于 MSP430 V6.50
MSP-EXP430FR2311 LaunchPad
P1.1----的 IAR 密钥
使用 P1.1作为开关。
P1.0 P2.0代表2个状态:进入 LPM4.5或从 LPM4.5退出
1)
进入 LPM4.5-P2.0高电平-
2)绿色 LED
从 LPM4.5-P1.0高电平-
PS:低电平红色 LED -高电平边缘
/
#include"msp430fr2311.h"
#define u08_t unsigned char
#define U16_t unsigned int
#define u32_t unsigned long
#define MCLK_FREQ_MHz 8
/*******
===================================================================================================================================
(三 /
__否_初始化 u08_t key_ok_arry[5];
/*********
===================================================================================================================================
(三 /
void Software_Trim (void);
void InitSysClk (void);
void Init_GeneralIO (void);
void StopAllPerihClock (void);
void InitKeyBuf (void);
void SetPwmAndAD_IO (void);
void InitPwm_Pole1Pole2 (void);
void PowerOffTheSystem (void);
/*********
=================================== ========================================================================
(三 /
void main( void ){
__no_operation();
__no_operation();
// if (PMMLPM5IFG & PMMIFG)
IF (SYSRSTIV = SYSRSTIV_LPM5WU)
{
_DELAY_CYCLES (1000);
PMMCTL0_H = PMMPW_H;
PMMIFG &=~PMMLPM5IFG;
InitSysClk();
InitKeyBuf();
SetPwmAndAD_IO();
InitPwm_Pole1Pole2();
while (1)
{
_bis_SR_register (GIE|LPM4_BITS);
__no_operation();
__no_operation();
}
}
其他
{
PowerOffTheSystem();
}
}
空 InitKeyBuf (空)
{
u08_t i;
for (i=0;i<5;i++)
{
key_ok_arry[i]=1;
}
}
/*********
函数名:
100us脉宽 InitPwm_Pole1Pole2 **说明:100Hz
********* /
void InitPwm_Pole1Pole2 (void)
{
TB0CTL = TBSSEL_2 + TBCLR;//SMCLK = 8MHz
TB0CTL |= TBIE + ID_3;//1MHz
TB0CCR0 = 5000-1;//10ms
TB0CCR1 = 50;
TB0CCR2 = 5000-50;
TB0CCTL0 = 0;
TB0CCTL1 = 0;
TB0CCTL2 = 0;
增减计数模式 μ s
TB0CTL |=MC_3;
}
/*********
函数名:
说明:InitSysClk **
MCLK:8MHz
/
void InitSysClk (void)
{
_bis_SR_register (SCG0); //禁用 FLL
CSCTL3 |= SELREF_REFOCLK; //将 REFO 设置为 FLL 基准源
CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3;// DCOFTRIM = 3、DCO 范围= 10MHz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
_DELAY_CYCLES (4);
_BIC_SR_register (SCG0); //启用 FLL
Software_Trim (); //软件调整以获得最佳 DCOFTRIM 值
CSCTL4 = SELMS_DCOCLKDIV | SELA_REFOCLK;//将默认 REFO (~32768Hz)设置为 ACLK 源、ACLK = 32768Hz
操作
{
CSCTL7 &=~(XT1OFFG | DCOFFG); //清除 XT1和 DCO 故障标志
SFRIFG1 &=~OFIFG;
} while (SFRIFG1和 OFIFG); //测试振荡器故障标志
CSCTL8=0x0007;
}
/*********
函数名:**初始
**说明:
/
void Init_GeneralIO (void)
{
P1OUT =BIT1;
P1SEL0=0;
P1SEL1=0;
P1REN=BIT1;
P1DIR = BIT0;
//低边沿
P1IES = 0;
P1IFG = 0;
P1IE = BIT1;
P2OUT = BIT0;
P2SEL0 = 0;
P2SEL1=0;
P2REN=0;
P2DIR = BIT0;
P2IES = 0;
P2IE=0;
PM5CTL0 &=~LOCKLPM5;
}/
*********
函数名:
是PWM输出 SetPwmAndAD_IO **说明:P1.0/P1.1是AD输入 P1.6/P1.7/P2.0
/
void SetPwmAndAD_IO (void)
{
P1OUT = BIT0+BIT1;
P1SEL0 = 0;
P1SEL1 = 0;
P1REN = BIT1;
P1DIR = BIT0;
P1IES = 0;
P1IFG=0;
P1IE = 0;
P2OUT=0;
P2SEL0 = 0;
P2SEL1 = 0;
P2REN = 0;
P2DIR = 0;
P2IES = 0;
P2IE=0;
PM5CTL0 &=~LOCKLPM5;
}
/*********
函数名:
说明:TBIFG_10ms_ISR **
IBIFG
/
#pragma vector=TIMER0_B1_vector
__interrupt void TBIFG_10ms_ISR (void)
{
TB0CTL &=~ TBIFG;
/********* 键_确定********** /
key_ok_arry[4]= key_ok_arry[0];
IF (P1IN 和 BIT1)
{
key_ok_arry[1]= 1;
}
其他
{
key_ok_arry[1]= 0;
}
key_ok_arry[0]&&(key_ok_arry[1]|key_ok_arry[2]|key_ok_arry[3]);
key_ok_arry[0]|=(key_ok_arry[1]和 key_ok_arry[2]和 key_ok_arry[3]);
key_ok_arry[3]= key_ok_arry[2];
key_ok_arry[2]= key_ok_arry[1];
//高-低-边缘按键
if ((~key_ok_arry[0])&(key_ok_arry[4]))
{
PowerOffTheSystem();
返回;
}
}
/*********
函数名:
说明:StopAllPerihClock **
/
void StopAllPerihClock (void)
{
CSCTL8 = 0;
TB0CTL = TBCLR;//SMCLK = 8MHz
TB1CTL = TBCLR;
ADCCTL0 = 0;
RTCCTL =0;
}
/*********
函数名:软件_调整
**说明:
/
void Software_Trim (void)
{
U16_t oldDcotTap = 0xFFFF;
U16_t newDcotTap = 0xFFFF;
U16_t newDcoDelta = 0xFFFF;
u16_t bestDcoDelta = 0xFFFF;
U16_t csCtl0Copy = 0;
U16_t csCtl1Copy = 0;
U16_t csCtl0Read = 0;
U16_t csCtl1Read = 0;
u16_t dcoFreqTrim = 3;
u08_t endLoop = 0;
操作
{
CSCTL0 = 0x100; // DCO 抽头= 256
操作
{
CSCTL7 &=~DCOFFG; //清除 DCO 故障标志
} while (CSCTL7 & DCOFFG); //测试 DCO 故障标志
_DELAY_CYCLLES (((U16_t) 3000 * MCLK_FREQ_MHz);//等待 FLL 锁定状态(FLLUNLOCK)保持稳定
//建议等待24个经过分频的 FLL 参考时钟周期
while (((CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1))和&((CSCTL7 & DCOFFG)= 0));
CSCCtl0Read = CSCTL0; //读取 CSCTL0
CSCCtl1Read = CSCTL1; //读取 CSCTL1
oldDcoTap = newDcoTap; //记录上次的 DCOTAP 值
NewDcoTap = csCtl0Read & 0x01ff; //获取此次的 DCOTAP 值
dcoFreqTrim =(csCtl1Read & 0x0070)>>4;//获取 DCOFTRIM 值
if (newDcoTap < 256) // DCOTAP < 256
{
newDcoDelta = 256 - newDcoTap; // DCPTAP 和256之间的增量值
if ((oldDcotap!= 0xFFFF)&&(oldDcotap >= 256)// DCOTAP 交叉256
endLoop = 1; //停止 while 循环
其他
{
dcoFreqTrim --;
CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim<4);
}
}
其他 // DCOTAP >= 256
{
newDcoDelta = newDcoTap - 256; // DCPTAP 和256之间的增量值
if (oldDcoTap < 256) // DCOTAP 交叉256
endLoop = 1; //停止 while 循环
其他
{
dcoFreqTrim++;
CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim<4);
}
}
if (newDcoDelta < bestDcoDelta) //记录最接近256的 DCOTAP
{
csCtl0Copy = csCtl0Read;
csCtl1Copy = csCtl1Read;
bestDcoDelta = newDcoDelta;
}
}while (endLoop =0); //轮询直至 endLoop = 1
CSCTL0 = csCtl0Copy; //重新加载锁定的 DCOTAP
CSCTL1 = csCtl1Copy; //重新加载锁定的 DCOFTRIM
while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));//轮询直到 FLL 锁定
为止}
/*********
函数名:
说明:进入LPM4.5进入极低的功耗 PowerOffTheSystem **
/
void PowerOffTheSystem (void)
{
__no_operation();
StopAllPerihClock();
_BIC_SR_register (GIE);
WDTCTL = WDTPW + WDTHOLD;
init_GeneralIO();
PMMCTL0_H = PMMPW_H; //打开 PMM 寄存器进行写入
PMMCTL0_L &=~(SVSHE); //禁用高侧 SVS
PMMCTL0_L |= PMMREGOFF; //并设置 PMMREGOFF
PMMCTL0_H = 0; //锁定 PMM 寄存器
_bis_SR_register (LPM4_bits | GIE);
}