【问题标题】:Issue on toggling of the SSR关于切换 SSR 的问题
【发布时间】:2012-06-07 02:16:10
【问题描述】:

我正在使用 Keil C 编写我的程序。我有一些问题,我已经被困了很长时间,我的程序将使用遥控器切换 SSR(固态继电器)。我的程序是如何工作的:首先,有一个学习按钮,它将学习遥控器的任何红外信号,并将存储在“数据”中。当我再次按下遥控器时,它会将数据存储到“TempDATA”中。然后我的程序将比较两者并检查是否有错误。如果没有错误,它将切换 SSR 并且绿色 LED 将亮起。如果有任何错误,它将打开红色 LED。

但是,问题是,它会触发 3 次而不是一次。因此,当没有错误时,它将打开 SSR 'ON,OFF,ON'。如果再次按下遥控器按钮,SSR 将“关闭、打开、关闭”。如果有任何错误,它将显示 'EEE' 而不是 1 'E'。我该如何解决这个问题?

/***********************Problem Solved************************/

通过添加延迟:

while(1)
{  
    if(Data_Ready)                   //Data_Ready = 1
    {
               /*insert delay here*/
               Data_Ready = 0; 
               Result = 1;
               for(j=0;j<30;j++)              
               .
               .
               .

问题解决了。

/****************************************MAIN*******************************************/
void main(void)
{   
unsigned char Result=0; 
unsigned int j;
unsigned int x =0;                              
TMOD = 0x21;          //Enable Timer 1 for 2nd Serial Port  & Timer0
TH1 = 0xFD;           //9600 Baud Rate
SCON0 = 0x50;        
SSR = 0;
Learn = 0;          
RedLED = 0;           
GreenLED= 0;

IE = 0x84;            //Enable External Interrupt 1                                                         
IT1 = 1;              //Set External Interrupt 1 to Edge Triggered.



while(1)
{  
    if(Data_Ready)                   //Data_Ready = 1
    {   
        Data_Ready = 0; 
        Result = 1;
        for(j=0;j<30;j++)                //Loop 30 times
        {
            if(DATA[j] != TempDATA[j])   //Compare DATA to TempDATA
            { 
                Result = 0;     
                break;                   //break from loop
            }               
        }//end for

        if(Result)                   
        {
            Result = 0;
            GreenLED = 1;            //Turn ON GreenLED
            RedLED = 0;              //Turn OFF RedLED

            SSR = ~SSR;              //Toggle SSR to ON and OFF


            SerialTx('S');
            SerialTx('S');
            SerialTx('R');

        }
        else
        {   
            Result = 0;
            RedLED = 1;              //Turn ON RedLED
            GreenLED = 0;            //Turn OFF GreenLED

            SerialTx('E');          //Print E on MTK to show Error       
        }

    }//end if
}//end while

}//end main

当我按下遥控器按钮而不按下学习按钮时,Data_Ready 设置为 1。所以它只会在我按下遥控器按钮而不按下学习按钮时进行比较。

【问题讨论】:

  • 你试过在调试器中运行吗?
  • @MitchWheat 是的,它工作得很好。
  • 顺便说一句,请不要用“//Loop 30 times”评论循环
  • 按钮有适当的去抖动功能吗?
  • @univerio 你指的是学习按钮吗?

标签: c for-loop toggle 8051


【解决方案1】:

问题似乎出在

SSR=~SSR;

命令。第一次,初始状态已经是OFF。因此,在接收到正确的数据时,它会否定 SSR 使其开启。然后三个时间序列将其再次关闭和打开。这对应于您获得正确结果的第一次情况。

现在,下一次接收到正确数据时,SSR 否定之前的状态,该状态已经开启,3 时间序列现在将是 OFF=>ON=>OFF

所以,你可以在这里做的是在发送下一个 ON/OFF 序列之前,故意将 SSR 设置为 OFF 状态。

(我没有用过 Keil C,我在 AVR Studio 上工作过用于编写 ATMEL uCs,所以我只能对所使用的 API 进行猜测。但这个答案是我从明显的逻辑中推断出来的)

希望对你有帮助。

干杯!


更新:

Error[SerialTx('E')] 是否给出正确的输出?

我假设 SSR 的值类似于“0”或“1”或 TRUE/FALSE。

所以在命令 SSR=~SSR 之前设置 SSR=0(或关闭它的东西),条件是它仅在您的 On=>Off=>On 触发器的第一个序列上执行。这将需要一个全局静态标志来保存序列的状态。例如,

static int sequence_in_progress = 0;

当收到信号时:sequence_in_progress +1 每次接收到信号时都会递增。

现在,如果第一次接收到正确的信号,这可以用作将 SSR 设置为关闭的检查:

if(sequence_in_progress==1)
{ SSR=0; //Or something that turns it off}

if(sequence_in_progress==3)
{sequence_in_progress=0;//reset it to zero every time your code finishes processing}

【讨论】:

  • 即使将 SSR 设置为 0 后,问题仍然存在。而且我忘记了 1 个重要部分,即错误 [SerialTx('E')] 也会触发 3 次。
  • 检查我的答案中的更新,它使用全局标志来维护迭代状态,如果第一次收到信号,则有条件地将 SSR 设置为 OFF。
  • 似乎如果我添加了一个长延迟(10s),它只会触发一次。我认为问题在于 SSR 的切换。
  • 是的,好像我错过了问题本身的某些内容。触发部分没问题,问题是它应该触发一次,但触发三次。这可能是由于触发了数据到达时标记的 Data_Ready 造成的。而且由于它触发了3次,所有3次,接收到的数据都是正确的。尝试降低波特率,或者如你所说,引入少许延迟。
  • 啊哈,我已经解决了这个问题。当程序进入 If(Data_Ready) 时,我添加了一个小延迟,它只会触发一次。感谢您的所有帮助。
猜你喜欢
  • 2015-10-06
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多