0

UART を必要とするいくつかのプロジェクト作業のために Arduino Due を使用し始めており、UART 割り込みと I/O 間の相互作用のように見えることに混乱しています。

私の最初のコードは、TXBE 割り込みの受信時に送信バッファをロードすることにより、UART をセットアップし、連続的にデータを送信する小さなルーチンでした。UART 出力をオシロスコープに接続し、別の I/O ピンを汎用出力として設定しました。このピンは状態を反転するため、送信バッファがリロードされたときにスコープをトリガーするために使用されます。問題は、UART データが表示されていて、問題ないように見えたのですが、I/O が反転していないことでした。この時点で私のloop()ルーチンは空だっ​​たので、別の出力ポートをセットアップし、loop()その状態を健全性チェックとしてトグルしました。UART以外の出力はまだありません。

これが私が最終的に得たコードです:

uint32_t tempo; // 32-bit temporary variable
boolean flag = true;

void UART_Handler(void) {
  REG_UART_THR = 0x6DL; // load data into the transmit buffer
  if (flag) {
    REG_PIOD_SODR = 0x02L; // drive PD1 high
    flag = false;
  } else {
    REG_PIOD_CODR = 0x02L; // drive PD1 low
    flag = true;
  }
}

void setup() {
  // set up the UART I/O
  REG_PIOA_IDR = 0x0300L; // disable interrupts on PA8 and PA9
  tempo = REG_PIOA_ABSR; // get the current settings of the AB select register
  REG_PIOA_ABSR = tempo & 0xFFFFFCFF; // set PA8 and PA9 to peripheral A control
  REG_PIOA_PDR = 0x0300L; // disable parallel I/O for PA8 and PA9
  NVIC_EnableIRQ(UART_IRQn); // enable UART interrupts in NVIC
  // now set up the UART
  tempo = REG_PMC_PCSR0; // get the current settings of the peripheral clock register 0
  REG_PMC_PCER0 = tempo | 0x0100L; // enable the UART clocks
  REG_UART_CR = 0x0CL; // reset UART receiver and transmitter
  REG_UART_MR = 0x0800L; // set to normal outputs with no parity
  REG_UART_BRGR = 0x89L; // baud rate set to 38400
  REG_UART_IDR = 0x1FBL; // disable all UART interrupts
  REG_UART_IER = 0x0800L; // enable TXBUFE interrupt
  REG_UART_CR = 0x50L; // enable UART receiver and transmitter
  // set up the debug outputs
  REG_PIOD_IDR = 0x03L; // disable interrupts on PD0 and PD1
  REG_PIOD_PER = 0x03L; // enable parallel I/O for PD0 & PD1
  REG_PIOD_OER = 0x03L; // set PD0 & PD1 output enabled
  REG_PIOD_CODR = 0x03L; // drive PD0 & PD1 low
}

void loop() // run over and over
{
   REG_PIOD_SODR = 0x01L; // drive PD0 high
   delay(1);
   REG_PIOD_CODR = 0x01L; // drive PD0 low 
   delay(1);
}

スコープの出力はhttp://www.iwanczuk.com/temp/scope1.pngで見ることができます(画像を投稿するほどの評判はありません!)。

しばらく物事を見つめて洞察を得られなかった後、行をコメントアウトして TXBUFE 割り込みを無効にするREG_UART_IER = 0x0800L; // enable TXBUFE interruptと、PortD1 の切り替えが表示されましたが、明らかに UART 出力はありませんでした ( http://www.iwanczuk.com/temp/scope2.pngを参照)。 )。2つは相互に排他的であるように思われますが、それが本当ならばかげているでしょう. 私は何かが欠けていると確信していますが、それが何であるかを見たり見つけたりすることはできません。

SAM3X8E のデータ シートを読んで、明らかな不足があるかどうかを確認しました。また、関連する Web 検索であると思われることも実行しましたが、解決策が見つかりませんでした。また、ポート A とポート D の 2 つの出力に汎用出力を使用してみました。これを 2 つの Arduino Due ボードで試しましたが、両方で同様の結果が得られました。

誰が私が間違っているのか考えていますか? 前もって感謝します。

4

2 に答える 2

0

問題の原因である本当のエラーが何であるかを理解しました。UART 割り込みレジスタの説明では、送信バッファが空のコンテキストで TXBUFE ビットについて説明しているため、これは、別のバイトを送信保持レジスタに入れることができるタイミングを示すビットであると想定していました。ただし、UART ステータス レジスタの説明には、TXBUFE ビットは「トランスミッタ PDC チャネルからのバッファ フル信号」であると記載されています。後者は、このビットの機能にまったく異なる傾斜を付けます。UART ステータス レジスタの説明によると、確認する必要があるビットは TXRDY ビットです。

于 2015-02-11T13:06:53.937 に答える
0

さて、私はこの問題の根底にたどり着きました。それが最良の答えであるかどうかはわかりませんが、それは解決策です。一長一短は、TXBE 割り込みを回避することです。代わりに TXEMPTY 割り込みを使用すると、正常に動作します。

Atmel データシートの 168 ページの行には、(sic) 「割り込みが無効になっていても保留状態に入ることができる」と記載されているため、TXBE の問題は、保留中の割り込みを ISR の前または内部でクリアしていないためではないかと考えました。NVIC_ClearPendingIRQ(UART_IRQn);ISR の開始時と TXBE 割り込みを有効にする直前に追加しましたが、(誤った) 動作は変わりませんでした。

TXEMPTY の動作は、送信シフト レジスタが空になったときではなく、送信シフト レジスタが空になったときに割り込みが生成されたように見えるため、(私にとっては) まだ少し奇妙です。送信バッファをロードせずに割り込みを有効にすると、すぐに割り込みが発生します。この「自己 = プライミング」動作が好きな人もいるかもしれませんが、私にはそれができません。送信する最初のバイトが送信機にロードされるまで、TXEMPTY 割り込みが有効にならないように送信ルーチンを作成しています。

Arduino フォーラムのこの投稿に基づいて: http://forum.arduino.cc/index.php?topic=186388.0 USART にも同様の問題があると思います。

うまくいけば、これは他の人を助けるでしょう。

于 2015-02-11T12:31:48.847 に答える