「ATmega328でUART通信」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
編集の要約なし
(文字列「</source>」を「</syntaxhighlight>」に置換)
21行目: 21行目:
  // RoundOff
  // RoundOff
  UBRR0 =  (U16)(((F32)F_CPU / (F32)BAUDRATE / 16.0) - 1.0 + 0.5);
  UBRR0 =  (U16)(((F32)F_CPU / (F32)BAUDRATE / 16.0) - 1.0 + 0.5);
  </source>
  </syntaxhighlight>
<br>
<br>
表と式が異なるが、そのまま計算すると整数切り捨てのための誤差が大きくなるため、四捨五入で誤差を小さくしている。<br>
表と式が異なるが、そのまま計算すると整数切り捨てのための誤差が大きくなるため、四捨五入で誤差を小さくしている。<br>
36行目: 36行目:
  // Enable receiver and transmitter
  // Enable receiver and transmitter
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


63行目: 63行目:
  // Set frame format: 8data, 1stop bit : 8N1
  // Set frame format: 8data, 1stop bit : 8N1
  UCSR0C = (0 << USBS0) | (3 << UCSZ00);
  UCSR0C = (0 << USBS0) | (3 << UCSZ00);
  </source>
  </syntaxhighlight>
一般的には、データビット8[bit]、パリティビット無し、ストップビット1[bit]の通称8N1という形式が多い。<br>
一般的には、データビット8[bit]、パリティビット無し、ストップビット1[bit]の通称8N1という形式が多い。<br>
ここでも、8N1形式で送受信を行う。<br>
ここでも、8N1形式で送受信を行う。<br>
84行目: 84行目:
     UDR0 = data;
     UDR0 = data;
  }
  }
  </source>
  </syntaxhighlight>
<br>
<br>


98行目: 98行目:
     return UDR0;
     return UDR0;
  }
  }
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:AVR]]
[[カテゴリ:AVR]]

2021年11月15日 (月) 01:08時点における版

概要

ATmega328に用意されているUSART機能を使用してシリアル通信を行う。
USARTはUniversal Synchronous Asynchronous Receiver Transmitterの略で、
非同期通信のUARTだけでなく、同期通信も可能とした機能のことである。

今回は、非同期通信のUARTについてのみ記述する。

AVRのマイコンでUARTを使うには、以下の3つの設定を行う必要がある。

  1. ボーレートの設定
  2. レシーバとトランスミッタの有効化
  3. フレームフォーマットの設定



ボーレートの設定

設定したいボーレート(通信速度)に合わせて通信用の内部クロックを生成するため、下表の式を元にUBRRレジスタの値を算出する。

ATmega328 UART 1.jpg

BAUD : ボーレート
Fosc : ATmega328のクロック周波数

<source lang="c++">
// Set baudrate parameter
// RoundOff
UBRR0 =  (U16)(((F32)F_CPU / (F32)BAUDRATE / 16.0) - 1.0 + 0.5);
</syntaxhighlight>


表と式が異なるが、そのまま計算すると整数切り捨てのための誤差が大きくなるため、四捨五入で誤差を小さくしている。
誤差が大きくなると文字化けするので、適宜試しながら正しく通信できる速度を探らなければならない。

UBRRレジスタのサンプル値もデータシートに記載されているので、そちらを参照して定数で指定してもよい。
例えば、ATmega328のクロック周波数が8[MHz]のとき、ボーレート19.2[kbps]に設定したければUBRRレジスタの値は25になる。

ATmega328 UART 2.jpg



レシーバとトランスミッタの有効化

レシーバとトランスミッタの有効化は、USARTのコントロールレジスタを設定する。

<source lang="c++">
// Enable receiver and transmitter
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
</syntaxhighlight>



フレームフォーマットの設定

シリアル通信では1本の信号線で時系列に0または1を送信することで通信を行う。
そのため、予めどのようなフォーマットでデータを送信するかを定義する必要がある。

シリアル通信のフレームフォーマットは以下の要素で構成されます。

名称 ビット数 説明
スタートビット 1 フレームの先頭であることを示すビット
データビット 5 - 9 送信するデータ
5 - 9[bit]の範囲で自由に設定できる
パリティビット 0 or 1 ビットの誤りをチェックするビット
設定しなくともよい
ストップビット 1 or 2 フレームの終わりであることを示すビット


上表において、スタートビットは常に1[bit]なので、残りの3項目のビット数を設定する。

<source lang="c++">
// Set frame format: 8data, 1stop bit : 8N1
UCSR0C = (0 << USBS0) | (3 << UCSZ00);
</syntaxhighlight>

一般的には、データビット8[bit]、パリティビット無し、ストップビット1[bit]の通称8N1という形式が多い。
ここでも、8N1形式で送受信を行う。


サンプルコード

送信と受信ともにUDR0レジスタを用いて1[byte]データを操作する。
1度の操作で1[byte]しか扱えないため、数byteを送受信するときは単純に同じ操作を繰り返す。

送信方法

送信バッファが空になるまで待機し、UDR0レジスタに1[Byte]分のデータを書き込む。

<source lang="c++">
void Transmit1Byte(char data)
{
   // Wait for empty transmit buffer
   while(!(UCSR0A & (1 << UDRE0)));
   // Put data into buffer, sends the data
   UDR0 = data;
}
</syntaxhighlight>


受信方法

1[Byte]分のデータを受信するまで待機(ポーリング)し、UDR0レジスタを読み取る。

<source lang="c++">
char Receive1Byte(void)
{
   // Wait for data to be received
   while(!(UCSR0A & (1 << RXC0)));
   // Get and return received data from buffer
   return UDR0;
}
</syntaxhighlight>