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/MSP430FR2355:MSP430FR2355

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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/924178/ccs-msp430fr2355-msp430fr2355

器件型号:MSP430FR2355

工具/软件:Code Composer Studio

你好。 我正在尝试创建一个通过超声波传感器测量距离的系统。 如果距离低于最小距离、系统会发出信号、同时将红色 LED (LED1、P1.0)置于高电平、并启动与系统连接的扬声器。 如果距离高于最小距离、则系统会将红色 LED 置于低电平并停止扬声器、但将绿色 LED (LED2、P6.6)置于高电平。 我希望我的系统的功能在这里清晰明了。 我刚才描述的这些功能都运行良好、并为我提供正确的结果。 现在、我要创建一个开始/停止按钮(我使用 S1、P4.1)。 此按钮允许用户手动开始测量并停止测量。 当系统等待该输入时、它会将自身置于睡眠模式。 因此、我使用按钮 S1创建了一个中断。 现在我的问题是、一旦按下按钮、系统就开始测量距离(因此该部件工作正常)、但再次按下按钮、系统将不会返回睡眠模式。 我知道问题所在的位置、但无法真正解决。 测量本身处于 while 循环中、因此无法离开循环并结束中断。 我的问题是、是否有合适的解决方案、以便我可以按一次按钮来启动系统以测量距离、再次按下按钮以停止测量并让系统返回睡眠模式。 请提供任何帮助。

#include "driverlib.h"
#include "rom_driverlib.h"
#include "Board.h"
#include "us_sensor.h"

#include "us_sensor1.h"#include "压 电.h"


// MCLK 的目标频率(单位为 kHz
)#define CS_MCLK_NEW_LLR1000
/void 比率







(/MCLK/FLLRef void);void CS void 30 (void gpio

WDT_A_HOLD (WDT_A_base); //停止看门狗计时器

init_gpio(); // ES winitrd Nur LED I/O festgelegt

init_cs(); //Initalisiert das 时钟系统
// Submit DCO als Oszillator und ACLK als Taktquelle (winitrd für US-Sensoren benötigt)

sr04_init(); //Init us 传感器
sr04_init1(); //Init us-sensor1.

压电初始化(); //Init 压电扬声器
压电阻();

_bis_SR_register (GIE + LPM0_bits); //启用全局中断


}

void init_gpio (void){
//将 LED1设置为输出方向
GPIO_setAsOutputPin (
GPIO_PORT_LED1、
GPIO_PIN_LED1
);
//将 LED2设置为输出方向
GPIO_setAsOutputPin (
GPIO_PORT_LED2、
GPIO_PIN_LED2
);
//使用内部上拉电阻将 S1设置为输入方向
GPIO_setAsInputPinWithPullUpResistor (
GPIO_PORT_S1、
GPIO_PIN_S1
);

GPIO_selectInterruptEdge (
GPIO_PORT_S1、
GPIO_PIN_S1、
GPIO_HIGH_TO_LOW_TRANSITION
);

GPIO_clearInterrupt (
GPIO_PORT_S1、
GPIO_PIN_S1
);

GPIO_enableInterrupt (
GPIO_PORT_S1、
GPIO_PIN_S1
);

PMM_unlockLPM5 ();
}

void init_cs (void){
//设置 DCO FLL 基准= REFO
cs_initClockSignal (
CS_FLLREF、
CS_REFOCLK_SELECT、
CS_CLOCK 分频器_1
);

//set ACLK = REFO
cs_initClockSignal (
CS_ACLK、
CS_REFOCLK_SELECT、
CS_CLOCK 分频器_1
);

//创建结构变量以存储正确的软件调整值
CS_initFLLPam param ={0};

//设置比率/所需的 MCLK 频率、初始化 DCO、保存修整值
CS_initFLLCalculateTrim (
CS_MCLK_frequed_in_kHz、
CS_MCLK_FLLREF_Ratio、
参数(&P)
);

//清除所有 OSC 故障标志
CS_clearAllOscFlagsWithTimeout (1000);

//启用振荡器故障中断
SFR_enableInterrupt (SFR_oscillator_FAULT_INTERRUPT);
}


#pragma vector=UNMI_Vector
__interrupt void NMI_ISR (void)
{
uint16_t status;
执行{
//如果在超时后仍然无法清除振荡器故障标志,
//在此处捕获并等待。
状态= CS_clearAllOscFlagsWithTimeout (1000);
} while (status!= 0);
}


bool 标志= false;
#pragma vector=Port4_vector
__interrupt void Port_4 (void)
{
uint16_t 距离;
uint16_t 距离1;
if ((P4IES & BIT1)=BIT1){
//在高电平到低电平转换时:
//激活从低到高的转换:打开按钮释放
P4IES &=~BIT1;
GPIO_getInputPinValue (GPIO_PORT_P4、GPIO_PIN1);

_bis_SR_register (GIE); //启用全局中断

sr04_start(); // MESSUNG von US 传感器
sr04_start1(); // MESSUNG von US 传感器
while (1)
{
距离= sr04_get_value (); //Get distance from US-Sensor1
距离=距离/2; //以一种方式计算距离

距离1 = sr04_get_value1 (); //Get distance from US-Sensor2
距离1 =距离1/2; //以一种方式计算距离


if ((distance <= 1500)||(distance1 <= 1500)){ //检查1500mm 处的最小距离;如果 US1或 US2小于最小距离
GPIO_setOutputHighOnPin (GPIO_PORT_LED1、GPIO_PIN_LED1); //将 LED1设置为高电平
GPIO_setOutputLowOnPin (GPIO_PORT_LED2、GPIO_PIN_LED2); //将 LED2设置为低电平
压电起动(); //启动 PWM 信号的压电计时器
}
否则{
压电阻(); //停止来自 PWM 信号的压电定时器
GPIO_setOutputHighOnPin (GPIO_PORT_LED2、GPIO_PIN_LED2); //将 LED2设置为高电平
GPIO_setOutputLowOnPin (GPIO_PORT_LED1、GPIO_PIN_LED1); //set LED1 on Low
}


__no_operation(); //调试器断点位置
}


}
否则{
//在低电平到高电平转换时:
//激活从高到低的转换:按 ON 按钮
P4IES |= BIT1;
}

GPIO_clearInterrupt (
GPIO_PORT_S1、
GPIO_PIN_S1
);
} 

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

    由于 Port4 ISR 中的 while (1)循环、一旦您收到第一个调用(按钮按压)、就永远不会退出 ISR。 由于您启用了 GIE、后续调用(按钮)将调用此调用上方的 ISR、但此调用将永远不会退出、并且您永远不会返回到 main 中的 LPM0。

    我建议您将整个 while (1)移动到 main 中、并且不要在 ISR 中启用 GIE。 相反、只需设置("易失性")标志和 LPM0_EXIT、然后让 main 检查该标志、可能是在 while 循环的开头。

    更一般而言、在 ISR 中设置 GIE 非常危险。 如果您发现自己要这样做、请停下来寻找其他方法来做您想要的事情。

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

    好的、谢谢。 这个项目是我学习的一部分,我实际上正开始学习这样一个环境和这种编码。 正如您说过的、我将 while 循环放在主程序中并设置一个标志、如果我按下按钮并让系统启动和停止测量、该标志将会改变。 我刚开始使用嵌入式系统、因此您的评论帮助我了解了我可以做什么以及我不应该做什么。 再次感谢您的参与。