The AVR Microcontroller and Embedded Systems Using Assembly and C

23. アナログコンパレーター / 非公式訳

ATmega328Pデータシート非公式訳: 23. アナログコンパレーター 23.1 概要 AIN0ピン(PD6)をプラス入力端子、AIN1ピン(PD7)をマイナス入力端子(基準電位)とするコンパレーターです。AIN0ピンの入力電圧のほうがAIN1ピンの入力電圧よりも高いときにアナログコン…

タイマー1 / インプットキャプチャ機能 / パルス幅を測る

pp.496-497 今度は周期ではなくパルス幅を測る。rising edgeをキャプチャしたら次回はfalling edgeをキャプチャし、falling edgeをキャプチャしたら次回はrising edgeをキャプチャして、rising edgeからfalling edgeまでのカウント数を数える。 ISR()はフラ…

タイマー1 / インプットキャプチャ機能 / 周期を測る

pp.494-495 今50 Hzの方形波(周期20 ms)を入力している。 #define F_CPU 8000000UL #include <avr/io.h> #include <avr/interrupt.h> #include "LCDClass.h" LCDClass lcd("PD7","PD6","PD5","PD4","PD3","PD2"); // (RS,EN,D4,D5,D6,D7)の順番で指定する。 volatile uint16_t timeOld; </avr/interrupt.h></avr/io.h>…

タイマー1 / インプットキャプチャ機能 / 外部パルスのパルスエッジをキャプチャする

p.494 ICP1ピン(PB0)に入力したパルスのパルスエッジが検出されたら、そのときのタイマー1のカウント値をキャプチャして表示する。 #define F_CPU 8000000UL #include <avr/io.h> #include <avr/interrupt.h> #include "LCDClass.h" LCDClass lcd("PD7","PD6","PD5","PD4","PD3","PD2");</avr/interrupt.h></avr/io.h>…

タイマー0 / 強制アウトプットコンペアマッチ

p.480 実際にはコンペアマッチしていないのに、コンペアマッチしたことを示す信号がウェーブフォームジェネレーターへ供給される。何に使うのかはわからない。 非公式訳: FOC0Aビットが意味を持つのは、WGM02:00の各ビットでPWMモード以外のモードを指定した…

タイマー0 / CTCモード / 途中でコンペア値をロードし直す / 割り込みを使う

pp.479-480 前回と同じようなことを今度は割り込みを使っておこなう。 下のプログラムは、コンペアマッチするたびに0,1,2,4,8,16,32,64の順番でコンペア値をロードし直す。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R16, HIGH(RAMEND) OUT SP…

タイマー0 / CTCモード / 途中でコンペア値をロードし直す

p.478 これまではコンペア値を固定していたが、ここではプログラムの途中でコンペア値をロードし直して随時パルス幅が変更できるようにする。 ; PD6 (OC0A)のIOをOUTにする。 SBI DDRD, PD6 BEGIN: ; Loの長さを設定する LDI R20, 0 OUT OCR0A, R20 ; コンペ…

タイマー0 / CTCモード / コンペアマッチA時にOC0Aピンをトグルする

pp.476-477 今度はCTCモードにして、コンペアマッチ時に出力をトグルする。 CTCモードであるため、コンペアマッチした次のタイミングでカウント値が0に戻る。 ここでは、内部クロックを1024分周し、コンペア値を2にした。 パルス幅: (2+1) * 1/(8 MHz/1024) …

タイマー0 / ノーマルモード / コンペアマッチA時にOC0Aピンをトグルする

pp.474-475 今度はノーマルモードにして、コンペアマッチ時に出力をトグルしてみる。ノーマルモードであるため、コンペアマッチしてもカウントはとまらない。結局コンペア値は関係ない。 ここでは、内部クロックを1024分周してカウントしている。 パルス幅: …

タイマー0 / CTCモード / コンペアマッチA時にOC0Aピンをトグルする

p.474 SBI DDRD, PD6 ; PD6 (OC0A)のIOをOUTにする。 LDI R20, 3 ; コンペア値Aを3にする。カウント値が0に戻った瞬間に何かが起きる。 OUT OCR0A, R20 LDI R20, (1 << COM0A0) | (1 << WGM01); コンペアマッチA時にOC0A (PD6)をトグル。CTCモード OUT TCCR0…

タイマー0 / コンペアマッチA時にOC0Aピンをセットする

p.474 SBI DDRD, PD6 ; PD6 (OC0A)のIOをOUTにする。 LDI R20, 5 ; コンペア値Aを5にする。だからカウント値が6になった瞬間に何かが起きる。 OUT OCR0A, R20 LDI R20, (1 << COM0A1) | (1 << COM0A0); コンペアマッチA時にOC0A (PD6)をセットする。 OUT TCC…

DAコンバーター / 電圧源によるR-2R方式

pp.443-446 ATmega328PはDACペリフェラルを内蔵していない。 テキストはパラレル入力のDAC0808を使っているが、ここでは、DACを自作する / 電圧源によるR-2R方式 / LabVIEWで制御する -のときに試したDACを使う。 単に0から255まで1ずつ増やしてポートDから…

ADコンバーター / 二酸化炭素(CO2)センサー / 基準電圧IC REF5020AIDを使う

テキストからは逸れるが、基準電圧IC REF5020AID (2.048 V±0.1%)をADコンバーターの基準電圧に使ってみる。1 LSBが丁度2 mVになるので計算が楽。 #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include "LCDClass.h" const uint16_t mVREF = 2048; const ui</util/delay.h></avr/io.h>…

ADコンバーター / 自動トリガリングモード

参考: 組込み開発のための実践的プログラミング, pp.125-128 自動トリガリングモードはThe AVR Microcontroller and Embedded Systems Using Assembly and C: Using Arduino Uno and Atmel Studioでは取り上げていない。フリーランニングモードのみ、ADCペリ…

ADコンバーター / 二酸化炭素(CO2)センサー

テキストは応用例として温度センサーを試しているが、ここではGravity - 赤外線CO2センサ/メーター - スイッチサイエンスを使ってみる。 #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include "LCDClass.h" const uint16_t mVref = 4800; // 実測値 int ma</util/delay.h></avr/io.h>…

ADコンバーター / 変換が完了したら割り込む / Cで記述する

p.438 前回と同じことをCで記述する。 #include <avr/io.h> #include <avr/interrupt.h> ISR(ADC_vect){ PORTD = ADCL; // AD変換が完了したらAD変換値を読み出す。 PORTB = ADCH; ADCSRA |= (1 << ADSC); // 変換開始ビットをセットし直す。 } int main(){ DDRB = 0xFF; DDRD = 0xFF; A</avr/interrupt.h></avr/io.h>…

ADコンバーター / 変換が完了したら割り込む

pp.436-438 今度は変換完了時に割り込む。0 v→基準電圧→0 v→基準電圧→... の順にごくゆっくり変化する電圧をAD変換してみる。 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 .E…

ADコンバーター / 変換完了をポーリングで確認する / Cで記述する

p.437 前回と同じことを今度はCで記述してみる。 #include <avr/io.h> int main(){ DDRB = 0xFF; DDRD = 0xFF; ADMUX |= (1 << REFS0); // 基準電圧はAVCC ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN); // 128分周。ADCペリフェラルをオン。 </avr/io.h>…

ADコンバーター / 変換完了をポーリングで確認する

p.436 ここではテキストどおり変換完了割り込みフラグ(ADIF)をポーリングで監視しているが、ADCペリフェラル / CdSを使った明るさセンサー / 上位3ビット値(0~7)だけを8セグメントLEDバーに表示する -のように変換開始ビット(ADSC)がクリアされるのを監視す…

ADコンバーター / 変換完了をポーリングで確認するときのプログラミング手順

pp.435-436 非公式訳 ADCに使う端子のIOをINにする。 ADCモジュールをオンにする。電源オン時は省電力化の目的でオフになっている。 変換速度を選ぶ。変換速度の選択にはADCSRA (ADC Control and Status Register A)のADPS2:0ビットを使う。 電圧基準およびA…

ADコンバーター

ATmega328Pデータシート(DS40002061A-page 248)抄訳(非公式訳): 最大の分解能を得たいときは、ADCへ供給するクロックの周波数を50 kHz~200 kHzにする。 分解能が10ビットも要らなければ、ADCへ供給するクロックを200 kHzよりも高くしてサンプリングレートを…

マトリクスキーパッド4×4 / Cで記述する / 任意の端子に接続できるようにする

テキストからは逸れるが今度は任意の端子を選んで接続できるようにする。セット、クリアを、ポート単位ではなくピン1本ずつ行う。 https://github.com/ti-nspire/AVR/tree/master/MatrixKeypad サンプルファイル: #define F_CPU 8000000UL #include <avr/io.h> #includ</avr/io.h>…

マトリクスキーパッド4×4 / Cで記述する

pp.419-420 同じことを今度はCで記述する。 サンプルファイル: /* 下のように接続する。 ROW0 → PD7 ROW1 → PD6 ROW2 → PD5 ROW3 → PD4 COL3 → PD3 COL2 → PD2 COL1 → PD1 COL0 → PD0 */ #define F_CPU 8000000UL #include <avr/io.h> #include "MatKeyClass.h" const </avr/io.h>…

マトリクスキーパッド4×4

pp.413-418 16個あるスイッチのどれが押されたのかを8ピンだけで検出する。接続は下のように固定する。検出されたキーに割り当てた数値をポートBに出力して動作を確認する。 ; 下のように接続する。 ; ROW0 →PD7 ; ROW1 →PD6 ; ROW2 →PD5 ; ROW3 →PD4 ; COL3…

LCDキャラクターディスプレイ / Cで記述する / ポートもピンもすべて任意に指定できるようにする

テキストからは逸れるが今度は4ビットモードでポートもピンもすべて任意に指定できるようにする。ビットのセット、クリアを、たとい同じポートであったとしてもポート単位ではなくピン1本ずつおこなう。 https://github.com/ti-nspire/AVR/tree/master/LCD_C…

LCDキャラクターディスプレイ / Cで記述する

p.411 下の条件でCで実装する。 4ビットモードを使用する。 RSはPD0に、ENはPD2に、D7:4はPD7:4につなぐ。 サンプルファイル: #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include "LCDClass.h" int main(){ LCDClass lcd; lcd.init(); lcd.gotoRowCol(1,</util/delay.h></avr/io.h>…

LCDキャラクターディスプレイ / LPM命令を使って文字列を書き込む

p.402 これまでは1文字ずつ指定していたが、ここでは文字列で指定できるようにする。 .EQU RS = PD0 .EQU EN = PD2 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 .ENDMACRO IN…

LCDキャラクターディスプレイ / 4ビットモード / 1ポートだけ使う

pp.399-401 4ビットモードなら結局全部で6本つなげばいいだけなので1ポートでまかなえる。上位ニブルにデータを、下位ニブルに制御信号を割り振ることにする。制御信号(RS、EN)をいじるときはデータ(D7:4)には触らず、and vice versa。 .EQU RS = PD0 .EQU E…

LCDキャラクターディスプレイ / 4ビットモード

pp.396-398 今度は4ビットモードを試す。上位ニブル、下位ニブルの順に書き込む。 .EQU RS = PB0 .EQU EN = PB2 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .ENDMACRO INITS…

LCDキャラクターディスプレイ / 8ビットモード

pp.394-396 とにかく何かを1文字ずつ表示する。書き込みしかしないのでR/W端子はGNDに固定した。 .EQU RS = PB0 .EQU EN = PB2 ; スタックポインタの初期化マクロ .MACRO INITSTACK LDI R20, HIGH(RAMEND) OUT SPH, R20 LDI R20, LOW(RAMEND) OUT SPL, R20 .…