2016-06-11 1 views
0

これは私がこのようなものを見るのは初めてです。私はそれがハードウェア障害であると思われ始めている。 私は配列 "test"の内容を送信しようとすると、その配列が4要素より大きい場合、または宣言のすべての要素を初期化します。初期化しようとする値の代わりに0xffが含まれています。AVR gcc、奇妙な配列の振る舞い

これは問題なく動作します。私は(LCDおよびUARTに送信)、一方の配列から値を読み出すときに、両方の読み取り値はテスト値と一致している:これはない

uint8_t i=0; 
uint8_t test[4] = {1,2,3,4}; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
} 

、代わりにテストは0xFFを返し[i]の値:

uint8_t i=0; 
uint8_t test[5] = {1,2,3,4,5}; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
} 

でも、これが機能します。それは適切な値

uint8_t i=0; 
uint8_t test[6] = {1,2,3,4,5}; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
} 

これも作品を返す:私は別のMCUとスワップアウトのlinux

上でコンパイルし、それはそれが必要ように動作したときに、それが正常に動作

uint8_t i=0; 
uint8_t test[5]; 
test[0]=1; 
test[1]=2; 
test[2]=3; 
test[3]=4; 
test[4]=5; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
    } 

。ハードウェアの問題である必要があります

+1

この質問は特に明確ではありません。コードを貼り付けるだけでなく、私たちに精神的にそれを相違させてください。 *問題点を説明してください。あなたは "0xFF"を返します - どこからですか?そのコードはどこにも表示されません。送信に問題がある場合は、受信側の結果を気にするのはなぜですか?問題を切り分けてください。あなたはUARTを送信していますよね?さて、明白なデバッグのステップは、実際にポートから出てくるものを見ることです。 –

+1

配列のサイズが変わっても、ループの境界は決して変化しません。それは常に「while(i <5)」です。これが 'ARRAY_LENGTH'マクロが便利な理由です。 –

+0

投稿を編集して正しく作成しました。問題は、私は通常、配列[] = {1,2,3}を行う方法で配列を初期化すると、それが0xffを含む私の値の代わりに4つの要素よりも大きいことです。 6つ以上の要素配列を宣言し、最後の要素をスキップして初期化するとうまく動作します。 私は怠惰から(i <5)値を変更していませんでしたが、問題には影響しません。配列に4つの要素がある場合、それらを正しく出力する+ 1つの迷惑行を出力する、5つの要素を持つ場合は0xffを5回出力する、6つの要素を持つが5を初期化する場合は5つの適切な値がある – Barricadexx

答えて

0

あなたの問題はあなたがUSARTをオーバーロードしていることです。私はGLCD_WriteData()が非常に速く、USART_Transmit()が送信用の文字をバッファリングしてすぐに戻ると仮定します。私はあなたのハードウェアを知らないので、わかりませんが、USART用の4文字のバッファは妥当と思えます。

送信しようとしている実際の文字が失われているため、5文字の例は機能しません。代わりに0xFFが入ります。 USARTバッファの状態をチェックし、スペースが利用可能であることを表示するまで待つ必要があります(注:NOTは空です。非効率です)。 8250および16450 UARTチップで

2つのステータスビットがあります

  • TSRET ransmit S hift R egisterはE MPTYであることを言います。
  • THRER egisterはE MPTYですolding T ransmit Hという。

THREは、TSREでない場合でも設定できます - それは忙しいです。私はTSREをテストし、次の文字は部屋が出るまで送っていないか、バッファと割り込みハンドラを設定します。

+0

I/Oハードウェアは問題ありません。MCUはlcdのビジーフラグをチェックし、USART_transmitはただ1文字のハードウェアバッファです。 。私は128要素の配列を作ることができ、whileループでそれらに値を代入して、それをうまく印刷します。私が 配列[5] = {1,2,3,4,5}を実行し、whileループを通してそれを読むと、それはすべて0xFFです。もう一つ、もし私が1つずつ読むと:USART_Transmit(array [0]).. 5には問題ありませんが、そのコードにread byを追加すると、突然0xffになります。 – Barricadexx

+0

@Barricadexx最適化を変更しようとしましたか? – zviad

0

I/Oハードウェアでない場合は、コンパイラが間違ったコードを生成していると思います。 USART_Transmit()の正確な宣言は何ですか? uint8_tが必要ですか?またはint(何らかの理由で)のようなものですか?それが常に動作する場合、あなたはコンパイラの問題ではなく、ハードウェアの問題を持っている、

while(i<5){ 
    int c = test[i];   // Whatever USART_Transmit wants 
    GLCD_WriteData(test[i]); 
    USART_Transmit(c); 
    i++; 
} // while 

:それはintのような何か他のものは、なら

は、次のコードを試してみてください。

EDIT:設けUSART_Transmit()用コード:

void USART_Transmit(uint8_t data) {
//Wait for empty transmit buffer
while(!(UCSR0A & (1<<UDRE0)));
//Put data into buffer, sends the data
UDR0 = data;
}

はJTAGよりも良いです - あなたはLCDディスプレイを持っています! UDRE0が、その後、そのコード3であると仮定すると

char Hex(uint8_t nibble) { 
    return nibble<10 ? 
      '0'+nibble : 
      'A'+nibble-10; 
} // Hex 
... 
void Send(uint8_t c) { 
    uint8_t s; 
    UDR0 = c; // Send character NOW: don't wait! 
    do { 
     s = UCSR0A; // Get current USART state 
     //s = UCSR0A & (1<<UDRE0); // Or this: isolate ready bit... 
     GLCD_WriteData('x'); 
     GLCD_WriteData(Hex(s >> 4)); // Write state-hi hex 
     GLCD_WriteData(Hex(s & 0xF)); // Write state-lo hex 
    } while (!(s & (1<<UDRE0)));  // Until is actually ready 
} // Send(c) 
... 
Send('A'); 
Send('B'); 
Send('C'); 

:私はどのように多くの文字を知らないが、それは

あなたが好きなものを試みることができる...持っている、またはそれは文字を送信するのにかかる時間x00x00x00x00x00x08x00x00x00x00x08x00x00x00x08のようなシーケンスが動作している場合は結果が得られます。 x08x08x08が生成されたら、スタックされたUCSR0Aビットがあり、ハードウェアです。

+0

ボイドUSART_Transmit(uint8_tデータ) {//空の送信バッファ 一方((UCSR0A&(1 << UDRE0))!)を待ちます。 //バッファにデータを入れ、データを送信します UDR0 = data; } あなたのコードは5つの0xFFのリスロードを持っています。 私はtest [i]をちょうど 'i'に置き換えてもintであっても、予想されるシーケンス0-4を得るので、transmiting関数を使うことになります。私はJTAGを持っていればいいので、思い出を覗いてみることができます。私はこれをあきらめている。私はそれが私が持っていた他のチップのためにそれをコンパイルし、それは正常に動作します。それは今のところできます。助けてくれてありがとう!私はちょうど問題がsiloconにあると仮定します – Barricadexx

1

最初の例では、配列test [4]の外に出ています。配列が4つの項目の長さしかない場合、5回実行しています。

+0

彼は最初の例が働いていると言っていますが、2番目の例はそうではありません。 –