main.c

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"    atof()を使うためです
#include "stm8s.h"     STMのライブラリを使うため
#include "usrlib-uart.h"     UARTを使うためのヒラサカ自作ライブラリ
#include "usrlib-sd.h"
        SDカードを使うためのヒラサカ自作ライブラリ
#include "usrlib-lcd.h"       LCDを使うためのヒラサカ自作ライブラリ

float offset_AIN[10];      温度補正値.0〜9まで.
char UARTstr[120];  // UART send buffer    UARTに表示するためのバッファです

// address of data on EEPROM  (offset calinration values)
温度補正値をEEPROMに記録し、不揮発性にします.
EEPROMは4000H番地以降に存在します.
0〜9まであるADC入力それぞれに対する温度補正値の領域をEEPROMに確保します.
char* EEPROM_OFFSET_AIN0 = (char*)0x4000;   AIN0
char* EEPROM_OFFSET_AIN1 = (char*)0x4010;   AIN1
char* EEPROM_OFFSET_AIN2 = (char*)0x4020;   AIN2
char* EEPROM_OFFSET_AIN3 = (char*)0x4030;   AIN3
char* EEPROM_OFFSET_AIN4 = (char*)0x4040;   AIN4
char* EEPROM_OFFSET_AIN5 = (char*)0x4050;   AIN5
char* EEPROM_OFFSET_AIN6 = (char*)0x4060;   AIN6
char* EEPROM_OFFSET_AIN7 = (char*)0x4070;   AIN7
char* EEPROM_OFFSET_AIN8 = (char*)0x4080;   AIN8
char* EEPROM_OFFSET_AIN9 = (char*)0x4090;   AIN9

void Menu(void);


void main(void)      メイン関数です
{
    int i;
    uint32_t block;

    // clock initialization
    //  16MHz HSI
    //  fMASTER 16MHz
    //  fCPU 16MHz
    CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, @CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
    CLK_HSIPrescalerConfig( ACLK_PRESCALER_HSIDIV1 );
    CLK_SYSCLKConfig( BCLK_PRESCALER_CPUDIV1 );
@HSIにしています.HSIはSTM8S内蔵16MHz clockのことです.
AfMASTERのプリスケーラをx1に
BfCPUのプリスケーラをx1に
このようにしてCPU、タイマ、ADCなどに16MHzが供給されるようになります.

    // ADC scan mode 0-9 ch initialization
    ADC1_DeInit();
    ADC1_Init(@ADC1_CONVERSIONMODE_CONTINUOUS, AADC1_CHANNEL_9, BADC1_PRESSEL_FCPU_D4, CADC1_EXTTRIG_TIM, DDISABLE, EADC1_ALIGN_RIGHT, FADC1_SCHMITTTRIG_ALL, GDISABLE);
    HADC1_ScanModeCmd(ENABLE);
    IADC1_DataBufferCmd(ENABLE);
    JADC1_StartConversion();
ADCを初期化します.
@ADCを連続変換モードにするか、一発変換モードにするかの選択._CONTINUOUSなら連続変換、_SINGLEなら一発変換.
AADCの入力AINxのどれをAD変換するかを設定します._9だと10個全部をAD変換._8だとAIN0〜AIN8までの9個をAD変換._0だとAIN0だけをAD変換するようになります.AD変換しないピンは、普通のデジタルIOピンとして使えると思いますが、未確認です.
BADCへ供給するclock周波数を選択します.
ADCのclockは1〜4MHzという制限がありますので、適切なfADC1になるように設定します.ここでは16MHz÷4=4MHzにしています.ちなみに、FCPUという名前でdefineされているのでfCPUを分周するかのごとく誤解してしまいますが、正しくはfMASTERを分周します.これはSTM8Sのライブラリを書いた人の誤解による誤記と思われます.fMASTERはこのサンプルプログラムでは16MHzですから、ADC clockを8MHz〜888kHzの範囲で選択できます.  (ただし、AD変換レートが8MHz〜888kHzになるわけではありません.なぜなら、1回のAD変換に14clock必要だからです)
    ADC1_PRESSEL_FCPU_D2  Prescaler selection fADC1 = fMASTER/2.  
    ADC1_PRESSEL_FCPU_D3  Prescaler selection fADC1 = fMASTER/3.  
    ADC1_PRESSEL_FCPU_D4  Prescaler selection fADC1 = fMASTER/4.    ←これですから16MHz÷4=4MHzになります
    ADC1_PRESSEL_FCPU_D6  Prescaler selection fADC1 = fMASTER/6.  
    ADC1_PRESSEL_FCPU_D8  Prescaler selection fADC1 = fMASTER/8.  
    ADC1_PRESSEL_FCPU_D10  Prescaler selection fADC1 = fMASTER/10.  
    ADC1_PRESSEL_FCPU_D12  Prescaler selection fADC1 = fMASTER/12.  
    ADC1_PRESSEL_FCPU_D18  Prescaler selection fADC1 = fMASTER/18.  

CDはADC変換のトリガ信号を選択する引数ですが、DがDISABLEになっているので、Cはドントケアでいいでしょう.
EADCは10bitですが、変換結果は16bitで返されます.なので、左詰にするか右詰にするかをこの引数で選択します.普通は_RIGHTの右詰でつかいます.
FG はAINxのシュミット特性をオンオフするために使います.わたしの感触では、シュミット特性がオンでもオフでもAD変換動作には影響ないようです.しか し問題は、シュミット回路にアナログ信号が入力されると消費電力が増えてしまうことだそうです.ですから、この機能は、アナログ入力ピンのシュミット特性 をオフし、デジタル入力ピンにはシュミット特性をオンしておくべきだという正しい運用をするための引数です.
FがADC1_SCHMITTTRIG_ALL GがDISABLEなので全てのAINxをシュミット特性オフにしています.
HAIN0-9を自動的に順繰りにスキャンするモードにします.
I
AIN0-9を自動的に順繰りにスキャンするモードで、スキャン結果を保存するためのレジスタをオンにするおまじないです.
J変換開始

    TIM2_DeInit();
    TIM2_TimeBaseInit( @TIM2_PRESCALER_128, A12499 ); // 16MHz/128/12500=10Hz
    TIM2_ITConfig(BTIM2_IT_UPDATE, ENABLE);
タイマ2を時刻表示のための0.1秒割り込みタイマとして動かします.
@A16MHz÷128÷12500=10Hzという計算です.
Bカウンタが12499に達したら割り込みをかけるという意味です.

    UART_Init((u32)115200, UART2_WORDLENGTH_9D, UART2_STOPBITS_1, UART2_PARITY_ODD);
UARTの設定です.115200bps,8bit,奇数パリティ,ストップビット1bit に設定しています.

    GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST); // LED indicator
LEDインジケータのためPD0を出力に設定

    GPIO_Init(GPIOD, GPIO_PIN_7, GPIO_MODE_IN_PU_IT);   // TLI to stop SD logging
    EXTI_DeInit();
    EXTI_SetTLISensitivity( EXTI_TLISENSITIVITY_FALL_ONLY );
PD7のTLI (top level interrupt)をオンにしています.
SDカードを抜去するまえにSDカードのFAT16を閉じるためにTLIで割り込みをかけるためです.

    LCD_Init(); // LCD initialization
LCDをつかうための初期化です.

    // ADC offset initialization
上のほうで、温度補正値をEEPROM上に文字列として確保しました.その文字列をfloatに変換して変数に格納します.
    offset_AIN[0]=atof(EEPROM_OFFSET_AIN0);  AIN0
    offset_AIN[1]=atof(EEPROM_OFFSET_AIN1); 
AIN1
    offset_AIN[2]=atof(EEPROM_OFFSET_AIN2);  AIN2
    offset_AIN[3]=atof(EEPROM_OFFSET_AIN3);  AIN3
    offset_AIN[4]=atof(EEPROM_OFFSET_AIN4);  AIN4
    offset_AIN[5]=atof(EEPROM_OFFSET_AIN5);  AIN5
    offset_AIN[6]=atof(EEPROM_OFFSET_AIN6);  AIN6
    offset_AIN[7]=atof(EEPROM_OFFSET_AIN7);  AIN7
    offset_AIN[8]=atof(EEPROM_OFFSET_AIN8);  AIN8
    offset_AIN[9]=atof(EEPROM_OFFSET_AIN9);  AIN9

    enableInterrupts();  割り込み許可

    UART_PutString("\r\nstart temperature logger\r\n");  オープニングメッセージをUARTへ出力

    // SD card detect pin pullup
    GPIO_Init(SD_DETECT_GPIO_PORT, SD_DETECT_PIN, GPIO_MODE_IN_PU_NO_IT);
SDカードが挿入されているかどうかをチェックするポートを入力にセット.

    // Wait for SD card insertion
    UART_PutString("waiting for SD card\r\n");   SDカードを待つメッセージをUARTへ
    LCD_PutString("waiting for SD            ",LCD_DISP_LOWERLINE);  LCDにも同様のメッセージ(1行目)
    LCD_PutString("waiting for SD            ",LCD_DISP_UPPERLINE);   LCD(2行目)
    while(SD_Detect()==SD_NOT_PRESENT){;}     SDカード検出するまでwait
    UART_PutString("SD card inserted\r\n");    SDカードが挿入されたメッセージ
   
    // SD initializations
    for(i=0;i<=30000;i++) GPIO_WriteReverse(GPIOD,GPIO_PIN_0);    単なる遅延
   SD_Init();  // Initialization SPI and SD card     SDカードインターフェース初期化
   SD_PutString_init(); // Initialization FAT16     FAT16ルーチン初期化
    SD_format_2GB();     SDを有無を言わせず2GBにformat
    UART_PutString("SD card formatted\r\n");     SDカードformat済みメッセージをUARTへ
    // clear top of data
    for(i=0;i<SD_BLOCK_SIZE;i++) SDstr[i]=0;    SDカードRWバッファをゼロクリア   (debugの利便性のためだけなので省いてもOK)
    for(block=504;block<=520;block++)    SDカードblock504-520をゼロクリア 
(debugの利便性のためだけなので省いてもOK)
    {
        SD_WriteBlock(SDstr, (uint32_t)(block*SD_BLOCK_SIZE));
    }
    UART_PutString("SD card cleared\r\n");   SDカードクリアメッセージ
   
    TIM2_Cmd(ENABLE); // logging start      0.1秒タイマスタート  =温度ロガー動作開始

    while(1) { Menu(); } // main loop
     メニューループ
}


// TLI to stop SD logging
int mode=0; // 0:logging mode  1:administration mode     modeは温度ロガーのモードと、EEPROMやSDの管理モードの2つあります
void TLI_interrupt(void) interrupt 0       TLIの割り込み処理ルーチンです.SDカードを抜去するために必要な処理です.
{
    GPIO_Init(GPIOD, GPIO_PIN_7, GPIO_MODE_IN_PU_NO_IT); // TLI inhibit
SDカードの抜去は一度限りですので、次回の割り込みを禁止します.
TLIの割り込みを禁止するには、このようにポート自体を非割り込みピンに設定するしかないようです.
すなわち、EXTI_DeInit()では割り込み禁止できません.

    TIM2_Cmd(DISABLE); // stop logging      温度ロガーを停止します
    SD_PutString("",'v'); // flash data       SDカードに未書き込みのデータを強制的にSDカードに書きます
    UART_PutString("temperature logging is terminated\r\n");     温度ロガー停止メッセージをUARTへ
    LCD_PutString("temp log stopped",LCD_DISP_LOWERLINE);    LCDにもメッセージ
    mode=1; // administration mode      EEPROMやSDの管理モードに移行します
}


u16 adc[10];                   ADC0-9 の値 10bit数値
u32 adc_sum[10];           ADC0-9 ノイズ除去のためADC値を加算します
float mV[10];                  ADC0-9 ADC値をmVに換算します
float temperature[10];    mVから温度に換算します
char VERBOSE='s';         シンプルな表示か、煩雑な表示かのフラグ
float INTERVAL=1;          温度ロガーのインターバル秒
u16 adc_sum_cnt;           ノイズ除去のため加算した回数
u32 sec01=0;                   現在時刻のカウンタ
int day, hour, min, sec;   日時分秒

void Tim2Update(void) interrupt 13 // 0.1Sec interrupt    タイマ2割り込みで0.1秒毎にここに飛んできます
{
    int i;
    char str [20];
    sec01++;     現在時刻カウンタを++します.0.1秒毎に++します.
    if((sec01 % (u32)(10*INTERVAL))==0) // start interval      温度ログのインターバルならば以下の処理をします
    {
        // calculations of voltage and temperature
        for(i=0;i<=9;i++)    AIN0からAIN9まで
        {
            mV[i] = (float)adc_sum[i]/(float)adc_sum_cnt/1024.0*3333;
ここは解説が必要でしょう.ADCのフルスケールは電源電圧すなわち0〜3.3Vです.
0〜3.3Vを1024等分しています.なので計算式は mV=AD値÷1024x3333 となります.
ただし、ノイズ除去のためにadc_sum_cnt回加算したのでその回数分割り算していますので、下記になっています.
  mV = adc_sum ÷ adc_sum_cnt ÷ 1024 x 3333

            temperature[i] = ( mV[i] - 850 ) / 10 + 25 + offset_AIN[i];
つぎにmVを温度に換算します.温度センサのスペックから、温度25度の時に850mVが出ます.
また、1度変化するごとに10mV変化します.なので、 温度 = ( mV - 850 ) ÷ 10 + 25 になります.
さらに、上の方でEEPROMからロードした温度補正値を加算してできあがりです.
        }

        // current time display
   現在時刻を表示します
        day  = (sec01/24/60/60/10) % 1000;    現在時刻を0.1秒刻みでカウントするsec01を日に換算します
        hour = (sec01/60/60/10) % 24;    同様に時に換算します
        min  = (sec01/60/10) % 60;   同様に分に換算します
        sec  = (sec01/10) % 60;   同様に秒に換算します

        // temperature display
   温度を表示します
        sprintf(UARTstr,"%03u %02u:%02u:%02u             ",day,hour,min,sec);
        LCD_PutString(UARTstr,LCD_DISP_UPPERLINE);   LCDの1行目に日時分秒を表示します
        sprintf(UARTstr,"%03u %02u:%02u:%02u",day,hour,min,sec);
        for(i=0;i<=9;i++)    AIN0からAIN9まで
        {
            sprintf(str," %d:%2.1f",i,temperature[i]);     温度を文字列に
            if((strlen(UARTstr)+strlen(str))>=119) break;     バッファオーバーフローをチェック
            strcat(UARTstr,str);     文字列を作成
        }

        strcat(UARTstr,"\r\n");
        UART_PutString(UARTstr);    UARTに温度を出力
        SD_PutString(UARTstr,'v');    SDに温度を出力
        sprintf(UARTstr,"%2.1f,%2.1f,%2.1f       ",temperature[2],temperature[6],temperature[9]);   LCDにはch2,ch6,ch9を出力
        LCD_PutString(UARTstr,LCD_DISP_LOWERLINE);   LCDの2行目に温度を出力

        if(VERBOSE=='v')   煩雑表示する場合(verbose mode)
        {
            strcpy(UARTstr,"ADC(0-9)=");
            for(i=0;i<=9;i++)
            {
                sprintf(str,"%d:%d ",i,(int)((float)adc_sum[i]/(float)adc_sum_cnt));  ADC値を表示
                strcat(UARTstr,str);
            }
            strcat(UARTstr,"\r\n");
            UART_PutString(UARTstr);
            strcpy(UARTstr,"mV(0-9)=");
            for(i=0;i<=9;i++)
            {
                sprintf(str,"%d:%d ",i,(int)mV[i]);   mVを表示
                strcat(UARTstr,str);
            }
            strcat(UARTstr,"\r\n");
            UART_PutString(UARTstr);
        }

        // prepair for next turn
        adc_sum_cnt=0;    次の
温度ログのインターバルのために加算回数をクリア
        for(i=0;i<=9;i++){ adc_sum[i]=0; }   同じ理由で加算変数をクリア
    } // end of interval     
温度ログのインターバル処理おしまい

    else  // not interval
     温度ログのインターバルじゃない場合の処理
    {
        adc_sum_cnt++;    加算回数++
        for(i=0;i<=9;i++)
        {
            adc[i]=ADC1_GetBufferValue(i);     AINxの値を取ってきます
            adc_sum[i]+=adc[i];     加算します
        }
        if(VERBOSE=='v')   
煩雑表示する場合(verbose mode)
        {
            strcpy(UARTstr,"ADC(0-9)=");
            for(i=0;i<=9;i++)
            {
                sprintf(str,"%d:%4d ",i,adc[i]);   
ADC値を表示
                strcat(UARTstr,str);
            }
            strcat(UARTstr,"\r\n");
            UART_PutString(UARTstr);    UARTへ出力
        }
    } // end of not interval
    TIM2_ClearFlag(TIM2_FLAG_UPDATE);    次回のタイマ2割り込みを待ち受けるためフラグクリア
}



void Menu(void)
{
    int i;
    int fieldnumber;
    uint32_t address;
   
    if(UART_STR_EXIST==0) return;   UARTが1行受信したか? さもなくばreturn

    fieldnumber = separate_line(command);   1行を単語毎に分解します.fieldnumberは単語の個数

    // temperature logger, verbose mode or not
    if(mode==0 && strcmp(Field[0],"v")==0 && fieldnumber==1)    mode=0なら温度ログモード
Field[0]は1つ目の単語の文字列です.それはコマンド文字列です.(以下同様)
コマンドvは、verbose modeをon/offするコマンドです
    {
        (VERBOSE=='v') ? (VERBOSE='s') : (VERBOSE='v');
    }

    // temperature logger, set interval second
    else if(mode==0 && strcmp(Field[0],"int")==0 && fieldnumber==2)
コマンドintは、インターバル秒を変更するコマンドです
    {
        if(atof(Field[1])<0.1)goto NG;
        else if(atof(Field[1])>60)goto NG;
        else INTERVAL = atof(Field[1]);   2個目の単語は秒です
    }

    // temperature logger, set date and time
    else if(mode==0 && strcmp(Field[0],"time")==0 && fieldnumber==4)
コマンドtimeは現在時刻を設定するコマンドです
    {

        u32 day, hour, min;
        day  = (u32)atof(Field[1]);    2個目の単語は日です
        hour = (u32)atof(Field[2]);    3個目の単語は時です
        min  = (u32)atof(Field[3]);    4個目の単語は分です
        sec01 = day*24*60*60*10 + hour*60*60*10 + min*60*10;    時分秒を0.1秒毎のタイマ変数1つでカウントします
    }

    // temperature logger, set offset values to EEPROM
    else if(mode==1 && strcmp(Field[0],"ofs")==0 && fieldnumber==3)   ここから下はEEPROMとSDを管理するモードmode=1です
コマンドofsは温度補正値を設定するコマンドです
    {
        int AINx;
        AINx = (int)atof(Field[1]);    2個目の単語はADCのチャンネルです
        if(AINx<0 || 9<AINx) goto NG; // check AINx    0-9でなければNG
        else
        {
            FLASH_Unlock(FLASH_MEMTYPE_DATA);    EEPROMを書くためのlock解除
            for(i=0;i<=15;i++)
            {
                FLASH_EraseByte(0x4000+AINx*16+i);    該当するADCチャンネルの補正値が格納されたアドレスをクリア
            }
            for(i=0;i<strlen(Field[2]);i++)
            {
                FLASH_ProgramByte(0x4000+AINx*16+i,(u8)Field[2][i]);   3個目の単語は補正値.文字列のままEEPROMに格納
            }
            FLASH_Lock(FLASH_MEMTYPE_DATA);    EEPROMをlockする
            offset_AIN[AINx]=atof(Field[2]);    すぐにつかう温度補正値変数を変更
        }
    }

    // temperature logger, dump EEPROM
    else if(mode==1 && strcmp(Field[0],"dump")==0 && fieldnumber==1)
コマンドdumpはEEPROMをダンプ表示します
    {
        UART_PutString("\r\n");
        for(i=0;i<=9;i++)    AIN0〜AIN9
        {
            int k;
            char dump_ascii[10];
            char dump_char[20];
            UARTstr[0]=0; // null string
            dump_char[16]=0;
            for(k=0;k<=15;k++)   各AINxの温度補正値は16文字
            {
                uint8_t a;
                a=FLASH_ReadByte(0x4000+16*i+k);    EEPROMから1文字読む
                sprintf(dump_ascii,"%02x ",a);    数字2文字で表示
                strcat(UARTstr,dump_ascii);   文字列を連結
                if(a<32)a=46;   制御文字なら”.”にする
                if(a==0x7F)a=46;
                if((a&0xF0)==0x80)a=46;
                if((a&0xF0)==0x90)a=46;
                if((a&0xF0)==0xE0)a=46;
                if((a&0xF0)==0xF0)a=46;
                dump_char[k]=a;  文字表示
            }
            UART_PutString(UARTstr);  UARTへ出力
            UART_PutString(" | ");
  UARTへ出力
            UART_PutString(dump_char);  UARTへ出力
            UART_PutString("\r\n");  UARTへ出力
        }
    }

    // temperature logger, clear EEPROM
    else if(mode==1 && strcmp(Field[0],"clr")==0 && fieldnumber==1)
コマンドclrはEEPROMをクリアします
    {
        UART_PutString("\r\n");
        FLASH_Unlock(FLASH_MEMTYPE_DATA);    EEPROM書き込みlockを外します
        for(i=0;i<=0x9f;i++) FLASH_EraseByte(0x4000+i);    EEPROMを消します
        FLASH_Lock(FLASH_MEMTYPE_DATA);    EEPROM書き込みlockします
        for(i=0;i<=9;i++)offset_AIN[i]=0;    いまつかう温度補正値をクリアします
    }

    // SD CARD, write incremental number to a SD block
    else if(mode==1 && strcmp(Field[0],"inc")==0 && fieldnumber==2)
コマンドincは、SDカードにincrementalデータを書きます
    {
        address=(uint32_t)(atof(Field[1])*SD_BLOCK_SIZE);   2個目の単語はblock
        for(i=0;i<SD_BLOCK_SIZE;i++) SDstr[i]=(uint8_t)i; // set Tx data   blockバッファをinclementalデータで埋める
        SD_WriteBlock(SDstr, address);    // Write block of 512 bytes   SDの所望のblockにバッファを書く
    }

    // SD CARD, fill a number to a SD block
    else if(mode==1 && strcmp(Field[0],"fill")==0 && fieldnumber==3)
コマンドfillはSDカードを指定のデータで埋めます
    {

        uint8_t c;
        c=(uint8_t)atof(Field[1]); 
  2個目の単語は埋めるデータ
        address=(uint32_t)(atof(Field[2])*SD_BLOCK_SIZE);      3個目の単語はblock
        for(i=0;i<SD_BLOCK_SIZE;i++) SDstr[i]=c; // set Tx data   blockバッファをデータで埋める
        SD_WriteBlock(SDstr, address);    // Write block of 512 bytes   
SDの所望のblockにバッファを書く
    }

    // SD CARD, fill a number to SD blocks
    else if(mode==1 && strcmp(Field[0],"fill")==0 && fieldnumber==4)
コマンドfillはSDカードを指定のデータで埋めます
    {
        uint8_t c;
        uint32_t block_stt, block_end, block;
        c=(uint8_t)atof(Field[1]);
    2個目の単語は埋めるデータ
        block_stt=(uint32_t)atof(Field[2]);     3個目の単語は開始block
        block_end=(uint32_t)atof(Field[3]);     4個目の単語は終了block
        for(i=0;i<SD_BLOCK_SIZE;i++) SDstr[i]=c; // set Tx data   blockバッファをデータで埋める
        UART_PutString("\r\n");
        for(block=block_stt;block<=block_end;block++)  開始block〜終了block
        {
            if((block % 6)==5)UART_PutString("\r\n");
            address=(uint32_t)(block*SD_BLOCK_SIZE);
            SD_WriteBlock(SDstr, address);    // Write block of 512 bytes
    SDの所望のblockにバッファを書く
            sprintf(UARTstr,"0x%04x%04x  ",(int)(block>>16),(int)(block&0xFFFF));   block表示
            UART_PutString(UARTstr);
        }
    }

    // SD CARD, write text to a SD block
    else if(mode==1 && strcmp(Field[0],"txt")==0 && fieldnumber==3)
コマンドtxtはSDカードに文字列を書くコマンドです
    {

        for(i=0;i<SD_BLOCK_SIZE;i++) SDstr[i]=0; // set Tx data
        strcpy(SDstr,Field[1]); // set Tx data   
2個目の単語は文字列
        address=(uint32_t)(atof(Field[2])*SD_BLOCK_SIZE);     3個目の単語はblock
        SD_WriteBlock(SDstr, address);    // Write block of 512 bytes     SDの所望のblockにバッファを書く
    }

    // SD CARD, format 2GB
    else if(mode==1 && strcmp(Field[0],"format")==0 && fieldnumber==1)
コマンドformatはSDカードをformatするコマンドです
    {
        UART_PutString("\r\n");
        SD_format_2GB();    formatコマンドをコールします
    }

    // SD CARD, dump a block
    else if(mode==1 && fieldnumber==1)
単なる数字ならSDカードのblockダンプコマンドです
    {
        address=(uint32_t)(atof(Field[0])*SD_BLOCK_SIZE);
   1個目の単語はblock
        if(address==0 && Field[0][0]!=0x30) goto NG; // adrs 0 but not "0"    数字の0でなければNG
        sprintf(UARTstr,"\r\nblock 0x%04x%04x\r\n",(int)(((uint32_t)atof(Field[0]))>>16),(int)(((uint32_t)atof(Field[0]))&0xFFFF));
        UART_PutString(UARTstr);    block番号表示
        SD_ReadBlock(SDstr, address); // Read a block     block読みコマンド.SDstrに読んだ512byteが返される
        SD_DumpBlock();    block表示コマンド
    }

    // SD CARD, dump blocks
    else if(mode==1 && fieldnumber==2) // dump blocks
単なる数字ならSDカードのblockダンプコマンドです
    {
        uint32_t block_stt, block_end;
        block_stt=(uint32_t)atof(Field[0]);
   1個目の単語は開始block
        block_end=(uint32_t)atof(Field[1]);   1個目の単語は終了block
        if(block_stt==block_end) goto NG;
        if(block_stt>block_end) goto NG;
        for(i=block_stt;i<=block_end;i++)  
開始block〜終了block
        {
            address=(uint32_t)(i*SD_BLOCK_SIZE);
            sprintf(UARTstr,"\r\nblock 0x%04x%04x\r\n",(int)((uint32_t)i>>16),(int)((uint32_t)i&0xFFFF));
            UART_PutString(UARTstr);
    block番号表示
            SD_ReadBlock(SDstr, address); // Read a block     block読みコマンドSDstrに読んだ512byteが返される
            SD_DumpBlock();    block表示コマンド
        }
    }
    else
    {
NG:
        UART_PutString("\r\n\nCOMMAND NG!\r\n");   コマンドNGならここへ飛んでくる
    }

MENU:
    UART_PutString("\r\n");
    if(mode==0)   温度ロガーモードのメニュー表示
    {
        UART_PutString("-----TEMPERATURE LOGGER MENU-----\r\n");
        UART_PutString("time 18 9 30  : set day&time 18th 9:30\r\n");
        UART_PutString("int 3         : interval time 3 seconds\r\n");
        UART_PutString("v             : switch verbose <--> silent\r\n");
    }
    if(mode==1)    EEPROM,SDカードの管理メニュー表示
    {
        UART_PutString("-----TEMPERATURE LOGGER EEPROM MENU-----\r\n");
        UART_PutString("ofs 4 -0.5    : set AIN4 offset to -0.5\r\n");
        UART_PutString("dump          : dump EEPROM\r\n");
        UART_PutString("clr           : clear EEPROM\r\n");
        UART_PutString("-----SD CARD MENU-----\r\n");
        UART_PutString("inc 2         : write incremental to block 2 (adrs=2*512)\r\n");
        UART_PutString("fill 49 129   : write 49 to block 129 (adrs=129*512)\r\n");
        UART_PutString("fill 49 12 129: write 49 to block 12-129\r\n");
        UART_PutString("txt hello 996 : write hello to block 996 (adrs=996*512)\r\n");
        UART_PutString("format        : format 2GB FAT16\r\n");
        UART_PutString("3             : dump block 3 (adrs=3*512)\r\n");
        UART_PutString("3 18          : dump block from 3 to 18\r\n");
    }
    UART_STR_EXIST=0;   UARTが1行読み込んだフラグをクリア
    return;
}


inserted by FC2 system