今回はアナログ入力を使ってみます。
アナログ値で入力された値をデジタル値に変換して7segLEDに表示することをやってみます。
AtoD_7segLED1.c
//ボリュームのアナログ値をデジタル値に変換し8ビットに丸めてそのまま7segLEDに表示するプログラム
# include <stdio.h>
# define BRR (*((unsigned char *)0xFFA9))
# define TMA (*((unsigned char *)0xFFA6))
# define IRR1 (*((unsigned char *)0xFFF6))
# define IRRTA 0x40
//TimerAはIRR1の第6ビットが立つ
# define ADCSR (*((unsigned char *)0xFFB8))
//A/D変換の設定レジスタ
# define ADDRA (*((unsigned short *)0xFFB0))
//A/D 変換データレジスタA
//A/D 変換データは10 ビットだが、10 ビットのA/D 変換値はこのデータレジスタの上位10 ビットに格納される(下位6 ビットは0)。
# define PMR1 (*((unsigned char *)0xFFE0))
# define PMR5 (*((unsigned char *)0xFFE1))
# define PCR1 (*((unsigned char *)0xFFE4))
# define PCR5 (*((unsigned char *)0xFFE8))
# define PCR7 (*((unsigned char *)0xFFEA))
# define PCR8 (*((unsigned char *)0xFFEB))
# define PDR5 (*((unsigned char *)0xFFD8))
# define PDR7 (*((unsigned char *)0xFFDA))
void wait();
main()
{
unsigned char LED[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7d,0x27,0x7f,0x67};//1の位用配列
unsigned char LED10[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfc,0xa7,0xff,0xe7};//10の位用配列
int i,count=0,count10=0;
//SWの状態記憶用
int OldState=0;
int State=0;
int AtoD_val;
BRR=12; //16MHZ時には12を デフォルトは7 ボーレート変更
PMR1 = 0x00; /*ポート1を汎用IOに設定*/
PMR5 = 0x00; /*ポート5を汎用IOに設定*/
TMA = 0x18; //1秒
PCR1 = 0xff;
PCR5 = 0xff;
PCR7 = 0x00;
PCR8 = 0xff;
for (;;) {/* 無限ループ */
ADCSR = 0x20; //0010 0000 A/D変換開始, 単一モード, チャネル0
while((ADCSR & 0x80) == 0); // エンドフラグがONするまで待つ
ADCSR &= 0x7f; // エンドフラグのリセット
AtoD_val = ADDRA >> 8; // A/D変換値の上位8ビットのみ取得
PDR5 = AtoD_val;//LEDへ表示
wait(20000);
}
return 0;
}
void wait(int n)
{
int i;
for(i=0;i>n;i++);
}
今回新たに追加したレジスタは以下の2つです。
ADCSR : A/Dコントロール/ステータスレジスタ
ビット | ビット名 | 初期値 | R/W | 説 明 |
---|---|---|---|---|
7 | ADF | 0 | R/W | A/Dエンドフラグ [セット条件] • 単一モードでA/D変換が終了したとき • スキャンモードで選択されたすべてのチャネルの変換が1回終了したとき [クリア条件] • 1の状態をリードした後、0をライトしたとき |
6 | ADIE | 0 | R/W | A/Dインタラプトイネーブル このビットを1にセットするとADFによるA/D変換終了割り込み要求(ADI) がイネーブルになります。 |
5 | ADST | 0 | R/W | A/Dスタート このビットを1にセットするとA/D変換を開始します。 単一モードではA/D変換を終了すると自動的にクリアされます。 スキャンモードではソフトウェア、リセット、またはスタンバイモード によってクリアされるまで選択されたチャネルを順次連続変換します。 |
4 | SCAN | 0 | R/W | スキャンモード A/D変換のモードを選択します。 0:単一モード 1:スキャンモード |
3 | CKS | 0 | R/W | クロックセレクト A/D変換時間の設定を行います。 0:変換時間=134ステート(max) 1:変換時間=70ステート(max) 変換時間の切換えは、ADST=0の状態で行ってください。 |
2 | CH2 | 0 | R/W | チャネルセレクト2~0 アナログ入力チャネルを選択します。 SCAN=0のとき 000:AN0 001:AN1 010:AN2 011:AN3 100:AN4 101:AN5 110:AN6 111:AN7 SCAN=1のとき 000:AN0 001:AN0~AN1 010:AN0~AN2 011:AN0~AN3 100:AN4 101:AN4~AN5 110:AN4~AN6 111:AN4~AN7 |
1 | CH1 | 0 | R/W | チャネルセレクト2~0 アナログ入力チャネルを選択します。 |
0 | CH0 | 0 | R/W | チャネルセレクト2~0 アナログ入力チャネルを選択します。 |
アナログ入力の設定を行うレジスタです。
今回は単一モードなのでSCAN=0 開始を示すADST=1 使うポートはAN0とするので
ADCSR = 0x20; //0010 0000 A/D変換開始, 単一モード, チャネル0
と設定しました。
ADDR : A/D データレジスタ
アナログ入力チャネル | 変換結果格納レジスタ | |
---|---|---|
グループ0 | グループ1 | |
AN0 | AN4 | ADDRA |
AN1 | AN5 | ADDRB |
AN2 | AN6 | ADDRC |
AN3 | AN7 | ADDRD |
今回はAN0を使用するので読み取るレジスタはADDRAです。
AtoD_val = ADDRA >> 8; // A/D変換値の上位8ビットのみ取得
動作確認
ボリュームのつまみをひねると7segLEDの表示が変わっていきます。