[Homepage][BBS][Blog][YouTube][asablo]

エアーバリアブルBBS
新エアーバリアブルBBS
初めにお読み下さい Please read first ホームページ ブログ YouTube 過去ログ倉庫
PIC16F886のEEPROMについてお聞きします
約半年前にIntervalTimerのbin_to_dec変換方法についてお聞きして,
airvariableさんからのアドバイスを採用しましてうまく動作しています.
ありがとうございましたm(_""_)m

恥を忍んで,再びC言語の達人諸兄にお聞きします.

以下に示すのはIntervalTimerのソフトの一部ですが,なぜかEEPROMのアクセス(書込み及び読出し)がうまくいかないのです.
PICkit2でEEPROMを読み出したりすると0x00番地の値が0xddだったりして,前回終了時のmodeにならないのです.
前回終了時のmodeは1または2または3です(SW5およびSW6で選択).

EEPROMの処理ルーチン以外は正常に動作します.

尚,write_eeprom(address, value)および value = read_eeprom(address)はCCS-Cの組込み関数です.

<動作>
電源を投入した時に,SW5及びSW6がOFFの場合に前回終了時の動作モードで動作したいのです.

※動作が完成した暁には御礼のため回路図およびファームウェアなどを公開したいと思います.

void main()
{
int mode = 2; // modeのdefault値


//------------------------------------------------------------------------------------------
// 電源の投入直後のSW5(RB4),SW6(RB3)をチェック
//------------------------------------------------------------------------------------------
buzzer( 2, 1000, 100); // 電子ブザーを鳴動(鳴動回数,鳴動時間,非鳴動時間)

switch( input_b() & 0b00011000 ) { // RortBのbit4(RB4, SW5), bit3(RB3, SW6)の抽出
case 0b00010000: { // SW5(RB4)=OFF,SW6(RB3)=ONの場合
mode = 1; // modeを1に設定
output_bit( PIN_B7, 0 ); // B7 B6
output_bit( PIN_B6, 1 ); // × ●
break; // OF ON
} // 橙 黄

case 0b00001000: { // SW5(RB4)=ON,SW6(RB3)=OFFNの場合
mode = 2; // modeを2に設定
output_bit( PIN_B7, 1 ); // B7 B6
output_bit( PIN_B6, 0 ); // ● ×
break; // ON OF
} // 橙 黄

case 0b00000000: { // SW5(RB4)=ON,SW6(RB3)=ONの場合
mode = 3; // modeを3に設定
output_bit( PIN_B7, 1 ); // B7 B6
output_bit( PIN_B6, 1 ); // ● ●
break; // ON ON
} // 橙 黄
} // switch文終了

//--------------------------------------------------------------------------------------
// EEPROMの処理
//--------------------------------------------------------------------------------------
mode_num = read_eeprom( 0x00 ); // モード番号の読出し
delay_ms( 8 ); // EEPROM読出し遅延(8msec)

if( mode_num != mode ) { // EEPROMに格納されているmode番号が現モード番号と
write_eeprom( 0x00, mode ); // 異なる場合は現在のモード番号に更新する
delay_ms( 8 ); // EEPROM書込み遅延(8msec)
} // EEPROM処理の終了


while( mode == 1 ) {
// mode1の時の処理,※省略
}

while( mode == 2 ) {
// mode2の時の処理,※省略
}

while( mode == 3 ) {
// mode3の時の処理,省略
}

}
  • hayabusa
  • 2018/03/20 (Tue) 14:24:44
Re: PIC16F886のEEPROMについてお聞きします
hayabusaさん、こんにちは。
ソースを拝見するところでは、EEPROMの読み書き部分が1ヶ所ずつあるだけで、特に問題無いように見えます。

CCS-Cの挙動がどういうのかまでは分からないですが、先頭で型を宣言している部分
int mode = 2; // modeのdefault値
があり、こちらは16ビット長になっているかもしれません。
int8、unsigned int8、charなどと置き換えてみてはいかがでしょう。

また、これも昔では良く起きた漢字のコメントを使った場合の挙動の問題もありますので参考までに掲示します。
注釈行に\(バックスラッシュ)を使うときは注意(2009/10/17)
http://www.ne.jp/asahi/air/variable/picmel/other_info/index.htm#note10



  • air_variable
  • URL
  • 2018/03/21 (Wed) 17:21:17
Re: PIC16F886のEEPROMについてお聞きします
air_variable 様
アドバイスありがとうございました.
レスが遅くなり大変失礼しました.

自己解決しました.
簡単に言いますと,switch文の外にEEPROMの処理ルーチンを記述したのが原因でした.
また,変数定義の int mode = 2;はやめて単にint mode;

ちょっと長くなりますが,関係部分のソースの一部を以下に示します.
尚,もしご興味(要望)があれば回路図を含む全部を公開可能です.

//------------------------------------------------------------------------------------------
// 電源の投入直後のSW5(RB4),SW6(RB3)をチェック
//------------------------------------------------------------------------------------------
switch( input_b() & 0b00011000 ) { // RortBのbit4(RB4, SW5), bit3(RB3, SW6)の抽出
case 0b00010000: { // SW5(RB4)=OFF,SW6(RB3)=ONの場合
mode = 1; // modeを1に設定
break; //
} //

case 0b00001000: { // SW5(RB4)=ON,SW6(RB3)=OFFNの場合
mode = 2; // modeを2に設定
break; //
} //

case 0b00000000: { // SW5(RB4)=ON,SW6(RB3)=ONの場合
mode = 3; // modeを3に設定
break; //
} //

default: { // EEPROMの処理
mode_num = read_eeprom( address ); // mode番号の読出し
delay_ms( 8 ); // EEPROM読出し遅延(8msec)

if( ( 1 <= mode_num ) // mode_numが1以上,
&& ( mode_num <= 3 ) ) { // 且つ3以下の時
mode = mode_num; // modeをmode_numに設定
} //

else if( ( mode_num <= 0 ) || ( 4 <= mode_num ) ) { //
mode = 2; // mode_numが0以下,または4以上の時
} //
} // EEPROM処理の終了
} // switch文終了

if( mode != mode_num ) { // 現modeと保存されているナンバーが異なる場合は
write_eeprom( address, mode ); // 現modeをEEPROMに保存する
delay_ms( 8 ); // EEPROM書込み遅延(8msec)
}

//%%%%%%%%%%%%%%%%%%End of Documents%%%%%%%%%%%%%%%%%%
  • hayabusa
  • 2018/04/13 (Fri) 16:34:58

返信フォーム






プレビュー (投稿前に内容を確認)