当PIC接收到一个字符时(当按下一个按钮时),我试图让led一直亮着,默认情况下,led是关闭的,但我似乎找不到解决方案。
我在3个月的学习使用微控制器(特别是PIC)与MPLABX IDE编码,并开始了解UART通信。一开始我试着在收到一个字符时打开/关闭一个led灯,效果很好,但现在我试着在按下一个按钮时保持led灯的活动状态,但无法真正解决这个问题。我的代码是这样的中断函数:
//#define LED RB5
void __interrupt () ISR (void)
{
if(RCIF) // data is received
{
data = RCREG; // get the value
if (data == '1') // if value received is '1'
LED = 1; //turn ON led
RCIF = 0;
}
LED = 0; // turn OFF led
}
使用上面的代码可以使led的开关非常快,而我一直按下一个按钮,并不是我真正想要的。我希望有人能帮助我了解我需要做什么。谢谢!
最佳答案
我建议你在app.c中为此创建一个状态机。
用一个enum
和一个struct
定义一些状态,以保持状态并将它们放在app.h中,将app.h
包含在希望使用此模块的文件中(例如,您的系统中断.c文件)。
例如,您可以这样做:
typedef enum{
IDLE,
START_RECEIVING,
STILL_RECEIVING,
}uart_state_t;
typedef struct{
uart_state_t current_state;
}uart_module_t
volatile uart_module_t uart_module = {0}; // initial state = IDLE, needs to be volatile because it will be updated via interrupt
然后创建一个函数来服务您的状态机。这将处理它当前所处的状态,并根据需要转换到其他状态。例如,状态机在
IDLE
状态下启动,但一旦触发中断并设置了RCIF
位,您将转换到START_RECEIVING
状态,该状态将点亮LED,然后转换到STILL_RECEIVING
状态,在该状态下,它将轮询RCIF
位,直到清除。看起来像这样:void uartFSM(void){
switch(uart_module.current_state){
case IDLE:
{
break;
}
case START_RECEIVING:
{
LED = 1; // Turn LED on
uart_module.current_state = STILL_RECEIVING; // state update
break;
}
case STILL_RECEIVING:
{
if(!RCIF){
// done receiving
LED = 0; // Turn LED off
uart_module.current_state = IDLE; // state update
}
break;
}
default:
{
// whoops
break;
}
}
}
现在你的打断会是这样的:
void __interrupt () ISR (void)
{
if(RCIF) // data is received
{
data = RCREG; // get the value
// if value received is '1'
if (data == '1') uart_module.current_state = START_RECEIVING; // state update
}
}
现在,您只需确保调用
uartFSM()
中的某个位置,以便状态机得到服务。关于c - PIC16F1937和UART:接收时保持LED导通,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56004826/