打印传感器状态时出现无限循环错误 pic18f4520

问题描述

我的代码有问题,我正在编写一个微控制器 pic18f4520 来读取两个反射传感器,但是当我从任何传感器打印状态时,就会变成一个无限循环,让我更好地解释

示例:

  • 传感器 A
  • 传感器 B
  1. 当传感器 A 开启时 (0) 打印“BAG INICIALIZE”
  2. 当传感器 A 和 B 开启时 (0) 打印“BAG IN PLACE”
  3. 当传感器 A 和 B 关闭时 (1) 打印“BAG REMOVED”

印刷很好,但无限

我的参考代码是:一切都在 while(1)

//reading ports when boot
//Sensor A = J13 
//Sensor B = J6

void USART_EnviaMsg(char *str);
void USART_EnviaMsg (char *msgout)
{
    char letraout;
    while(*msgout != 0x00)      //As long as I don't come across the null at the end of the string.
    {
        letraout=*msgout;       //Read the pointer letter.
        msgout++;               //pointer go forward.
        while (TXIF==0){}       //wait to send
        TXREG=letraout;         //send the letter.
    }                
}

while(1){
 if ((PORTDbits.RD3 == 0) && (J6 == 1)) 
        {
                __delay_ms(100);         //Antibounce.
       if (PORTDbits.RD3 == 0) //I check again that it is pressed.
            {
            J6 = 0;
            }
        }
      if (PORTDbits.RD3 == 1)
            J6 = 1;
            //Bolsa A - J13...
      if ((PORTDbits.RD2 == 0) && (J13 == 1)) //J13
        {
                __delay_ms(100);         //Antibounce.
      if (PORTDbits.RD2 == 0) //I check again that it is pressed.
            {
            J13 = 0;
            }
        }
      if (PORTDbits.RD2 == 1)
                J13 = 1;
       
      if (J13 == 0 && J6 == 0){
          ValorBag = 2;
          USART_EnviaMsg("BAG IN PLACE");
          USART_EnviaMsg(CRLF);
      }
      if (J13 == 0 && J6 == 1){
          ValorBag = 0;
          USART_EnviaMsg("BAG PUTTING");
          USART_EnviaMsg(CRLF);
      }
      if (J13 == 1 && J6 == 0){
          ValorBag = 0;
          USART_EnviaMsg("BAG ERROR");
          USART_EnviaMsg(CRLF);
      }
      if ((J13 && J6)== 1){
          ValorBag = 1;
          USART_EnviaMsg("BAG REMOVED");
          USART_EnviaMsg(CRLF);
      }
}

如果某些条件为真,则打印无限循环 例子:

"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"

解决方法

将两个输入位打包成一个整数。记住它的最后一个值,只有在它自上次以来发生变化时才写出消息,如下所示:

void foo()
{
    static const int SensorA=1;
    static const int SensorB=2;
    int Status =0; //Bitmap of above Bitmasks
    int lastStatus=Status; //Bitmap of above Bitmasks
    while(1)
    {
        if ((PORTDbits.RD3 == 0) && (Status & SensorA))
        {
            __delay_ms(100);         //Antibounce.
            if (PORTDbits.RD3 == 0) //I check again that it is still pressed.
            {
                Status &= ~SensorA; //Clear bit
            }
        }
        if (PORTDbits.RD3 == 1)
            Status |= SensorA; //Set bit

        if ((PORTDbits.RD2 == 0) && (Status & SensorB))
        {
            __delay_ms(100);         //Antibounce.
            if (PORTDbits.RD2 == 0) //I check again that it is still pressed.
            {
                Status &= ~SensorB; //Clear bit
            }
        }
        if (PORTDbits.RD2 == 1)
            Status |= SensorB; //Set bit

        if (Status == lastStatus) continue; //nothing changed

        lastStatus = Status; //Changed. Remember current Status. Issue Msg only once.
        switch (Status)
        {
            case 0:
                USART_EnviaMsg("A=0,B=0");
                break;
            case SensorA:
                USART_EnviaMsg("A=1,B=0");
                break;
            case SensorB:
                USART_EnviaMsg("A=0,B=1");
                break;
            case SensorA+SensorB:
                USART_EnviaMsg("A=1,B=1");
                break;
        }
    }
}