#norelated * LEDサンプル [#d2eb2c43] やっぱり最初はこれよね。~ LEDをPD0〜PD7に接続。~ #ref(LEDTest.png,left,nowrap,LEDサンプル) 本当は抵抗が必要なはずだが、まぁいい。~ とりあえずは光ればいい。~ 以下、ソースコード。~ #include <avr/io.h> #include <util/delay.h> void delay_ms( int t ) { while( t-- ){ _delay_ms( 1 ); } } int main( void ) { DDRD = 0b11111111; PORTD = 0b00000000; char count = 0; char binc = 1; while( 1 ){ PORTD = ( 1 << count ); if( binc ){ count++; if( 7 <= count ){ binc = 0; } } else { count--; if( 0 >= count ){ binc = 1; } } delay_ms( 50 ); } return 0; } ATmega168Pは、内蔵RC発信器が8MHzとなっていたので、普通にCPUのFrequencyも8MHzだろうと思いこむ。~ AVRStudioのProject Optionで、Frequencyを8000000Hzに設定して、F_CPUのdefineを設定したんだけど、実際やってみると、delay_msの待ちが余りに遅い。~ 具体的に言うと、8倍くらい。~ データシートを読み返してみると、ヒューズビットにCKDIV8とかいうのがあって、こいつが0だと、実際には8で割った数がシステムクロックとなるらしい。~ (システムクロック前置分周器:目的としては、消費電力節約用?)~ ってんで、Frequencyを1000000Hzに設定しなおして、事なきを得る。~ デバイスの最高周波数より高い周波数のクロックを入力する場合、前置分周器で押さえてやったりするみたいね。~ というわけで、ヒューズビットのCKDIV8を立てて、Frequencyを8000000Hzにしてもちゃんと動きました。~ この辺は、電源とかの兼ね合いで変えるべきかね。~ [[AVRWikiにあるように、:http://avrwiki.jpn.ph/wiki.cgi?page=AVR%A4%E8%A4%AF%A4%A2%A4%EB%BC%C1%CC%E4(FAQ)#p17]]_delay_ms関数は、システムクロック数によって、待てる時間が異なり、しかもその時間は結構短い。~ なので、1ms指定で指定ms分ループをしている。~ _delay_ms関数は結局、周波数の定数F_CPUを参照して、それをもとにループ回数を決め、ループを回しているだけらしい。~ このため、定数を_delay_msに渡す場合は、コンパイラが最適化し、ループ回数が決定している。~ けど、変数を渡すようなコードを書くと、doubleに変換した引数とF_CPUの計算ルーチンが入るため、コードが膨らむ。~ 手軽に使えるけど、色々考えなければいけないようだ。~