温度センサLM35DZの出力をPIC16F88でAD変換して,3桁の7セグLEDに表示してみました。
この7セグLEDは,ダイナミックドライブ用に内部で配線されてて11ピンのものです。こりゃ便利ですね。
ソースはこれ→lesson32.c
7セグLEDへの表示は,TMR0割り込みで実行していますが,小数点をつけるのに少々苦労しました。
結局,小数点つきの0~9の表示用数字データを作って配列に入れておき,これを使うことにしました。PORTB=p[tmp1+10]なんてあたりに苦労のあとが忍ばれますなあ(笑)
気温が28.5℃だと,AD変換の結果,tmpという変数に285という値が入りますから,これを100で割ってから,さらに10で割ったときの余りを求めて「2」という数字を得て,tmpを10で割ってからさらに10で割ったときの余りを求めて「8」という数字を得ます。最後にtmpを10で割ったときの余りを求めて「5」という数字を得ます。これで3桁ぶんの数字が得られるのです。LCDの場合と違ってめんどくさいですねー。
/**************************************
16F88 HI-TECH C v.9.83
温度計 LM35DZをRA0(AN0)に接続 7segLED表示
**************************************/
#define _LEGACY_HEADERS
#include "pic.h"
#include "stdlib.h"
#define _XTAL_FREQ 8000000
__CONFIG(DEBUGDIS & LVPDIS & BORDIS & MCLRDIS & PWRTEN & WDTDIS & INTIO);
__CONFIG(FCMDIS & IESODIS);
unsigned int adconv(),tmp,tmp0,tmp1,tmp2;
unsigned char i=0;
unsigned int p[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, //0,1,2,3,4,5,6,7,8,9
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0xa7,0xff,0xef}; //0.,1.,2.,3.,4.,5.,6.,7.,8.,9.
static void interrupt warikomi(void)//割り込み処理で7セグLED表示
{
TMR0IF = 0; //TMR0割り込み禁止
i++;
if(i==3){
i=0;
}
switch(i){
case 0:
PORTA=0b00011000;
PORTB=p[tmp0];
break;
case 1:
PORTA=0b00010100;
PORTB=p[tmp1+10];
break;
case 2:
PORTA=0b00001100;
PORTB=p[tmp2];
break;
}
}
void main()
{
OSCCON = 0b0111000; // 内蔵OSC 8MHz
ADCS2 = 0; //AD変換クロック値設定
ADCS1 = 0;
ADCS0 = 1;
ADFM = 1; // AD変換結果は右詰めで格納
VCFG1 = 0; // 基準電圧はVddとVss
VCFG0 = 0;
ANSEL = 0b00000001; // RA0(AN0)はアナログ
TRISA = 0b00000001; // RA0(AN0)入力
TRISB = 0b00000000; // すべて出力
PORTA = 0b00011100;
PORTB = 0b00000000;
OPTION = 0x00;
TMR0 = 0x00; //TMR0は0からスタート
TMR0IE = 1; //TMR0割り込み許可
GIE = 1; //すべての割り込み許可
while (1)
{
tmp=adconv()*4.53;
tmp2=(tmp/100)%10;
tmp1=(tmp/10)%10;
tmp0=tmp%10;
__delay_ms(100); //100msの時間待ち
}
}
unsigned int adconv()
{
CHS2 = 0; //AD変換ポート設定 RA0(AN0)
CHS1 = 0;
CHS0 = 0;
ADON = 1; //AD変換ON
__delay_us(20); //アクィジション時間 20us
GODONE = 1; //AD変換開始
while(GODONE); //変換完了待ち
return (ADRESH<<8) + ADRESL;
}