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を自動的に順繰りにスキャンするモードにします.
IAIN0-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;
}