お役立ち関数・クラス(シリアル通信)

1. はじめに

 シリアル通信を行うクラスです。対象のマイコンはAtmega88シリーズですが、「Class_Serial.cpp」の中身を少し変えるだけで、他のマイコンにも使えます。

2. 使う準備

 次の2つのファイルをAtmelStudioに読み込ませてください。ファイルを読みこませる方法は、AtmelStudioの使い方(応用編)の別ファイル関数の使い方という所に載っています。
 ・Class_Serial.hpp
 ・Class_Serial.cpp

3. プログラミングについて

 「Class_Serial.hpp」をインクルードしてください。シリアル通信を始める前にser0.begin()を呼び出します。引数はUBRRnレジスタに設定する値です。データシートで確認してください。serial0.println()で引数の文字列を改行文字をつけて送信します。
 次のプログラムは1秒に1回「test」という文字列を改行付きで送信するプログラムです。
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. // インクルードするのはヘッダーファイルのみです。
  5. // これで、Serial通信に関するメソッドを使うことが出来ます。
  6. #include "Class_Serial.hpp"
  7.  
  8. // 実行するためにインスタンスを生成します。
  9. Class_Serial serial0(&UCSR0A, &UCSR0B, &UCSR0C, &UBRR0, &UDR0);
  10.  
  11. // 受信割り込みを設定する。
  12. ISR(USART_RX_vect){
  13. serial0.receive_enqueue(UDR0);
  14. }
  15.  
  16. int main(void){
  17. // シリアル通信を開始する前に呼び出してください。
  18. // 引数はUBRRレジスタに設定する値を渡します。
  19. // 例)クロックが1MHzで9600bpsで通信:引数=12
  20.  
  21. serial0.begin(12);
  22.  
  23. while(1){
  24. // testという文字列を送信
  25. serial0.send_println("test");
  26. _delay_ms(1000);
  27. }
  28. }
  29.  

続いてはシリアル通信の受信処理です。このクラスは内部にバッファーを持っていて、受信した文字はそのバッファーに蓄積されます。バッファーに溜まっているデータの数はserial0.available()で得られます。この受信処理には割り込みを使用しています。そこで、割り込みを有効にするためのメソッドとしてaccept_intterupt()が用意されています。受信処理を行う場合はこのメソッドを呼び出す必要があります。次の例は4文字受信するたびに、受信した文字を送り返すプログラムです。
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. // インクルードするのはヘッダーファイルのみです。
  5. // これで、Serial通信に関するメソッドを使うことが出来ます。
  6. #include "Class_Serial.hpp"
  7.  
  8. // 実行するためにインスタンスを生成します。
  9. Class_Serial serial0(&UCSR0A, &UCSR0B, &UCSR0C, &UBRR0, &UDR0);
  10.  
  11. // 受信割り込みを設定する。
  12. ISR(USART_RX_vect){
  13. ser0.receive_enqueue();
  14. }
  15.  
  16. int main(void){
  17. // シリアル通信を開始する前に呼び出してください。
  18. // 引数はUBRRレジスタに設定する値を渡します。
  19. // 例)クロックが1MHzで9600bpsで通信:引数=12
  20. serial0.begin(12);
  21. serial0.accept_intterupt();
  22.  
  23. while(1){
  24. if(serial0.available() >= 4){ // 受信している文字数が4以上であるかを確認
  25. for(int i = 0; i < 4; i++){
  26. // メソッドread_dequeue()はバッファーからデータを取得して、
  27. // そのデータをバッファーから削除する。
  28. // 返されるデータは一番古いもの。いわゆるキュー構造になっている。
  29. char data = serial0.read_dequeue();
  30.  
  31. // 受信した4つのデータをそのまま送信している。
  32. serial0.send_char(data);
  33. }
  34. }
  35. }
  36. }
  37.  

最後に、変数に格納されているデータの送信方法です。文字列ではなく、整数型の変数で保存されている値を送信するためには、ser0.send_num()を使います。引数として、送信したい変数を指定してください。この時、送信する変数の型はsignedである必要があります。以下に例を示します。
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. // インクルードするのはヘッダーファイルのみです。
  5. // これで、Serial通信に関するメソッドを使うことが出来ます。
  6. #include "Class_Serial.hpp"
  7.  
  8. // 実行するためにインスタンスを生成します。
  9. Class_Serial serial0(&UCSR0A, &UCSR0B, &UCSR0C, &UBRR0, &UDR0);
  10.  
  11. // 受信割り込みを設定する。
  12. ISR(USART_RX_vect){
  13. ser0.receive_enqueue();
  14. }
  15.  
  16. int main(void){
  17. // シリアル通信を開始する前に呼び出してください。
  18. // 引数はUBRRレジスタに設定する値を渡します。
  19. // 例)クロックが1MHzで9600bpsで通信:引数=12
  20. ser0.begin(12);
  21.  
  22. // 送信する変数
  23. int16_t num = 0;
  24.  
  25. while(1){
  26. ser0.send_num(num);
  27. num++;
  28. _delay_ms(100);
  29. }
  30. }
  31.  
最終更新:2017年09月01日 00:40