SSブログ

割り込みハンドラが呼び出されない件を調査しました [PICkit3]

割り込み禁止の状態でSSPIFが立った後、割り込みを許可しても割り込みハンドラが呼び出されない件について調査してみました。結論から言うと”step実行中は割り込みサービス・ルーチンを呼び出さない”ということでした。

『なぁーんだ、そんなことか!』って簡単には納得出来ないのですが、兎に角そういうことのようです。

事の発端はSSP割り込みですが他の割り込みも呼び出されなくなったので、調査はタイマ割り込みとPORTB(SW操作)割り込みを使い、以下のプログラムで調査しました。
void interrupt intsrv(void)
{
  intcon_buff[buff_index++] = INTCON;
  intcon_buff[buff_index++] = TMR0;
  if( INTCONbits.T0IF == 1 )
  {
     INTCONbits.T0IF = 0;
     TMR0 = TMR0_INITIAL_COUNT;
  intcon_buff[buff_index++] = INTCON;
  intcon_buff[buff_index++] = TMR0;
  }

  if( INTCONbits.RBIF )
  {
      dummy_buff = PORTB;
      INTCONbits.RBIF = 0;          // clear (reset) flag
  intcon_buff[buff_index++] = INTCON;
  intcon_buff[buff_index++] = TMR0;
  }
  return;
}

void main()
{
  di();
  buff_index = 0;
  while(1)
  {
    if( INTCONbits.T0IF == 1 )
    {
      if( INTCONbits.RBIF == 1 )break;
      else
      {
        TMR0 = TMR0_INITIAL_COUNT;
        INTCONbits.T0IF = 0;
      }
    }
  }
  ei();   <== break pointを設定(step実行の場合)
  intcon_buff[buff_index++] = INTCON;
  intcon_buff[buff_index++] = TMR0;
  intcon_buff[buff_index++] = INTCON;
  intcon_buff[buff_index++] = TMR0;
  intcon_buff[buff_index++] = INTCON;
  intcon_buff[buff_index++] = TMR0;
  intcon_buff[buff_index++] = INTCON;
  intcon_buff[buff_index++] = TMR0;
  while( buff_index < 16 ); <==ここでrun(step実行の場合)
  di();
  while( 1 ); <==  Halt


<プログラムの動作>
(1)タイマ(T0IF)とSW操作(RBIF)の割り込み要求フラグが立つまでdi状態で待ち合わせる。
(2)ei状態にした直後からINTCONとTMR0の値を記録する。
(3)割り込みハンドラ内でもINTCONとTMR0の値を記録する。

========== その結果 ===========
intcon_buffに格納された値
<step実行の場合>
EF BA EF 62 EF 36 EF 9F 6F 4B 6B 06 6A 0A 6E 00 6A 06

<runの場合>
6F 01 6B 06 6A 0A EF 0B EA 0C EA 0C EA 0D 6E 00 6A 06

========== その解釈 ===========
(1)step実行で4回記録したINTCONの値が変わらない(=0xEF)のは、割り込みハンドラが呼び出されていないことを示している。
(2)2stepの実行でTMR0の値が大きく変化する(0xBA,0x62,0x36,0x9F)のは見かけの処理以外に多くのインストラクション・サイクルが(step実行で)費やされることを示している。
(3)runで6バイト目に記録されたINTCONの値(=0xEF)はeiした直後の値と考えられ、INTCONの書き込み前(eiした直後)に割り込みハンドラが呼び出された結果、6バイト目に書き込まれたものと思われる。
(4)whileループを実行中(run状態)に記録された値(0x6E,0x00,0x6A,0x06)はタイマ割り込みハンドラの処理内容と合致し、whileループの実行中にタイマ割り込みが発生したものと思われる。

以上の結果とその解釈から、先の結論を導きました。

うーん。

『MASTERの送受信処理も割り込みハンドラ内で実行できる』と言うことになりますが、step実行で動作を確認出来ないのが困りものです。

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

PICkit3がデバイスIDを誤認識する [PICkit3]

以前”外部電源にするとPIC18F2550を認識しない”不具合について、”入力回路がオープンのままになっていたOPアンプを取り除いて解決した”と記しました。そのときはPICkit3をReconnectするとデバイスIDを正しく読み取ってデバッグできるようになったのですが・・・

実はその後も”PIC18F2550を認識しない”不具合は続いています。現時点で判っている(再現性がある)ことは次の通りです。

(1)外部電源のDC5V(プラス側)に入れたSWをONにするとデバイスIDを誤認識する。
(2)その後、PICkit3をReconnectしても、誤認識したデバイスIDは変わらない。
(3)DC5V(プラス側)に入れたSWをONのままにして、外部電源のAC100VをONにすると正しくデバイスIDを認識する。
(4)その後、PICkit3をReconnectしても、デバイスIDは正しい値を保つ。
(5)300Ωの抵抗を介して外部電源のDC5Vをブレッド・ボードに接続すると、デバイスIDを正しく認識する。
(6)その後SWをONにして、PICkit3をReconnectしてもデバイスIDは正しい値を保つ。

”SWのチャタリングが何か悪さをしている”のであろうと想像していますが、何故PICkit3のReconnectでPIC18F2550のデバイスIDを正しく認識できない(し直さない)のか謎です。

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

EEPROMにlongあるいはfloatの補正テーブルを設ける [PICkit3]

これまでにもEEPROMを使ったデータの読み書きは行って来ましたが、全てバイト・データでした。温度コントローラの開発では、longあるいはfloatの補正テーブルをEEPROM上に設ける必要があります。

お試しでこんなコードを書いてみました。

#pragma romdata config=0xf00000
long rom offset_table[8] = {0,0,0,0,0,0,0,0};
float rom gain_table[8] = {1.0,2.0,3.0,4.0,5.0,6.0,7.0,1000.0};

以外とすんなり、longとfloatの初期化テーブルがEEPROM上にできました。

offset_table 0xf00000 program extern C:\Users\...\SRC\initialize.c
gain_table 0xf00020 program extern C:\Users\...\SRC\initialize.c

もしかして、そのままアクセスできる?

offset_table[0] = 1;
gain_table[7] = 1.0;

流石にこれは駄目でした。逆アセンブル・リストを見ると、Data Memoryの0x00と0x3cにアクセスしています。

909: offset_table[0] = 1;
10C4 0E00 MOVLW 0
10C6 6EF6 MOVWF 0xff6, ACCESS
10C8 0E00 MOVLW 0
10CA 6EF7 MOVWF 0xff7, ACCESS
|
10DA 6AF5 CLRF 0xff5, ACCESS
10DC 000D TBLWT*+
910: gain_table[7] = 1.0;
10DE 0E3C MOVLW 0x3c
10E0 6EF6 MOVWF 0xff6, ACCESS
10E2 0E00 MOVLW 0
10E4 6EF7 MOVWF 0xff7, ACCESS
|
10F4 0E3F MOVLW 0x3f
10F6 6EF5 MOVWF 0xff5, ACCESS
10F8 000D TBLWT*+

こんな共用体と関数を定義して、EEPROMの読み書きはバイト・データとして行い、プログラム上はlongあるいはfloatで扱えるようにしました。

union eeprom_long{
unsigned char c_array[4];
long l_val;
float f_val;
};

void eeprom_long_write(unsigned char eeprom_address, union eeprom_long *target);
void eeprom_long_read(unsigned char eeprom_address, union eeprom_long *target);

テスト・コードを書いて試してみると

val_100.f_val = 100.0;
eeprom_long_write( 0x20, &val_100);
eeprom_long_read( 0x20, &offset);
eeprom_long_read( 0x24, &val_100);

成功です。

eeprom_log_read.pngEEPROMからfloatのデータを読み書きした

こんなことが簡単に出来てしまうのもC言語の有り難さです。

nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

配線を直してもEEPROMの書き込みエラーは無くならない [PICkit3]

”PIC16F1827用ライター・ボードの配線を見直して、EEPROMの書き込みエラーは起きなくなりました。”と先日のブログに書きましたが、どうやら早計だったようです。一度は正しく書き込めたのですが、その後EEPROMの7番地と255番地でVerify Errorが発生するようになりました。

このままでは作業が進まないので、次のように対処することにしました。
(1)書き込み前の全消去を止める。
Programmer > Settings > Program Memory > Program OptionのErase all before Programのチェックを外す。
(2)EEPROMの書き込み要否を手動で設定できるようにする。
Programmer > Settings > Program Memory > Manually select...にチェックを入れる。
(3)書き込み前に手動で全消去する。
Programmer > Erase Flash Device
(4)最初はEEPROMも書き込み対象に設定する。
Programmer > Settings > Program Memory > MemoriesのProgramとConfigurationとEEPROM にチェックを入れる。
(5)書き込む。(Verifyエラーになる)
Programmer > Program

The following memory regions failed to verify correctly
EEData Memory
Address: 00000007 Expected Value: 0000000e Received Value: 000000ff

(この段階でEEPROMも7番地と255番地以外は正しく書き込まれている)

(6)EEPROMを書き込み対象から外す。
Programmer > Settings > Program Memory > MemoriesのEEPROM のチェックを外す。
(7)書き込む。(Verify completeになる)
Programmer > Program

Verifying...
Verify complete

デバッガも同じ処置で接続できるようになりました。

MPLABのVersionは8.76、PICkit3のFirmwareのVersionは01.26.71で、多分現時点の最新版だと思います。他の人は問題なく書き込めているのでしょうか?orz

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(2)  トラックバック(0) 
共通テーマ:日記・雑感

PIC16F1827用ライター・ボード [PICkit3]

PIC16F1827用ライター・ボード

間欠タイマーの改造案を思いつきました。試してみたいのですが、現在ブレッド・ボードはPIC18F2550用(温度コントローラの試作回路を組み込んである)になっていて、回路を組み直さなければPIC16F1827には書き込めません。

今後のことを考え、PIC16F1827用にライター・ボードを作ることにしました。
これです。

wrt1827.pngPIC16F1827用ライター・ボード

最初、PICkit3の1pin(Vpp)とPIC16F1827の4pin(/MCLR-Vpp)を10kΩの抵抗を介して接続していました。(これは間違いです)

そんな状態でもデバイスは正しく認識して、書き込みも何となく出来ます。しかしEEPROMの初期化データが所々正しく書き込めません。何がおかしいのか調べて、上記不具合を見つけました。10kΩの抵抗を上の写真のように緑色の線で接続したところ、EEPROMの書き込みエラーは起きなくなりました。

これで、心置きなく思い付きを試すことができます。デバイスごとにライター・ボードを作成するのが楽しみです。次はPIC18F14K50用かな?

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

PICkit3でPIC18F14K50が使えない(その3 事情判明) [PICkit3]

”PICkit3(デバッガ)でPIC18F14K50が使えない”件ですが、事情が判ってきました。
これです。

”This Processor Extension Pak is mandatory for debugging code since the production silicon does not have on-board debugging capability.”と書かれています。

PICデバイスの全てにオン・ボード・デバッグ機能が組み込まれている訳ではないらしく、オン・ボード・デバッグ機能が組み込まれていないデバイスとPICkit3のデバッガを接続するためには所定のヘッダ・ボードを使わなければならないようです。多分、ヘッダ・ボードを接続したときのDevice IDがPICkit3の期待値(=47a0)なのだろうと思われます。

ヘッダ・ボードの要否に関する情報はConfigure>Select Deviceの所に記されていました。

<PIC18F2550の場合>
pic2550.pngヘッダ・ボードは不要

<PIC16F1827の場合>
PIC16F1827.pngヘッダ・ボードを使っても良い

<PIC18F14K50の場合>
PIC18F14K50.pngヘッダ・ボードの使用は必須


試してみると、PICkit3のプログラマはPIC18F14K50に接続できました。
パチパチパチ~


さて、開発作業はどのように進めれば良いのでしょう?
親族SNS管理人としては、手間を掛けてヘッダ・ボードを入手するのは気が進まないので、”PIC18F2550で開発を進めて、試作実験機はPIC18F14K50で製作する”という一番コストの掛からない方法を採用するつもりです。

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

PICkit3でPIC18F14K50が使えない(その2) [PICkit3]

Microchipフォーラムで似た不具合状態の報告を見つけました。これです。

”ターゲットのDevice ID(=4760)がICE version のデバイスID(=47a0)と一致しないため14K50のデバッグが出来なかったが、MPLAB IDE v8.33(@2009.07.16)にupdateしたら直った”と言うことです。

状況はとても似ているのですが、親族SNS管理人が利用しているMPLAB IDEは最新版(v8.73a)なのでupdateは試せません。念のためMPLAB IDEを再インストールしてみましたが、状況は変わりませんでした。orz

再び白旗を掲げてデバイスをPIC18F14K50(8kステップ)からPIC18F2550(16kステップ)に変更することにしました。パッケージが20pinから28pinになるのは大変ツライ変更で、部品実装に苦労しそうです。

ソフトを開発している間に問題解決してくれると良いのですが・・・

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

PICkit3でPIC18F14K50が使えない [PICkit3]

温度コントローラの開発をPIC16F1827で始めたのですが、A/D変換機能を組み込む前にプログラム・メモリが足りなくなってしまいました。

プログラムを見直してプログラム・メモリを捻出するのは間欠タイマーで懲りていてやる気になれません。早々と白旗を掲げてデバイスをPIC16F1827(4Kステップ)からPIC18F14K50(8kステップ)に変更することにしました。PIC18F2550でUSBインターフェースを試作したことがあるので、PIC18F14K50への移行には何の問題もないと思っていました。しかし、そうは問屋が卸しませんでした。

PICkit3とデバイスをブレッド・ボード上で接続して、電源を供給して・・・あれ?

以下のメッセージが表示されました。
”Target Device ID (00004760) does not match expected Device ID (000047a0)”

色々調べた限りでは、PICkit3が読み取ったTarget Device ID(=4760)はPIC18F14K50のIDとして正しい値のように思われます。問題は”PICkit3の期待するDevice IDが何故47a0なのか?”ということです。

ネット検索を掛けてもPICkit3とPIC18F14K50との接続に関する問題は殆ど報告されていません。他の方々は何の問題も無く接続出来ている、ということなのでしょうか? orz

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

間欠タイマーのブザー応答はなかなか良い感じ! [PICkit3]

間欠タイマーのSW操作に合わせてブザー応答を組み込んでみました。

『SWを押す時間の長短とその組み合わせで間欠タイマーを操作する』というのはちょっと難しいんじゃ無いかと心配していました。しかし、ブザーで短押し、長押し、倍長押しの区別が付くようになって、状況は一変しました。

”正しい操作シーケンスを辿ったときLEDやブザーで応答する”という構想でしたが、試してみると”結果が出るまで正しく押せたかどうか判らない”のは操作する側にとって大きなストレスになることが判ってきました。

そこでSW操作に応じて、以下のピッチでブザーを鳴らしてみました。
短押し ==> E5(ミ)
長押し ==> G5(ソ)
倍長押し ==> A5(ラ)
SWを押すと直ぐミの音が鳴り、押し続けるとソの音に変わり、さらに押し続けるとラの音が鳴る仕掛けです。

長押し2回 だと” ミソ~、ミソ~”
長押し1回短押し3回は” ミソ~、ミ、ミ、ミ”
倍長押し3回 なら” ミソ~ラ~、ミソ~ラ~、ミソ~ラ~”

SW操作がメロディーになって聞こえます。

これは楽しい発見です。
これなら行ける!(?)

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

間欠タイマーのロジックが漸くまとまり(始め)ました [PICkit3]

タイマー割り込み処理では操作SWのON/OFFとその継続時間のカウントのみ行い、メイン・ルーチンでは0.1秒ごとにSW操作シーケンス(長押しが二回続いたとか、長押し一回のあと短押しが三回あったとか)を判定する方法にして、間欠タイマーのロジックが漸くまとまり始めました。

誤操作(定義されていないSW操作シーケンス)への対応とキャンセル操作(ユーザが途中で操作を打ち切る手段)の組み込みがまとまれば、SW操作はほぼ完成です。

あとは、ブザー応答だ。

にほんブログ村 IT技術ブログへ
に

ほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:日記・雑感

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。