The AVR Microcontroller and Embedded Systems Using Assembly and C

USART / とにかく何かを送受信する / Cで記述する / 割り込みを利用する

p.386 AVR Programming: Learning to Write Software for Hardware カテゴリーの記事一覧 -では、Elliotの用意したUSARTライブラリーをずっと使っていたが、これは送受信の完了をポーリングで確認するものであった。 ここでは受信完了時に割り込んで何かをし…

USART / とにかく何かを送信する / 送信完了割り込みを使う

今度は、データレジスタエンプティ割り込みではなく送信完了割り込みを使ってみる。とりあえず何かを送信し終えない限り送信完了フラグが立たない。テキストにサンプルが載っていないので多分あまり一般的な方法ではない。 ; スタックポインタの初期化マクロ…

USART / とにかく何かを送信する / データレジスタエンプティ割り込みを使う

p.385 送信時も割り込みを使ってみる。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO ; 割り込みベクターテーブルを侵さないようにするため、マイコンのリセット後…

USART / とにかく何かを受信する / 受信完了時に割り込む

p.384 前回は、1バイトを受信したかどうかをポーリングで確認したが、今度は受信完了時に割り込みを発生させる。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO ; 割…

USART / とにかく何かを受信する

p.376 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO INITSTACK ; レシーバーを有効化して(PD0端子をRXD機能にして)、 LDI R16, 1 << RXEN0 STS UCSR0B, R16 ; 8N1 (…

USART / とにかく何かを送信する

p.347 一般にLSBファースト。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO INITSTACK ; トランスミッターを有効化して(PD1端子をTXD機能にして)、 LDI R16, 1 << T…

PC COMポート

p.363 非公式訳 かつてx86 PC (8086、286、386、486、Pentiumの各マイクロプロセッサーをベースとしたPC)はCOMポートを2つ備えていました。どちらのCOMポートもRS-232タイプのコネクターでした。それぞれ「COM 1」「COM 2」という番号が割り振られていました…

RS-232ハンドシェイキング信号の詳細

pp.362-363 非公式訳 2つのデバイス同士で速く確実なデータ転送を行うためには、データ転送の取り決めをしておく必要があります。たとえばプリンターの場合がそうですが、受信側のバッファーに空きがなくてシリアルデータ通信のデータが受けられないときには…

RS-232規格

p.361 非公式訳 (~略)ただしこの規格は、TTLロジックICの登場するずっと前に定められた規格であるため、その入出力電圧レベルはTTL互換ではありません。RS-232では、1は-3~-25 Vで表現されます。0は+3~+25 Vで表現されます。-3~+3 Vは未定義です。(略~)

割り込みの優先順位

p.341 非公式訳 割り込みが2つ同時に発生した場合は、優先順位の高いほうの割り込みが先に処理されます。割り込みの優先順位は、割り込みベクタにおけるアドレスによって決まります。アドレスの若い割り込みほど優先順位が高い。表10-1を見てください。たと…

ピン変化割り込み

p.341 今度はピン変化割り込みを試す。入力信号のロジックが変化するたびに割り込みがかかる。ピン変化割り込みは外部割り込み(INT0、INT1)と違ってすべてのGPIOで利用できる。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OU…

外部割り込みINT0

p.338 今度は外部割り込みINT0を試す。 INT0 (PD2)へ入力される信号のfalling edgeが検出されるたびにPB1の出力をトグルしてみる。入力は念のためローパスとシュミットトリガとでディバウンスしたので、INT0 (PD2)は内部プルアップしない。 ; スタックポイン…

Timer0のコンペアマッチ割り込み

pp.333-334 今度はTimer0のコンペアマッチ割り込みを使ってみる。 メインループでは、PORTCに入力された値をPORTBから出力する。 それと並行して、Timer0がコンペアマッチするたびにPD4の出力をトグルする。 ; スタックポインタの初期化マクロ .MACRO INITST…

Timer0、Timer1の両方のオーバーフロー割り込みを同時に使う

pp.330-331 今度はTimer0、Timer1の両方のオーバーフロー割り込みを同時に使ってみる。 メインループでは、PORTCに入力された値をPORTBから出力する。 それと並行して、Timer0がオーバーフローするたびにPD4の出力をトグルする。 さらにそれと並行して、Time…

Timer0オーバーフロー割り込み

pp.328-329 メインループでは、ポートCに入力された値をポートBに出力するという処理を繰り返す。 それと並行して、Timer0オーバーフロー割り込みの発生するたびにPD4の出力をトグルする。 SREGレジスタのIビットは、割り込み発生後にハードウェアによってク…

CからTimer0の各種レジスタにアクセスして時間遅延を生成する

p.313 今度はCからTimer0を利用して時間遅延を生成してみる。普通はわざわざ自分で作ったりせずに<util/delay.h>の_delay_ms()函数、_delay_us()函数を使う。 //#define F_CPU 8000000UL #include <avr/io.h> //#include <util/delay.h> void delay_T0(int n){ for(int i=0; i</util/delay.h></avr/io.h></util/delay.h>

Timer0で外部パルスをカウントする

p.309 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO ; スタックポインタを初期化して、(しなくてもよい) INITSTACK ; PD4 (T0)のIOをINにして、(INがデフォルトなの…

16ビットレジスタへのアクセス / どうコンパイルされるのかを.lssファイルで見てみる

16ビットレジスタへ書き込むとき: #include <avr/io.h> int main() { TCNT1 = 0x1234; } 上位バイト、下位バイトの順に書き込まれる。 16ビットレジスタから読み出すとき: #include <avr/io.h> int main() { uint16_t sute = TCNT1; } 下位バイト、上位バイトの順に読み出される。</avr/io.h></avr/io.h>

16ビットレジスタへのアクセス

pp.301-302 非公式訳 AVRは8ビットマイコンです。つまりデータは一度に8ビットずつしか処理できません。しかしTimer1のレジスタのうち、TCNT1、OCR1A、ICR1などは16ビットレジスタです。こうした16ビットレジスタは2つの8ビットレジスタに分割されていて、そ…

CTCモードのTimer1で時間遅延を生成する

p.300 PB6の出力をトグルする。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO ; スタックポインタを初期化して、 INITSTACK ; PB6のIOをOUTにして、 SBI DDRB, 6 ; …

ノーマルモードのTimer1で時間遅延を生成する

pp. 298-299 一定の時間が経過するたびにPB6をトグルする。 TCNT1レジスタが16ビットであることを除けば、コードそのものはTimer0、Timer2と変わらない。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, L…

CTCモードのTimer2で時間遅延を生成する

p.295 CTCモードのTimer2で生成した時間遅延を利用してPB6をトグルする。 Timer0と大きく違うのは、★で示した行だけである。OUTの代わりにSTSを使う。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(…

ノーマルモードのTimer2で時間遅延を生成する

p.294 一定の時間が経過するたびにPB6の出力をトグルする。 Timer0と大きく違うのは、★印で示した行だけである。目的のI/Oレジスタが拡張I/Oメモリースペースに存在しているので、OUTの代わりにSTSを使う。STSはStore Direct to Data Space。 OUTは2バイト命…

Timer0とTimer2との違い

p.292 非公式訳 Timer2は8ビットタイマーです。したがってTimer0と同じ動作をします。しかし下に示す3つの違いがあります。 Timer2はリアルタイムカウンターとして使用できます。そのためには、AVRのTOSC1端子およびTOSC2端子に32.768 kHz (訳註: 215)の水晶…

CTCモードのTimer0で生成した時間遅延に何サイクルを要しているか数える

1回のループに何サイクルかかっているのかを1命令ずつ数え上げてみる。クロックとの対応を見るため、PB0からクロックが出力されるようヒューズを設定した。 今、クロックはノミナル8 MHzなので1サイクルは1 ÷ 8 MHz = 0.125 us。下のプログラムは1ループに33…

CTCモードのTimer0で時間遅延を生成する

p.288 今度は、タイマーオーバーフローではなくコンペアマッチを利用して時間遅延を生成してみる。CTCはClear Timer on Compare Match。 一定の時間が経過するたびにPB6の出力をトグルする。コードはほぼテキストのままである。クロックは内蔵の8 MHz、コン…

ノーマルモードのTimer0で生成した時間遅延に何サイクルを要しているか数える

p.279 1回のループに何サイクルかかっているのかを1命令ずつ数え上げてみる。クロックとの対応を見るため、PB0からクロックが出力されるようヒューズを設定した。 今、クロックはノミナル8 MHzなので1サイクルは1 ÷ 8 MHz = 0.125 us。下のプログラムは1ルー…

ノーマルモードのTimer0で実際に時間遅延を生成する

p.278 一定の時間が経過するたびにPB6の出力をトグルする。コードはほぼテキストのままである。クロックは内蔵の8 MHz、初期カウント値を0xF2にした結果、約4.8 usの時間遅延が生成された。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIG…

ノーマルモードのTimer0を設定する手順

p.277 非公式訳 ノーマルモードのTimer0で時間遅延を生成するときは下の手順を実行します。 TCN0レジスターに初期カウント値をロードします。 ノーマルモードと適切な分周比とが選択されるよう、TCCR0A、TCCR0Bの各レジスタを設定します。クロックソースを選…

フラグをクリアする

p.277 非公式訳: このフラグ(TOV0; Timer0 Overflow)の奇妙なところは、クリアするためには1を書き込む必要があるということです(訳註: オーバーフロー割り込みの実行されたときにはハードウェアによってクリアされる)。実はこのルールは、AVRチップのすべて…