0

Keil C を使用してプログラムを作成しています。私は何年もの間立ち往生してきたいくつかの問題を抱えており、私のプログラムはリモコンでSSR(ソリッドステートリレー)を切り替えます。私のプログラムの仕組み: まず、リモコンの赤外線信号を学習し、「DATA」に保存する学習ボタンがあります。リモコンをもう一度押すと、データが「TempDATA」に保存されます。私のプログラムは両方を比較し、エラーがあるかどうかを確認します。エラーがなければ、SSR をトグルし、緑色の LED が点灯します。エラーが発生すると、赤色の LED が点灯します。

ただし、問題は、1 回ではなく 3 回トリガーされることです。それで、エラーがなければ、SSRを「ON、OFF、ON」にします。リモコンのボタンをもう一度押すと、SSR は「オフ、オン、オフ」になります。また、エラーがある場合は、1 つの「E」ではなく「EEE」が表示されます。この問題を解決するにはどうすればよいですか?

/***********************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

Learnボタンを押さずにリモコンボタンを押すと、Data_Readyが1にセットされます。そのため、学習ボタンを押さずにリモコンのボタンを押した場合にのみ比較されます。

4

1 に答える 1

1

問題は

SSR=~SSR;

指図。最初は、初期状態は既にオフになっています。そのため、正しいデータを受信すると、SSR をネゲートして ON にします。次に、3 つのタイム シーケンスにより、オフとオンが再び繰り返されます。これは、正しい結果が得られた最初の状況に対応します。

これで、次に正しいデータが受信されると、SSR は以前の状態を無効にし、すでにオンになっていて、3 つの時系列がオフ =>オン =>オフになります。

したがって、ここでできることは、次の ON/OFF シーケンスを送信する前に、最初に SSR を意図的に OFF 状態に設定することです。

(Keil C は使用していません。AVR Studio で ATMEL uC のプログラミングに取り組んできたので、使用する 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}
于 2012-06-07T04:43:50.723 に答える