AVRとFT232RLを使ったUSB−シリアル通信の実験

[公開:any]

[電子工作/AVR]
[電子工作/実験]
[AVR,ATmega168,FT232RL]

origin 2008-04-12


FT232RLを使ったUSB−シリアル変換モジュールを秋月電子で購入してきたので、ワンチップマイコンのAVRのUSART機能と接続してPCへのデータ取り込み実験をしてみました。

USB-シリアル変換モジュールは、24ピンのDIPサイズでかなりコンパクトです。FT232RLは、通信速度が300〜460kbpsに対応しているので、かなり高速にデータのやり取りが可能です。
USBから給電して動作させることも出来ますが、今回はブレットボードから電源を供給して使用してみます。

USB-シリアル変換ユニットAE-UM232R

接続するPCには、FT232RLの供給メーカーであるFTDI社のサイトから必要なドライバーをダウンロードしてインストールします。Windowsからは、USB接続が仮想的なシリアルポートとして認識されて、利用できるようになります。

WindowsXPデバイス表示

今回の実験回路です。

実験回路図(Bsch3V作成)

AVRはATmega168を使用します。AVRのクロック源は、速度的には、内部オシレータでも十分ですが、高速なシリアル通信の場合は、タイミングがシビアになって、文字化け等の影響がでる可能性もあります。今回は、外部のクリスタルオシレータを使用しました。

FT232RLユニットとの接続は、RXDとTXDの2本だけとなります。・・・が、しかし、今回は「AVRを使ったバッテリー放電器の製作」で作った放電器に内蔵することを想定してるので実際は、AVRからのデータの送信のみを実験します。(つまり、PCからの送信データを受信することはない)

ブレットボードで実験中。送信データは、1秒毎に経過秒と4つの固定ダミーデータとなっています。

ブレットボードでの実験

PC側の受信は、Tera Termを使っていましたが、どーせなら・・ということで専用のアプリケーションを久しぶりにdelphiを使って作成してみました。
COMポートの設定をして、STARTボタンでシリアルポートからデータを取り込むことが出来ます。
今回は、CSV形式のダミーデータを取り込んでいます。取り込みが終わったらファイル保存して、ExcelやOpenOfficeのscalcをつかってグラフ化することができます。

自作シリアル受信ソフトウェア

参考までに、今回AVRに書き込んだプログラムです。
AVRStuido4とWinAVR-20071221で作成してあります。
USARTへの送信は、USARTへの1文字送出をファイルディスクプリタとして宣言すれば、fprintfで文字列が送出できるので便利です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>

#define FOSC 12000000
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

unsigned int hm;
unsigned int sec;
char buf[10];
FILE *fp;

ISR(TIMER1_COMPA_vect)
{
    hm++;
    if(hm == 5) {
        sec++;
        fprintf(fp, "%d,1.23,1.21,1.12,1.19\n", sec);   // elapsed time and dummy data 
        hm = 0;
    }
    if(sec > 65534)
        sec = 0;
}

void USART_Init(unsigned int baud)
{
    UBRR0 = baud;
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);    // 8 bit,2 stop bit
}

void USART_putchar(unsigned char data)
{
    loop_until_bit_is_set(UCSR0A, UDRE0);
    UDR0 = data;
}

void USART_putstr(char *s)
{
    while(*s != '\0') {
        USART_putchar(*s);
        s++;
    }
}

unsigned char USART_Receive(void)
{
    loop_until_bit_is_set(UCSR0A, RXC0);
    return UDR0;
}

int main()
{
    TCCR1B = 0b01001011;    // Timer1 prescaler 1/64
    TIMSK1 = _BV(OCIE1A);    // Timer1 compare match A interrupt
    OCR1A = 37500;            // 12MHz / 64 = 187500. 200ms = 37500.  

    USART_Init(MYUBRR);

    fp = fdevopen(USART_putchar, NULL);

    sei();

    while(1) {

    }
}

▲ページ Top へ...