読者です 読者をやめる 読者になる 読者になる

kivantium活動日記

プログラムを使っていろいろやります

AVR-PC間のUSART通信(Linux版)

AVR

AVRとPCを通信させる最も手軽な方法であるUSART通信(RS-232C)についてのメモ。

ハード

秋月のFT232RL USBシリアル変換モジュールを使います。
モジュールのTXDピンとAVRのRXDピン、モジュールのRXDピンとAVRのTXDピンを接続します。このモジュールは3.3V/5Vでの電源供給もしてくれるので便利です。

プログラム(Linux側)

入力された8bit整数を一つずつ送信します。

#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
#include<termios.h>
#include<unistd.h>
#include<fcntl.h>

#define BAUDRATE B4800
#define DEVICE "/dev/ttyUSB0"
#define LENGTH 1         //読み込む文字数
#define TRUE 1
#define FALSE 

int main(void){
    //ファイルディスクリプタ
    int fd
    int i, data;             
    //通信ポートを制御するためのインターフェイス
    struct termios oldtio, newtio;

    // O_RDWR:読み書き両用 O_NOCTTY:tty制御をしない
    if((fd=open(DEVICE, O_RDWR | O_NOCTTY))== -1){
        perror(DEVICE);
        exit(-1);
    }

    tcgetattr(fd, &oldtio);          // 現在のシリアルポートの設定を退避させる
    bzero(&newtio, sizeof(newtio));  // 新しいポートの設定の構造体をクリア

    newtio.c_cflag= (BAUDRATE | CS8 | CLOCAL | CREAD);
    /* CRTSCTS:フロー制御有り CS8:8ビット、ノンパリティ、ストップビット1 4800bps
     * CLOCAL:モデムの状態信号を無視 CREAD:受信可能にする */

    newtio.c_iflag=IGNPAR;            // IGNPAR:パリティエラーの文字は無視

    newtio.c_oflag=0;                // rawモード
    newtio.c_lflag=0;                // 非カノニカル入力

    newtio.c_cc[VTIME]=0;            // キャラクタ間タイマは未使用
    newtio.c_cc[VMIN]=LENGTH;        // LENGTH文字受け取るまでブロックする

    tcflush(fd,TCIFLUSH);            // ポートのクリア
    tcsetattr(fd, TCSANOW, &newtio); // ポートの設定を有効にする

    while(scanf("%d", &data) != EOF){
        write(fd, &data, 1);
    }
    tcsetattr(fd,TCSANOW,&oldtio);   //元の設定に戻す
}

プログラム(AVR側)

送信された整数をPORTBに出力します。1MHzで動作するTiny2313向けのプログラムになっています。周波数が違う場合はボーレートが変わってしまうのでUBRRH、UBRRLを変更する必要があります。
Mega328でもレジスタ名の後ろに0をつければ(UDR→UDR0など)動くはずです。

#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>

ISR(USART_RX_vect){
    PORTB = UDR;
}

int main(void){
    DDRA = 0xff;
    DDRB = 0xff;
    DDRD = 0xff;
    PORTB = 0x00;
    PORTD = 0x00;
    /* 
     * USART設定
     * 送受信有効・受信完了割り込み許可
     * 4800bps 8bit 非同期 stop 1bit 
     */
    UCSRA=0b00000000;
    UCSRB=0b10011000;
    UCSRC=0b00000110;
    UBRRH=0;
    UBRRL=12;
    sei();
    for(;;){
    }
}

レジスタの詳しい説明はのデータシートを見てください。