前回 ATTINY2313 でシリアル通信しましたが、今後 AD変換値をシリアルで他デバイスに送信するため、AD変換付のATMega88p 用にプログラムを移行します。
2313 そのままのプログラムでは、88p では動作しません。レジスタが複数あるようで、識別子を UBRRH ->UBRR0H のように 0 を付けて変更する必要があります。88pのデータシートを参照しながら変更しました。
//rs232_2.c (rs232_1.c を ATMega88 用に変更)
// 原典 http://akiba.geocities.jp/atmel_avr_atros/20071014.html のテストプログラムより
#include
#define FOSC 8000000 // 8MHz
#define BAUD 9600
#define MYUBRR (FOSC/16/BAUD)-1 // UART分周率
void sio_init(unsigned int baud){
UBRR0H = (unsigned char)(baud>>8); // ボーレート上位
UBRR0L = (unsigned char)baud; // ボーレート下位
// UCSR0A = (UCSR0A | 0b00000010); //U2X0 設定 (倍速=1) (デフォルト 0)
UCSR0B = (1< UCSR0C = (1< } void sio_puts(char *buf) { while(*buf){ while ( !(UCSR0A & (1< UDR0 = *buf++; } } int main(void){ sio_init(MYUBRR); // USART設定 for(;;){ sio_puts("ATtiny2313 "); } } 前回よくわからなかったボーレート設定ですが、今回、AD変換プログラムはCPUクロック1MHzでの動作を想定しているので、1MHzで動かすにはどうすればよいのかを見ているうちに理解しました。 まず、AVRのクロック周波数はWinAVRのデフォルト設定で動かすと 1MHz です。 これは、Fuse Bit の CKDIV8 1 CKOUT 0 CK clock 8MHz で規定されていて、CKDIV8 のデフォルトが(チェックあり=1)なので、8MHz が8分周され、1MHz がCPUクロックとなります。このプログラムは CKDIV8 =0 にして使うものなので、CPUクロックは 8MHz です。 次にシリアル通信機能はこの CPU クロックを基にスピードが決まります。88p のデータシートの表20-9 で 8MHz の値を見ます。9600pbs にしたい場合は、U2X=0 なら UBRR=51、U2X=1 なら 103 と記載されています。U2X は UCSR0A の第2ビットで、デフォルトは 0 です。 以上のことを手で計算しなくても、頭に書いてある DEFINE がしています。 #define FOSC 8000000 // 8MHz #define BAUD 9600 #define MYUBRR (FOSC/16/BAUD)-1 // UART分周率 この式で MYUBRR が 51 になるので、結果、通信速度が 9600bps になります。 さて、目標である電灯線の電力測定したデータを送出するには、どのくらいの通信速度があればよいのかを考えます。 予定では、交流1サイクルあたり25サンプリングします。したがって、50Hz の場合は、1秒間では 50Hz*25サンプル=1250サンプルです。1サンプルで取得するデータは、三相交流なので、 電圧1 電圧2 電流1 電流2 と4個です。数値は Byte 値では 255 までしか表わせないのでたぶん Int 値が必要なので、2バイト * 4個 = 8バイトを1サンプルあたりで送出します。 つまり、1250サンプル*8バイト=10000バイト/sec = 80000 bit/sec 必要です。 また表をみます。この条件に合うボーレートは、1MHz では不可能なので、8MHz ですと、250K となります。(UBRR=1を設定) ずいぶんと高速での送信になりますが、果たして文字化けとかは大丈夫でしょうか?と思って、PCとの通信を試してみるために、TeraTerm の設定ダイアログを開けると、 250K は無い!! たぶん(この)PCのクロックではサポートされないスピードなのかと思います。PCでやりとりできなければデバッグも大変ですから、どうしても、PCとのやりとり可能なスピードを使う必要があります。が、230.4K が 8MHz では使えないのでは、8MHz のCPUクロックはあきらめるしかないです。 どうしたものか。。