本文へスキップ

アトメル社のAVRマイコンをつかった電子工作および無線を使った電子工作を紹介します。





ホーム > 工作室トップ > 時計付温度計

時計付温度計

前頁で実験した時計の回路およびソフトを利用して温度計をつくります。表示は時計と温度を表示させます。三行目に気温を表示させます。温度は温度センサLM61CIZ(秋月電子さんで購入)を使用します。
ここではADコンバータの使い方について確認します。

1.仕様

項目 内容
機能 1行目:年月日を表示します。
2行目:時分秒を 表示します。
3行目:温度を表示します。
温度は1秒毎に更新します。
時計変更モードを持つ。[SET]、[UP]、[DOWN]の3つのスイッチを持ちます。。
時計変更モードには[SET]と[UP]を同時に押します。
[時計変更モード]
  SET:1回押す都度に年→月→日→時→分→秒の順に切り替わります。
  UP:押す毎に選択された項目が1ずつ加算します。上限まで行くと下限値から加算をします。
  DOWN:押す毎に選択された項目が1ずつ減算します。下限まで行くと上限値から減算をします。
  時計変更モードから通常モードへの復帰は時計設定モードで順に押していき「年→月→日→時→分」の次は通常モードとなります。
タイマ周期測定用出力を持ちます。
電源 単3ニッケル水素電池4本(4.8V)
LCD 形名:SC2004CS
表示:20文字X4行
データ:4ビットモードで使用します。
マイコン ATmega328
温度センサ 温度センサはLM61CIZを使用します。
ADコンバータの基準電源はシャントレギュレータTL451を使用します。
LCD制御 CHANさんのEZ-LCDを使用します。

2.回路

2.1.温度センサLM61CIZ
計測温度範囲 -30℃~100℃
精度 25℃で±3℃
電源電圧 +2.7V~+10V
出力電圧=(+10mV/℃ X T℃) + 600mV
LM61CIZピン配置

ピン配置


2.2.シャントレギュレータTL431
レファレンス電圧Vref[V]@25℃ カソード電流10mA  最小 標準 最大
2.47 2.495 2.52
カソード電流I[mA] 100
印加電圧VKA[V] ref

TL431ピン配置

ピン配置


2.3.回路図
温度計回路図

回路図

電源はニッケル水素電池を使用します。
電源電圧をそのままマイコンのADコンバータの基準電圧に使用するとかなり変動がありますので今回はシャントレギュレータをADコンバータの基準電圧にします。
温度センサおよび基準電圧ICの電源端子はマイコンのポートに接続して、マイコンから電源のON/OFFの操作をします。
部品表
名称 形名 メーカ 購入先 数量
LCD SC2004CS 秋月電子
マイコン ATmega328 アトメル 秋月電子
抵抗 10kΩ 1/4W 秋月電子
半固定抵抗 10kΩ 秋月電子
押しボタンスイッチ 赤色タクトスイッチ 秋月電子
温度センサ LM61CIZ ナショセミ 秋月電子
;シャントレギュレータ TL431ACZ 秋月電子
単3電池ホルダ4本用 秋月電子
単3ニッケル水素電池
温度計組立図

組立図

3.フローチャート

温度計フローチャート

フローチャート

メインルーチンは前頁の「時計をつくる」と同じです。
前頁のフローチャート時計更新の部分に温度センサからデータを取得するルーチンを入れます。
温度センサおよび基準電源は使用するときだけ電源を入れるようにします。

4.プログラムの実行

温度計実行画面

実行画面

プログラムを実行すると「年月日」、「時分秒」、「温度」が表示されます。
温度センサ立ち上がり波形

温度センサ立ち上がり波形

温度センサに電源が入ったときに出力電圧が立ち上がるまでの時間を測定します。
10μs程度で立ち上がることがわかります。
温度センサに電源を入れてから6ms後にAD変換を行うようにプログラムを組んでいます。
温度センサON時間

温度センサON時間

PC2のON時間を測定します。
ON時間は6.2msでした。

5.プログラム

ADC関連関連レジスタ設定


(1)ADMUXレジスタ
REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0
設定値 0 0 0 0 0 0 0 0

基準電圧REFS1:0選択
REFS1 REFS0 基準電圧
AREF端子を基準電圧とします。
AVCCを基準電圧(電源電圧)とします。
1 0 禁止
内部1.1Vを基準電圧とします。

ADLAR
ADLAR 10ビットデータ配置
0 左揃え
1 右揃え

アナログチャンネル選択
MUX3~0 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001~
1101
1110 1111
アナログ入力チャンネル ADC0 ADC1 ADC2 ADC3 ADC4 ADC5 - - ADC8 予約 1.1V 0V
備考 PC0 PC1 PC2 PC3 PC4 PC5 - - 温度 - VBG GND

(2)ADCSRA
ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
設定値 0 0 0 0 0 0 1 1

AD変換クロック選択
ADPS2 0 0 0 0 1 1 1 1
ADPS1 0 0 1 1 0 0 1 1
ADPS0 0 1 0 1 0 0 0 1
AD変換クロック CK/2 CK/2 CK/4 CK/8 CK/16 CK/32 CK/64 CK/128
ADCのクロックは50~200kHzの範囲に設定します。
(3)ADCSRBレジスタ
- ACME - - - ADTS2 ADTS1 ADTS0
設定値 0 0 0 0 0 0 0

AD変換トリガソース
ADTS2 ADTS1 ADTS0 トリガソース
0 0 0 連続変換
0 0 1 アナログ比較器
 0  1 0   外部割り込み要求0
0 1 1
0 0 タイマ/カウンタ0オーバーフロー
1 0 1
1 1 0 タイマ/カウンタ1オーバーフロー
1 1  タイマ/カウンタ1キャプチャ

(4)DIDR0レジスタ
- - ADC5D ADC4D ADC3D ADC2D ADC1D ADC0D
設定値 0 0 0 0 0 0 0 1
 '1'を設定でアナログ入力
 '0'を設定でデジタル入力

プログラム
#include    <avr/io.h>
#include    <avr/interrupt.h>
#include    <avr/sleep.h>
#include    "hd44780.h"
#include    <util/delay.h>

// 時計
#define     RED     0x20    // 赤スイッチ
#define     YELLOW  0x10    // 黄スイッチ
#define     GREEN 0x08  // 緑スイッチ
#define     MODE    (RED | YELLOW)          // 時計変更モード
#define     SWON    (RED | YELLOW | GREEN)  // 全てのスイッチがON
// 温度計
#define     LM61_ON     PORTC |= 1 << PORTC2    // LM61電源ON
#define     LM61_OFF    PORTC &= ~(1 << PORTC2)   // LM61電源OFF
#define     ADC_ON      ADCSRA |= (1 << ADEN) // adc許可
#define     ADC_OFF     ADCSRA &= ~(1 << ADEN)  // adc停止
#define     ADC_START ADCSRA |= 1 << ADSC   // adcスタート
#define     V_REF   2495                    // レファレンス電圧

void    InitHard(void);     // ハードウェア初期化
void    InitTime(void);     // 時間初期化
void    CalcDate(uint8_t, uint8_t);     // 時計演算 0:加算、1:減算
void    BlinkDisp(uint8_t, uint8_t);    // 指定位置ブリンクする。、0:通常、1:前桁の文字を表示
void    DateDisp(uint8_t, uint8_t, uint8_t);    // 指定場所の文字を更新する。
void    UpdateTime(void);   // 時計更新
void    DoADC(void);            // ADCを動作させ表示させる。  1秒毎
uint16_t    ReadADCCel(void); // ADCからデータを読み出す。デジタルフィルタ付
void    AdcDisp( uint16_t);     // ADC値を変換し表示


uint8_t     g_u8BlinkFlg = 0;   // 0:点灯、1:消灯
volatile uint8_t g_u8IntTimeFlg;    // 時計割り込みフラグ

uint8_t   g_u8CalenderBuf[6];       // 時計データ保存、データはBCDで保存。上位4bit:10の位、下位4bit:1の位

union switch_states                 // スイッチ状態フラグ
{
    uint8_t BYTE;
    struct
    {
        uint8_t mode      :1; // 時計変更モード
        uint8_t mode_keep :1; // 時計変更モード確定
        uint8_t red       :1; // 赤スイッチON
        uint8_t red_keep  :1; // 赤スイッチON->OFF
        uint8_t yellow    :1; // 黄スイッチON
        uint8_t yellow_keep :1; // 黄スイッチON->OFF
        uint8_t green     :1; // 緑スイッチON
        uint8_t green_keep  :1; // 緑スイッチON->OFF
    }BIT;
};          
union switch_states g_uSwitchState;

uint8_t g_u8CalenderArray[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // カレンダ通常年
                        { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};     // カレンダ閏年
uint8_t   g_u8LcdStr[] = {'-', '-', '-', '-', '.', '-', 0xdf, 'C'};     // LCD表示データ格納バッファ
    
int main(void)
{
    uint8_t   u8PortcState;
    uint8_t   u8LcdLocate;      // 変更位置記憶 0:yy, 1:mm, 2:dd, 3:hhh, 4:mmm, 5:sss
    uint8_t u8LocateChange = 0; // 表示位置変更フラグ 0:変更位置移動なし、1:移動あり  

    InitHard();                     // ポート、LCD初期化
    g_u8IntTimeFlg = 0;             // 250ms毎にカウント
    InitTime();                     // 時計初期化および初期値表示 
    
    sei();      // 割り込み許可
    
    while(1)
    {
        sleep_enable();     //sleep許可
        sleep_cpu();        //sleep中
        sleep_disable();    // sleep禁止
        
        // 時計更新
        if (g_u8IntTimeFlg > 3)   // 一秒経過
        {
            UpdateTime();   // 時計更新
            g_u8IntTimeFlg = 0;
            DoADC();            // 1秒毎にADCを動作させ温度をLCDに表示する。
        }

        // 時計調整
        u8PortcState = ~PINC & SWON;
        
        if (g_uSwitchState.BIT.mode_keep == 0)  // 時計変更モード確認
        {
            if ( (u8PortcState == MODE))    // 赤と黄色のスイッチを同時on。
            {
                g_uSwitchState.BIT.mode = 1;
            }
            else if ( (u8PortcState == 0) && (g_uSwitchState.BIT.mode == 1))    
            // 赤と黄スイッチがoff->on->offで時計変更モードに移行
            {
                g_uSwitchState.BIT.mode_keep = 1;
                u8LcdLocate = 0;
                BlinkDisp(u8LcdLocate, 0);  // 年の位置ブリンク表示
            }       
        }
        else if (g_uSwitchState.BIT.mode_keep)      // 時計変更モード、スイッチは赤->黄->緑の順で優先順位が低くなる。
        {                                       // 赤と緑が押されだ場合は赤が優先される。
            u8LocateChange = 0;                     //表示位置変更フラグクリア
            if (u8PortcState == RED)    // 赤がon 
            {
                g_uSwitchState.BYTE = 0;
                g_uSwitchState.BIT.mode_keep = 1;
                g_uSwitchState.BIT.red = 1;
            }
            else if (u8PortcState == YELLOW)    // 黄がon
            {
                g_uSwitchState.BYTE = 0;
                g_uSwitchState.BIT.mode_keep = 1;
                g_uSwitchState.BIT.yellow = 1;
            }
            else if (u8PortcState == GREEN)     // 緑がon
            {
                g_uSwitchState.BYTE = 0;
                g_uSwitchState.BIT.mode_keep = 1;
                g_uSwitchState.BIT.green = 1;
            }
            else if ( u8PortcState == 0)    // スイッチが全部off、スイッチがoff->on->offで各動作をする。
            {
                if (g_uSwitchState.BIT.red == 1)        // 赤がonだった
                {
                    g_uSwitchState.BIT.red = 0;
                    u8LcdLocate++;
                    u8LocateChange = 1;
                }           
                if (g_uSwitchState.BIT.yellow == 1)   // 黄がonだった
                {
                    g_uSwitchState.BIT.yellow = 0;
                    CalcDate( u8LcdLocate, 0);
                }
                if (g_uSwitchState.BIT.green == 1)      // 緑がonだった
                {
                    g_uSwitchState.BIT.green = 0;
                    CalcDate(u8LcdLocate, 1);
                }

            }
            BlinkDisp(u8LcdLocate, u8LocateChange);     // ブリンク、カレンダ更新
        }
    } // while loop
}

void InitHard(void)
{
    // port初期化
    DDRB = 0xff;        // portb7:0=出力
    PORTB = 0;
    DDRC = 0x06;        // portc2:1=出力
    PORTC = 0;
    DDRD = 0xff;    // portd7:0=出力
    PORTD = 0;
    // LCD初期化
    lcd_init();
    // 16bitタイマ設定
    // CTC動作、1/8分周
    OCR1A = 31686;      // 31249 設定値
    TCCR1A = (1 << COM1A0);
    TCCR1B = 0x0a;  // スタート
    TIMSK1 = 1 << OCIE1A; // ctc割り込み許可
    // ADC
    ADMUX = 0;  // Vref = 外部レファレンス
    ADCSRA = (1 << ADPS1) | (1 << ADPS0); // adcクロック = 125kHz
    DIDR0 = (1 << ADC0D); // adc0デジタル入力バッファ禁止
    //ADC_ON;
    
    // スリープモードはアイドルに設定
    set_sleep_mode(SLEEP_MODE_IDLE);
}

void InitTime(void)
{
    g_u8CalenderBuf[0] = 0x12;
    g_u8CalenderBuf[1] = 6;
    g_u8CalenderBuf[2] = 1;
    g_u8CalenderBuf[3] = 0;
    g_u8CalenderBuf[4] = 0;
    g_u8CalenderBuf[5] = 0;

    lcd_locate( 0, 0);              // 1行目:年月日表示
    lcd_putc((g_u8CalenderBuf[0] >> 4) + 0x30);     // 年
    lcd_putc((g_u8CalenderBuf[0] & 0x0f) + 0x30);
    lcd_putc('/');
    lcd_putc((g_u8CalenderBuf[1] >> 4) + 0x30);     // 月
    lcd_putc((g_u8CalenderBuf[1] & 0x0f) + 0x30);
    lcd_putc('/');
    lcd_putc((g_u8CalenderBuf[2] >> 4) + 0x30);     // 分
    lcd_putc((g_u8CalenderBuf[2] & 0x0f) + 0x30);
        
    lcd_locate( 1, 0);              // 2行目:時分秒表示
    lcd_putc((g_u8CalenderBuf[3] >> 4) + 0x30);     // 時
    lcd_putc((g_u8CalenderBuf[3] & 0x0f) + 0x30);
    lcd_putc(':');
    lcd_putc((g_u8CalenderBuf[4] >> 4) + 0x30);     // 分
    lcd_putc((g_u8CalenderBuf[4] & 0x0f) + 0x30);
    lcd_putc(':');
    lcd_putc((g_u8CalenderBuf[5] >> 4) + 0x30);     // 秒
    lcd_putc((g_u8CalenderBuf[5] & 0x0f) + 0x30);
}

void DoADC(void)        // ADCを動作させ表示させる。1秒毎
{
    uint16_t result;
    
    LM61_ON;                // 温度センサ電源ON
    ADC_ON;                 // ADCイネーブル
    DELAY_US(6000);         // wait 60ms レファレンス電圧、LM61、ADC安定待ち
    ADC_START;              // ADC動作開始
    result = ReadADCCel();  // ADCからデータを読み出す。デジタルフィルタ付
    ADC_OFF;                // ADC禁止
    LM61_OFF;           // 温度センサ電源OFF
    AdcDisp(result);        // LCDにデータを表示    
}

uint16_t ReadADCCel(void) // 指定されたチャンネルのADCからデータを読み出す。
{
    static uint16_t adc_data1, adc_data2, adc_data3;
    
    while((ADCSRA & (1 << ADSC)));
    adc_data3 = adc_data2;
    adc_data2 = adc_data1;
    adc_data1 = ADCW;
    
    return ((adc_data3 + adc_data2 + adc_data2 + adc_data1) / 4);
}

void AdcDisp( uint16_t result)          // ADC値を変換し表示
{
    int16_t i;
    long    sum;

    sum = ((long)result * V_REF/ 1024) - 600;
    // sumの正常範囲チェック
    if ( (sum > 1800) || ( sum < -400))
    {
        for ( i = 0; i < 4; i++)
        {
            g_u8LcdStr[i] = '-';
        }
        g_u8LcdStr[5] = '-';
    }
    else
    {
        if ( sum < 0)
        {
            sum *= -1;
            g_u8LcdStr[0] = '-';
        }
        else
        {
            g_u8LcdStr[0] = 0x20;
        }
        g_u8LcdStr[1] = 0x20;
        g_u8LcdStr[2] = 0x20;
        g_u8LcdStr[3] = 0x30;
        g_u8LcdStr[5] = 0x30;
            
        // binary -> BCDキャラクタ変換
        for ( i = 5; i > 0; i--)
        {
            g_u8LcdStr[i] = (sum % 10) + 0x30;
            sum /= 10;
            if ( i == 5)
            {
                i--;
            }
            if ( sum <= 0)
            {
                break;
            }   
        }
    }   
    // LCDに表示
    lcd_locate( 2, 0);
    for ( i = 0; i < 8; i++)
    {
        lcd_putc(g_u8LcdStr[i]);
    }   
}

void    BlinkDisp(uint8_t dat, uint8_t flg)   //指定位置から2文字分ブリンクする。
{
    uint8_t n, nn, raw, col;
    
    switch( dat)
    {
    case 0:   // 年
        lcd_locate(0, 0);
        break;
    case 1:   // 月
        lcd_locate(0, 3);
        raw = 0;
        col = 0;
        break;
    case 2: // 日
        lcd_locate(0, 6);
        raw = 0;
        col = 3;
        break;
    case 3: // 時
        lcd_locate(1, 0);
        raw = 0;
        col = 6;
        break;
    case 4:   // 分
        lcd_locate(1, 3);
        raw = 1;
        col = 0;
        break;
    case 5:   // 秒
        lcd_locate(1, 6);
        raw = 1;
        col = 3;
        break;
    default:    // 時計修正モード終了
        g_uSwitchState.BYTE = 0;
        lcd_locate(1, 6);
        lcd_putc((g_u8CalenderBuf[5] >> 4) + 0x30);
        lcd_putc((g_u8CalenderBuf[5] & 0x0f) + 0x30);
        return;
        break;  
    }

    if ( g_u8BlinkFlg == 0)
    {
        // 消灯
        g_u8BlinkFlg = 1;

        lcd_putc(' ');
        lcd_putc(' ');
    }
    else
    {
        // 点灯
        g_u8BlinkFlg = 0;
        lcd_putc((g_u8CalenderBuf[dat] >> 4) + 0x30);
        lcd_putc((g_u8CalenderBuf[dat] & 0x0f) + 0x30);
    }
    
    if (flg == 1)
    {   
        lcd_locate(raw, col);
        lcd_putc((g_u8CalenderBuf[dat - 1] >> 4) + 0x30);
        lcd_putc((g_u8CalenderBuf[dat - 1] & 0x0f) + 0x30);     
    }
}


void CalcDate(uint8_t dat, uint8_t flg)
{
    int sum, day;
    
    switch ( dat)
    {
    case 0:   // 年
        sum = (g_u8CalenderBuf[dat] >> 4) * 10 + (g_u8CalenderBuf[dat] & 0x0f);
        switch(flg)
        {
        case 0:   // 加算
            if ( ++sum > 99)
            {
                sum = 0;
            }
            break;
        default:    // 減算
            if ( --sum < 0 )
            {
                sum = 99;
            }
            break;
        }
        g_u8CalenderBuf[dat] =((sum / 10) << 4) | (sum % 10);
        break;
    case 1:   // 月
        sum = (g_u8CalenderBuf[dat] >> 4) * 10 + (g_u8CalenderBuf[dat] & 0x0f);
        switch(flg)
        {
        case 0:   // 加算
            if ( ++sum > 12)
            {
                sum = 1;
            }
            break;
        default:    // 減算
            if ( --sum < 1 )
            {
                sum = 12;
            }
            break;
        }
        g_u8CalenderBuf[dat] =((sum / 10) << 4) | (sum % 10);
        break;
    case 2:   // 日
        sum = (g_u8CalenderBuf[1] >> 4) * 10 + (g_u8CalenderBuf[1] & 0x0f);             // 月を抽出   
        if ((((g_u8CalenderBuf[0] >> 4) * 10 + (g_u8CalenderBuf[0] & 0x0f)) % 4) == 0)  // うるう年なら
        {
            day = g_u8CalenderArray[1][sum - 1];
        }
        else
        {
            day = g_u8CalenderArray[0][sum -1];
        }
        sum = (g_u8CalenderBuf[dat] >> 4) * 10 + (g_u8CalenderBuf[dat] & 0x0f);
        switch(flg)
        {
        case 0:   // 加算
            if ( ++sum > day)
            {
                sum = 1;
            }
            break;
        default:    // 減算
            if ( --sum < 1 )
            {
                sum = day;
            }
            break;
        }
        g_u8CalenderBuf[dat] =((sum / 10) << 4) | (sum % 10);
        break;
    case 3:   // 時
        sum = (g_u8CalenderBuf[dat] >> 4) * 10 + (g_u8CalenderBuf[dat] & 0x0f);
        switch(flg)
        {
        case 0:   // 加算
            if ( ++sum > 23)
            {
                sum = 1;
            }
            break;
        default:    // 減算
            if ( --sum < 1 )
            {
                sum = 23;
            }
            break;
        }
        g_u8CalenderBuf[dat] =((sum / 10) << 4) | (sum % 10);
        break;
    default:    // 分、秒
        sum = (g_u8CalenderBuf[dat] >> 4) * 10 + (g_u8CalenderBuf[dat] & 0x0f);
        switch(flg)
        {
        case 0:   // 加算
            if ( ++sum >59)
            {
                sum = 0;
            }
            break;
        default:    // 減算
            if ( --sum < 1 )
            {
                sum = 59;
            }
            break;
        }
        g_u8CalenderBuf[dat] =((sum / 10) << 4) | (sum % 10);
        break;      
    }
}

void    UpdateTime(void)        // 時計
{
    uint8_t sum, day, flg = 0;
    
    // 秒
    sum = (g_u8CalenderBuf[5] >> 4) * 10 + (g_u8CalenderBuf[5] & 0x0f);
    if ( ++sum > 59)
    {
        g_u8CalenderBuf[5] = 0;
        flg = 1;
        DateDisp(1, 6, g_u8CalenderBuf[5]);
    }
    else
    {
        g_u8CalenderBuf[5] =((sum / 10) << 4) | (sum % 10);
        DateDisp(1, 6, g_u8CalenderBuf[5]);
        return;
    }
    // 分
    if ( flg == 1) 
    {
        flg = 0;
        sum = (g_u8CalenderBuf[4] >> 4) * 10 + (g_u8CalenderBuf[4] & 0x0f);
        if( ++sum > 59)
        {
            g_u8CalenderBuf[4] = 0;
            flg = 1;
            DateDisp(1, 3, g_u8CalenderBuf[4]);         
        }
        else
        {
            g_u8CalenderBuf[4] =((sum / 10) << 4) | (sum % 10);
            DateDisp(1, 3, g_u8CalenderBuf[4]);
        }
    }

    // 時
    if ( flg == 1)
    {
        flg = 0;
        sum = (g_u8CalenderBuf[3] >> 4) * 10 + (g_u8CalenderBuf[3] & 0x0f);
        if( ++sum > 23)
        {
            g_u8CalenderBuf[3] = 0;
            flg = 1;
            DateDisp(1, 0, g_u8CalenderBuf[3]);
        }
        else
        {
            g_u8CalenderBuf[3] =((sum / 10) << 4) | (sum % 10);
            DateDisp(1, 0, g_u8CalenderBuf[3]);
        }
    }   
    // 日
    if ( flg == 1)
    {
        flg = 0;

        sum = (g_u8CalenderBuf[1] >> 4) * 10 + (g_u8CalenderBuf[1] & 0x0f);             // 月を抽出   
        if ((((g_u8CalenderBuf[0] >> 4) * 10 + (g_u8CalenderBuf[0] & 0x0f)) % 4) == 0)  // うるう年なら
        {
            day = g_u8CalenderArray[1][sum - 1];
        }
        else
        {
            day = g_u8CalenderArray[0][sum -1];
        }
        
        sum = (g_u8CalenderBuf[2] >> 4) * 10 + (g_u8CalenderBuf[2] & 0x0f);
        if( ++sum > day)
        {
            g_u8CalenderBuf[2] = 1;
            DateDisp(0, 6, g_u8CalenderBuf[2]);
            flg = 1;
        }

        else
        {
            g_u8CalenderBuf[2] =((sum / 10) << 4) | (sum % 10);
            DateDisp(0, 6, g_u8CalenderBuf[2]);
        }
    }   
    // 月
    if ( flg == 1)
    {
        flg = 0;
        sum = (g_u8CalenderBuf[1] >> 4) * 10 + (g_u8CalenderBuf[1] & 0x0f);
        if( ++sum > 12)
        {
            g_u8CalenderBuf[1] = 1;
            DateDisp(0, 3, g_u8CalenderBuf[1]);
            flg = 1;
        }
        else
        {
            g_u8CalenderBuf[1] =((sum / 10) << 4) | (sum % 10);
            DateDisp(0, 3, g_u8CalenderBuf[1]);
        }
    }
    // 年
    if ( flg == 1)
    {
        flg = 0;
        sum = (g_u8CalenderBuf[0] >> 4) * 10 + (g_u8CalenderBuf[0] & 0x0f);
        if( ++sum > 99)
        {
            g_u8CalenderBuf[0] = 0;
            DateDisp(0, 0, g_u8CalenderBuf[0]);
            flg = 1;
        }
        else
        {
            g_u8CalenderBuf[0] =((sum / 10) << 4) | (sum % 10);   
            DateDisp(0, 0, g_u8CalenderBuf[0]);
        }
    }   
}

void    DateDisp(uint8_t raw, uint8_t col, uint8_t dat)   // 指定場所の文字を更新する。
{
    lcd_locate(raw, col);
    lcd_putc((dat >> 4) + 0x30);
    lcd_putc((dat & 0x0f) + 0x30);  
}

SIGNAL(TIMER1_COMPA_vect) // 0.25秒ごとに割込発生
{
    g_u8IntTimeFlg++; 
}