TOPへ戻る

20080716 ATtiny2313LED モールス信号

ATtiny2313を使ってランダムにモールス信号をLEDを使って点灯させます。
最初はアルファベットをランダムに点灯させるだけでしたが、段々凝ってきてこの形になりました。
途中バグにはまってCut&Tryのデバックに限界を感じ、printf デバックを導入しました(^_^;
ブレッドボード上にRS232CドライバIC作りこむのはアレかなーと思って、
ツール工房さんの、RS232C-TTLレベル変換基板を使ってみました。
←クリックすると拡大します。

手持ちのRS-232Cのコネクタにすっぽりはまりました。
←クリックすると拡大します。

DEBUG PORTとして使いたいときは、こんな感じにブレッドボードに取り付けます。
メスコネクタなので、このままパソコンのRS-232Cポートに付けられます。
←クリックすると拡大します。

確認用回路図
←クリックすると拡大します。

// 0x41(65) A 0x30 0 // エスケープシーケンス http://www.mm2d.net/c/c-06.shtml // モールス信号 //http://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%BC%E3%83%AB%E3%82%B9%E7%AC%A6%E5%8F%B7 // Q符号 http://ja.wikipedia.org/wiki/Q%E7%AC%A6%E5%8F%B7 #include <stdio.h> #include <stdlib.h> #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #define x 2 // この数値を大きくすると点灯が遅くなります。 #define DEBUG 1 //////////////////////////////////////////////////////////////////////////////// #if DEBUG #define FOSC 8000000 // 8MHz #define BAUD 38400 #define MYUBRR FOSC/16/BAUD-1 // UART分周率 static int uart_putchar(char c); // 関数宣言 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); int uart_putchar(char c ) { loop_until_bit_is_set(UCSRA, UDRE); //特定のビットが1になるのを待つ命令 UDR = c; return 0; } void sio_init(unsigned int baud) { UBRRH = (unsigned char)(baud>>8); // ボーレート上位 UBRRL = (unsigned char)baud; // ボーレート下位 UCSRB = (1<<RXEN)|(1<<TXEN); // 送受信許可 UCSRC = (1<<USBS)|(3<<UCSZ0); } void sio_puts(char *buf) { while(*buf){ while ( !(UCSRA & (1<<UDRE)) ); // 送信バッファ空き待機 UDR = *buf++; } } #endif //////////////////////////////////////////////////////////////////////////////// char morse[37][6] PROGMEM = { // A B C D E F G H I J K L // "*-","-***","-*-*","-**","*","**-*","--*","****","**","*---","-*-","*-**", // M N O P Q R S T U V W X // "--","-*","---","*--*","--*-","*-*","***","-","**-","***-","*--","-**-", // Y Z // "-*--","--**", // 1 2 3 4 5 6 7 8 9 0 // "*----","**---","***--","****-","*****","-****","--***","---**","----*","-----"}; void IoInit( void ) { DDRB = 0xff; // portB output PORTB = 0x00; } void delay(int t) { int i; for(i=0;i<t;i++){ _delay_ms(10); } } void ton( char m ) { switch( m ){ case '*': PORTB = 0x01; delay(5*x); break; case '-': PORTB = 0x01; delay(15*x); break; default: delay(10*x); break; } PORTB = 0x00; delay(3*x); } void ton_s( char *m ) { char t; char i; char buf[6],foo; sio_puts(m); while(*m!=0x00){ t = *m; i = 0; // こいつか if ( ( t >= 0x41 ) & ( t <= 0x5a ) ) t = t - 0x41; else if ( ( t>=0x30 ) & (t<=0x39) ) t = t - 0x30 + 26; PGM_P foo = morse[t]; strcpy_P(buf,foo); // strcpy_P(buf,morse[t]); // printf("BUF:%s\n\r",buf); // この行を入れるとFLASH容量を超えてしまう。 sio_puts(buf); while(buf[i]!=0x00){ ton(buf[i]); i++; } delay(20*x); m++; } sio_puts("\n\r"); } void cqcq( void ) { ton_s("CQCQ"); delay(50); } int main( void ) { char buf[2]; IoInit(); sio_init(MYUBRR); // USART設定 stdout = &mystdout; sio_puts("\x1b[2J"); //画面クリア cqcq(); for(;;){ buf[0] = rand()%26+65; // A〜Zまでを乱数で発生させる buf[1] = 0x00; ton_s(buf); delay(20*x); } }
ソースファイルのダウンロード


AVRSP-Gのヒューズビットの設定
内蔵クロック8MHz 分周比1/1 の設定です。

コンパイラは WinAVR-20070525 を使いました。

動画を用意しました。いずれもカメラの性能のため荒いです(^^;


1)モールスのパターンがRAMに展開されないように(RAMが溢れちゃいます)、PROGMEMを使っています。
2)Cut&Tryのデバックに行き詰ってコンソールprintfデバックを導入(^^; 結局 i = 0; の初期化を忘れていたのが原因
3)tiny2313ではprintfを使うとFLASHがあふれてしまうので使えなかった。
4)実はモールスは知りません(^^; でも4級は持っています。
5)sio_puts("\x1b[2J"); エスケープシーケンスです。パソコン通信時代は結構使いました。
6)RS232C-TTL基板に6Pシングルヘッダーが添付されていたので、ブレッドボードに直接刺そうかな
  と考えましたが、D−SUBコネクタケースに入れる形式になりました。便利です。