#norelated #contents * USBシリアル通信サンプル [#h0f365ac] USB-シリアル変換モジュールを使って、PCとAVRで通信ができるようにする。~ AVRの通信というと、UART(USART)やら、I2Cやら、SPIやらという単語が出てくるけど、それぞれの位置づけがよくわかっていない。~ 今回使うUART(USART)は、送信と受信の2つのポートでデータのやり取りをする方式で、基本的には1対1の通信なのかな?~ I2Cってのは、同じ2本だけど、複数繋いで、それぞれを識別してデータを送れる、バス通信の方式なのかな?~ SPIは4本使って、複数繋いで、I2Cより速くデータを送れるバス通信の方式?~ AVRはこれらの方式をサポートしていて、それぞれ違うレジスタとポートを使って、機能を実現するっぽい。~ UART(USART)はRXD(PD0)とTXD(PD1)、I2CはSCL(PC5)とSDA(PC4)、SPIはSCK(PB5)とMISO(PB4)とMOSI(PB3)とSS(PB2)なので、使う機能によって繋げる場所を変えないといけないということか。~ [[秋月のUSB-シリアル変換モジュール:http://akizukidenshi.com/catalog/g/gK-01977/]]をPCのUSBに繋ぐと、まず、ドライバのインストールをする必要がある。~ FT232RのUSB UARTドライバと、USBシリアルポートドライバの2つ。~ ドライバは、以下のページからダウンロードできる。~ [[FTDI社のドライバダウンロードページ:http://www.ftdichip.com/FTDrivers.htm]]~ VCPとD2XXというのがあるけど、今はどちらも同じファイルが置いてあるらしい。~ 昔は用途で分かれていたとかなんとか。~ どっちのページに行ってもいいので、OS(今回はXP用)に対応したドライバをダウンロード。~ ファイルを解凍しておいて、モジュールにPCからUSBを接続すると、ドライバのインストールウィザードが出るので、解凍したフォルダを指定してインストール。~ 2回とも同じフォルダね。~ &ref(usb_uart.png,left,nowrap,75%,USB UARTドライバ);&ref(serealport.png,left,nowrap,75%,USBシリアルポートドライバ);~ インストールが終わると、デバイスマネージャのポートのところに、今インストールしたシリアルポートが出来ているはず。~ 今回の例だと、COM8として認識されています。(AVRライタがCOM7)~ #ref(devicemng.png,left,nowrap,デバイスマネージャ) とりあえずの動作確認を行うために、まず、[[TeraTerm:http://sourceforge.jp/projects/ttssh2/]]をダウンロードしてインストール。~ まぁ、標準のハイパーターミナルとかでもいいんだけど、使い慣れてないから……。~ で、モジュールのTXDとRXDのピンを、ジャンパで繋ぐ。~ 送信ポートと受信ポートをつないで、ループバックで返すようにするってことね。~ 繋いだら、[[TeraTerm:http://sourceforge.jp/projects/ttssh2/]]を立ち上げて、接続先をシリアルの、インストールしたポートを指定。(今回はCOM8)~ 繋がったら、適当に文字を入力してみて、それが画面に表示されたら、動作確認OK。~ 入力した文字が、USBを経由して、モジュールのTXD(送信側)からRXD(受信側)を通って、画面に表示されているってことね。~ デフォルトの9600bpsでつながるけど、今回はこの速度のままで動作は確認できた。~ #ref(serealtest.png,left,nowrap,シリアルポートテスト) TXDとRXDのピンを繋いでるジャンパを抜いたら、文字を入力しても表示されなくなるから、表示される=ちゃんと繋がってるってことで。~ ** 回路図 [#s3e509b8] 今回は、RXD(PD0)とTXD(PD1)のピンを使うため、今までPDに繋がっていたLCDを、PBに移動しました。~ それに伴って、LCDライブラリも多少手を加えてあります。~ #ref(UsbTest.png,left,nowrap,USBシリアル通信サンプル) %%FT232RLには、PCからUSBが繋がっており、電源はそっちから取っています。%%~ %%AVRの方から取ってもいいとは思うんだけど。%%~ 試してみたら、FT232RLに繋がってるUSBの方から、経路はわからんけど電流が漏れてしまっているらしい……。~ FT232RLにUSBを繋ぐと、基板の電源の方に付けている、導通確認用のLEDが、SWもOFFのままなのに、うっすらと光ってました。~ その電流の影響があるのか、基板のSWをONにした最初のタイミングで、LCDの初期化に失敗して、文字が出力されないようでした。~ リセットボタンを押すと、正常に表示されるんだけどね。~ なので、電源は基板と同じ方から取るようにしました。~ で、FT232RLのTXD(送信側)をAVRのRXD(受信側)に、FT232RLのRXD(受信側)をAVRのTXD(送信側)に繋げて終了。~ #ref(UsbTestp.png,left,nowrap,USBシリアル通信サンプル) もうブレッドボードがいっぱいいっぱい……。~ というわけで、後で追加でブレッドボードを購入します。~ ↓ #ref(UsbTestp2.png,left,nowrap,USBシリアル通信サンプル) ちょっとすっきり!~ ** ソースコード [#y4a51868] まず、メインで参照する各種ライブラリ。~ &ref(util.h,left,nowrap,ユーティリティヘッダ);&ref(util.c,left,nowrap,ユーティリティソース);&ref(LcdLib.h,left,nowrap,LCDライブラリヘッダ);&ref(LcdLib.c,left,nowrap,LCDライブラリソース);~ #include <avr/io.h> #include "LcdLib.h" #define USART_BPS 25 // ボーレート設定値 void Usart_init( void ) { UBRR0 = USART_BPS; // ボーレート分周値レジスタ(1MHz駆動の2400bpsに設定) UCSR0B = 0b00011000; // 受信許可bitと送信許可bitを立てる UCSR0C = 0b00000110; // 非同期/パリティ禁止/停止1bit/データbit長8bit } void Usart_rcvchar( char *data ) { while( !( UCSR0A & 0b10000000 )){ ; // 受信完了フラグが立つまで待つ } *data = UDR0; // 受信データを出力引数に設定 } void Usart_sndchar( char data ) { while( !( UCSR0A & 0b00100000 )){ ; // 送信データレジスタが空くまで待つ } UDR0 = data; // 送信データをレジスタに設定 } int main( void ) { char data = ' '; // 受信/送信データ格納用 Lcd_init(); // LCD初期化 Lcd_setstr( "Receive Data:" ); // 初期表示 Usart_init(); // シリアル通信初期化 while( 1 ){ // 一文字受信 Usart_rcvchar( &data ); // LCDを初期位置に戻して、テキストと受信データを出力 Lcd_setpos( 0, 0 ); Lcd_setstr( "Receive Data:" ); Lcd_setchar( data ); // 受信データをエコーバック Usart_sndchar( data ); } return 0; } *** 基本動作 [#z4886d61] まずは初期化。~ UBRRレジスタに、ボーレートを設定している。~ このボーレートを設定するレジスタは、実はUBRRHとUBRRLに分かれていて、Lの8bit+Hの4bitのあわせて12bit表現だけど、UBRRに値を入れれば、そのあたりはコンパイラが(というかinclude/avr内のマクロが)それをやってくれる。~ UCSRBとUCSRCに設定してあるのは、ソース内コメント通り。~ 受信や送信完了での割り込みはしていません。~ パリティは調べたらなんとなくわかるけど、停止bitとかとあわせて、どのように解釈してスタートbit、ストップbitを認識して通信するのかということは、実はあんまりわかってない。~ そのうち余力があれば掘り下げたいけど……。~ 受信関数、送信関数は簡単ですね。~ それぞれ、なんか来たよフラグと、送る入れ物が空いてるよフラグが立つまで待って、データレジスタの読み書きをしているだけです。~ メインは、初期化後、受け取ってLCDに表示してPCに戻すというループを繰り返しているだけです。~ あぁ、ちなみに、動かすときは、まずAVRの電源を入れて、PCにCOMポートを認識させた上で、今回は2400bpsに設定しているので、[[TeraTerm:http://sourceforge.jp/projects/ttssh2/]]等でそのCOMポートに2400bpsで繋いで(設定→シリアルポート)から、文字を入力してください。~ 最初、電源を入れずに[[TeraTerm:http://sourceforge.jp/projects/ttssh2/]]を立ち上げて、よく見ないでCOMポートに繋いだら、それはAVRライタのCOMポートで、なんも反応しなかったから焦ったよ……。~ #ref(ttsetting.png,left,nowrap,TeraTerm設定) というわけで、実際に動かしてみたのはこんな感じ。~ [[TeraTerm:http://sourceforge.jp/projects/ttssh2/]]上でキーを打つと、LCDに表示されると共に、エコーバックして[[TeraTerm:http://sourceforge.jp/projects/ttssh2/]]上にも表示されています。~ #u2b(8l0ro9lwqT0,w=480,h=385) ボーレートを上げるには、ベースクロックを上げたり、倍速モードbitを立ててやんないとならないらしい。~ 誤差とかも色々考慮しないとならないので、大変そうだ。~ クロックを上げると、今のLCDライブラリだと、動作不安定だしな……。~ この辺も今後の課題。~