0

ATmega168でピン変化割り込み

ATmega88以降は全てのI/Oピンに「外部入力割り込み」が付いている。これは、それぞれのピンに電流がONになったり、OFFになったりするとイベントが起こるという事だ。

今まではmain()の中のループで各ピンをずっと監視し続けなければならなかったが、この外部入力ピンを使うと完全にイベントドリブンでプログラムを書ける様になる。ちなみにArduinoからは使えない機能です。

ATmega168 SIG_PIN_CHANGE0ATmega168 SIG_PIN_CHANGE0

■作った

PB1につながったスイッチを押した時に割り込み(SIG_PIN_CHANGE0)が発生し、UARTでPCに通知する。PB0のLEDも光らせる。スイッチを離すとLEDを消し、UARTで通知する。

SourceCode, hex, Makefile(avr-gcc 3.4.6)

■外部入力割り込みの仕組み

2箇所設定する必要がある。

1.「ピン変化割り込みレジスタ」でピン変化割り込みを許可する

2.入力割り込みを受け取るピンを「ピン変化割り込みマスクレジスタ」で指定する

ピン変化割り込み0,1,2(PCIE0,1,2)の3つがあり、それぞれPORTB,PORTC,PORTDに対応している。

つまり、割り込み1つで7~8個のピンを受け持つという所がINT0,INT1の外部入力割り込みと違う。

ATmega88のデータシートの41ページを見るとPCICRというレジスタのPCIE0ビットに1をセットしてやるとピン変化割り込み0が許可される事がわかる。

sbi(PCICR,PCIE0); // ピン変化割り込み0

Read more

0

ATmega168でAD変換

ATmega168でADコンバータも試した。

CdS(光量センサ)と10kΩの抵抗を使った。

ATmega168 ADC and UART

ADC0でAD変換した値を文字列に変換して、UARTでPCに送る

ADC0の値が700以上の時、LEDを点灯させる。700以下だったら消灯する。

動いているところ

■コード

SourceCode, hex, Makefile(avr-gcc 3.4.6)

AD変換の準備のadc_init()、実際にAD変換を行ない値(int)を取るadc_convert(int pin)、USARTで文字列を送る関数 usart_sendStr()、intをStringに変換するintToStr(int, buf)を作った。

s.h.log: Arduino – UART、LED、AD変換を試したでも書いたが

シリアル通信で送信できるのは8bitまで。AD値は10bit。

なので、そのままSerial.print()してしまうと上位2bitが飛んで変な値になる。

こういう時は

・上位2bit/下位8bitを2回に分けて送信し、PC側で連結する

・マイコン側で、AD値が0~50の時は’a’を送る/51~100の時は’b’を送るの様に、プロトコルを決める

・Stringにして送信して、PC側で数値に直す

・4で割ると、10bitの最大値1023が8bitの最大値255に納まる。ただし精度は4分の1になる

のどれかで対処する。

なので今回は文字列に変換して送ってみた。これが無いとデバッグとかやってられない。

Read more

0

ATmega168でUSART受信割り込み、シリアルエコー

mega168でUART受信割り込みできた。

回路はmega8の時と同じ。

さっきできなかった理由は割り込みベクタ名が間違ってた為だった。

コンパイル結果をよく見ると SIGNAL(SIG_UART_RECV)の所でwarningが出ていたので、avr-gccのフォルダの中のコードをよく読んだらSIG_USART_RECVになっていた。

コンパイラのバージョンというわけではなく、ATmega8のコードではSIG_UART_RECVで通るのでATmega168以降はSIG_USART_RECVに変わったみたいだ。

あとavr/signal.hは廃止されてavr/interrupt.hに統合される模様。

■関連記事

s.h.log: AVR – MEGA8のUART送受信

s.h.log: AVR – ATMega8でUSARTエコー

■コード

SourceCode, hex, Makefile(avr-gcc 3.4.6)

Read more

0

ATmega168でシリアルエコー

8MHz駆動になったmega168で、UARTエコー。

シリアルコンソールで送信した値がそのまま帰ってくる。

ATMega8の時とは違って、受信割り込みに反応して返すのではなくmain()の中のループで受け取って返している。というか受信割り込みから復帰できないので。

今晩中に解決できるといいな…

SourceCode, hex, Makefile(avr-gcc 3.4.6)

Read more

0

ATmega168のクロックを内蔵8Mhzに切り替える

マルツで買ったATmega168に「avrsp -fl11100010」して、8Mhzで動かす設定に変えた。

ATMega168ATmega168 USART,LED



最初は1MHz
なのでこのままでは使い物にならないので、avrspを使ってヒューズビットのロービットを書き換えて内蔵8MHzで動かす。mega8とはロービットが微妙に変わっているので、mega8そのままではできない。

Read more