1: 2009-08-03 (月) 20:16:30 takaboo ソース 2: 2009-08-03 (月) 22:10:44 takaboo ソース
Line 1: Line 1:
-* [#l493db9b]+*ダウンロード[#l493db9b
 +*一覧 [#j8c69fab] 
 +**smpl1(USART).c [#y20358e6] 
 +マイコンのUSARTを使ったシリアル通信を行う。シリアル通信はGCC Developer Liteで提供される専用のライブラリを直接使用し、文字及び文字列の送受信や書式化文字列の送信を行う。~ 
 +シリアル通信ライブラリのプロトタイプ宣言はrs.hとして提供され、ソースにインクルードする事で参照される。~ 
 + #include <rs.h>            // USART通信ライブラリ 
 +また、シリアル通信を行う前には必ず初期化処理を必要とし、実際の通信処理を行う内部のサブルーチンは割り込みを使用しているので、割り込みを許可しておく。~ 
 + // 送受信用バッファ 
 + // バッファの大きさは任意(2~255の間)ですが、大きすぎるとRAMエリアを圧迫するだけです。 
 + // 通常の使用においては数バイト程度で十分です。またバッファはグローバル変数としてください。 
 + static char txb[10], rxb[10]; 
 + 
 + // 通信ポートを初期化 ボーレートは115200[bps] 
 + rs_init (br115200, txb, sizeof(txb), rxb, sizeof(rxb)); 
 + // 通信は割り込みで処理されます 
 + // 初期化後は必ず割り込みを許可状態にしてください 
 + sei (); 
 +その他のサブルーチンは以下のものが用意されている。詳細はソースのコメントを参照の事。 
 + ・1文字送信 
 +  void  rs_putc (char); 
 + ・文字列送信 
 +  void  rs_puts (char *); 
 + ・バイナリ列送信 
 +  void  rs_putb (char *, short); 
 + ・受信バッファデータサイズ取得 
 +  short rs_rx_buff (void); 
 + ・受信バッファクリア 
 +  void  rs_rx_purge (void); 
 + ・1文字受信 
 +  char rs_getc (void); 
 + ・文字列受信 
 +  short rs_gets (char *, short); 
 + ・簡易書式化文字列送信 
 +  short rs_printf (const char *, ...); 
 + 
 +**smpl2(USART).c [#jbe6dac4] 
 +マイコンのUSARTを使ったシリアル通信を行う。avr-libcで提供される標準I/Oルーチンを中継し、シリアル通信はGCC Developer Liteで提供される専用のライブラリを間接的に使用する。~ 
 +初期化まではsmpl1とほぼ同様だが、fdevopenで初期化された以後はC言語でよく使われる標準I/Oルーチン(putcharやprintf等)を使用する事ができる。 
 +  // 通信ポートを初期化 ボーレートは115200[bps] 
 +  rs_init (br115200, txb, sizeof(txb), rxb, sizeof(rxb)); 
 +  // 標準入出力をlibm32.a内のルーチンに割り当て 
 +  fdevopen(rs_putchar, rs_getchar); 
 +標準I/Oルーチンではまかないきれない機能は、シリアル通信ライブラリで提供されるサブルーチンで補填出来る。 
 + 
 +**smpl3(LED).c [#d0e3aab7] 
 +PC4にソース接続されたLEDを点滅させる。~ 
 +#ref(led1234.png) 
 +AVRの内部レジスタは avr/io.h をインクルードする事でデータシートに記載されている名称で参照できる。~ 
 +PC4を出力ポートに設定するにはDDRCの4ビット目を1に設定する。 
 + DDRC |= _BV(DDC4);    // PC4を出力に 
 +PC4へ1を書くとLEDは点灯、0を書くと消灯する。ちなみに、_BV() は引数で指定した数値をビットに変換するavr-libcで提供されるマクロである。~ 
 + PORTC &= ~_BV(PC4); // 消灯 
 + PORTC |= _BV(PC4);  // 点灯 
 +点滅の周期は util/delay.h で宣言される _delay_ms 関数を使用し、ミリ秒単位で設定している。 
 + _delay_ms (500);    // 500ms待つ 
 + 
 +**smpl4(4bitLED).c [#k0566312] 
 +PC4~PC7へそれぞれLEDをソース接続し点滅させる。~ 
 +出力端子の初期化は以下の通り。 
 +  DDRC |= _BV(DDC4) | _BV(DDC5) | _BV(DDC6) | _BV(DDC7);  // PC4..7を出力に 
 +点灯させるビットが増えると一つ一つビットを指定するのが面倒なので、4ビットまとめて点灯ないし消灯させる関数を用意している。 
 + void LED (int d) { 
 +   PORTC = (PORTC & 0x0f) | ((d << 4) & 0xf0); 
 + } 
 + 
 +**smpl5(ALLPIO).c [#i281618a] 
 +PC2~3にDIPスイッチ、PD2~PD3にプッシュボタンを接続し、逐次それらの状態を取り込んでLED1~4に反映させる。~ 
 +#ref(switch.png) 
 +入力端子の初期化は以下の通り。 
 + // DIP1(PC2,3)を構成 
 + DDRC &= ~(_BV(DDC2) | _BV(DDC3)); // PC2,3を入力に 
 + PORTC |= (_BV(PC2) | _BV(PC3));  // PC2,3の内蔵プルアップ抵抗をON 
 + 
 + // PB1~PB2(PD2,3)を構成 
 + DDRD &= ~(_BV(DDD2) | _BV(DDD3)); // PD2,3を入力に 
 + PORTD |= (_BV(PD2) | _BV(PD3));  // PD2,3の内蔵プルアップ抵抗をON 
 +DIPスイッチは2ビットまとめて数値として取り込む関数を用意している。 
 + // DIP1(ディップスイッチ)の状態取り込み 
 + unsigned char DIP1_STAT (void) { 
 +   return (~(PINC >> 2)) & 0x3; 
 + } 
 +プッシュボタン1/2の取り込みも同様に各々関数を用意している。 
 + // プッシュボタン1の状態取り込み 
 + unsigned char PB1_STAT (void) { 
 +   return bit_is_clear (PIND, PIND2); 
 + } 
 + 
 + // プッシュボタン2の状態取り込み 
 + unsigned char PB2_STAT (void) { 
 +   return bit_is_clear (PIND, PIND3); 
 + } 
 + 
 +**smpl6(PIOINT).c [#g253e09b] 
 +外部割り込みを使ってプッシュボタンの押下を検出し、各々のボタンで異なる機能を持たせる。さらに、割り込みが発生しない間はマイコンをスリープモードにし、低消費電力モードに移行させる。~ 
 +プッシュボタン1,2はPD2(INT0)とPD3(INT1)に直結しており、押下されて信号が0になった瞬間に割り込みを励起するよう設定する。 
 + // INT0/1の割り込み条件を立下りエッジに 
 + MCUCR |= _BV(ISC11) | _BV(ISC01);    // ISC11とISC01を1に 
 + MCUCR &= ~(_BV(ISC10) | _BV(ISC00));  // ISC10とISC00を0に 
 + 
 + // INT0/1割り込みを許可 
 + GICR |= _BV(INT1) | _BV (INT0); 
 +マイコンの低消費電力モードを設定する。今回はINT0/1でスリープから復帰できるモードを選択する。 
 + set_sleep_mode (SLEEP_MODE_IDLE); 
 +mainの中では sleep_mode () をコールする以外に特に何もしないが、スリープから復帰した事を明示的にわかるようにLED4を点滅する様に仕掛けている。 
 + // 特に仕事はないのでスリープモードに突入(割り込みにて復帰) 
 + while (1) { 
 +   sleep_mode (); 
 +   PORTC ^= _BV(PC7);  // 起きる度にLED4をブリンク 
 + } 
 +INT0に対応した割り込みルーチン名は INT0_vect としてavr-libcにて決められているので、その様に記述。処理はcnt変数の値をインクリメントし、その値をLED1~3に表示する。 
 + ISR(INT0_vect) { 
 +   LED (++cnt); 
 + } 
 +INT1に対応した割り込みルーチン名は INT1_vect としてavr-libcにて決められているので、その様に記述。処理はcnt変数の値をインクリメントし、その値をLED1~3に表示する。 
 + ISR(INT1_vect) { 
 +   LED (--cnt); 
 + } 
 +**smpl7(ADC).c [#h9ecd904] 
 +PA0~PA7の端子に入力されるDC0~5Vの電圧を計測し、シリアル通信で送信する。~ 
 +ここではA/D変換するにあたり基準となる電圧(DC5V)をAVCC端子に接続した。 
 +#ref(cn2_adc.png) 
 +A/D変換器の初期化は以下の通り。変換時間等は変換精度等の必要に応じて設定する事。 
 + // A/D変換許可, 変換クロックCK/16 
 + ADCSRA = _BV(ADEN) | _BV(ADPS2); 
 +内部にはA/D変換器は1つしかないため、8つの端子からの入力を同時に行う事はできない。任意のチャネルを選択し、変換を励起し、変換が終了するまでチャネルを切り替える事はできない。~ 
 +変換開始から終了の待機及び変換されたデータを取得する関数は以下の通り。 
 + // 任意CHのA/D変換 
 + unsigned short a2d (char ch) { 
 +   ADMUX = _BV(REFS0) | (ch & 7);          // リファレンス,CH指定 
 +   ADCSRA |= _BV(ADSC);                    // 変換開始 
 +   loop_until_bit_is_clear (ADCSRA, ADSC); // 変換終了待ち 
 +   return ADC; 
 + } 
 +DC0~5V入力された電圧に応じて0~1023の10ビットの精度で値が取得される。~ 
 + 
 +mainのループではプッシュボタン1を押すと0~1023の値として、プッシュボタン2を押すと5.00Vといった電圧値として8ch分の変換値をターミナルに対して文字列として送信する。 
 + ・PushButton1を押している間 
 +  ADC=[  338,  609,  617,  802,  639,  887,  670,  495 ] 
 + ・PushButton2を押している間 
 +  ADC=[ 0.57V,0.32V,1.21V,1.18V,1.55V,1.93V,1.82​V,1.78V ]


トップ   差分 リロード印刷に適した表示   全ページ一覧 単語検索 最新ページの一覧   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom