2013年8月15日木曜日

PIC C18 メモ(PIC18F に FAT)

-----------------------------
PIC18F に FAT を組み込むこと調べてみた
-----------------------------
PIC C18 メモ(USBメモリとして使う)の続き。(参考にしたものは特にありません)

【まずサンプルのままコンパイルしてみる】
  • \Microchip Solutions\MDD File System-SD Card を自分のプロジェクトにコピー
  • PIC18Fを選択なので
    MDDFS-SD-PIC18.mcp
    MDDFS-SD-PIC18.mcw
  • PIC18Fのフォルダの中身をルートに展開
  • 品種設定を[ 18f87j50 ] にあわせた
  • コンパイル時のエラー対処のためルート設定を自分の環境に合わせて修正(二箇所、ディレクトリ名を入力)
  • BUILD SUCCEEDED ROM:35165,RAM:2354,SUM:0xc0b2
    というとてつもない結果になった
  • FSconfig.h で条件設定してあるので、絞ってみた
    //#define SUPPORT_FAT32
    少しROM使用量が減った
2010.01.22
【PIC18F26J50へ】

  • [ 18f87j50.lkr ] を、新たに作成した[ 18f26j50_ksSD.lkr ] に内容はそのままコピー
  • [ HardwareProfile.h ] を新規作成
  • (新しい名前にすると他のファイル内のinclude xx の修正が発生するので、元のファイルは名前を変えた)
  • 18f87j50 は 80ピン製品
  • PIC18F 28ピンの場合のサンプルを探して( \PIC18F Starter Kit 1 のフォルダにあった)違う部分を見比べて割り付けが違うところを貼り付けた
  • メインのxx.c プログラムの修正個所
    #prgma config が3ヶ所修正。・・コンパイルエラーに対応しただけ
  • BUILD SUCCEEDED ROM:34221,RAM:2354,SUM:0x9fae
  • 18F26j50 は、ROM 64kB
  • 品種を変え、修正したのは、リンカスクリプトとハード設定、メイン(config)の3つのファイルだけで適切なサンプルアプリを選んで見比べ、コンパイルしたエラーを解決すれば意外とすんなりいくのかも

どちらもコンパイルまでで、実施していない。
2010.01.27


ここは、再検証していない。大きなROM容量が要求されるので、PIC24Fに上げたらとか、PICを2個使うとか、組み込み済品を採用するとか、選択肢が増え「比較一覧表」が残っていた。
2013.08.16

PIC C18 メモ(USBメモリとして使う)




「PIC18F2550を使ってSDメモリ・リーダー/ライター」(秋月電子USBマイコンボードでUSBマスストレージデバイス)のWEBページに従って進めた。

【まず、USBメモリとして仕上げてみる】
  • USBフレームワークの USB Device - Mass Storage - Internal Flash Demo
  • Device の変更、リンカースクリプトの変更など
  • PIC該当ピンにコネクタをつなぐだけ(右上回路図)で使える
  • PCを使って、ファイルの追加、ファイル名の変更が可能
2010.01.19
【 次に、PICをSDカードのリーダ/ライタとして】
  • SDカードのコネクタを接続する
  • SDカードに 3.3V が必要
  • 「手順」と違ってエラーが出たが、ネットに回答があった
  • Card Detect, Write Protect の処理が必要
  • 手配線が不安定要素か、時々OK
  • 読み込み、書き込み、ファイルの新規作成どれも可
  • プロパティで残容量もちゃんと出てくる
2010.01.21
出来上がったこのモジュールは、FATが組み込まれているわけではない。単なるUSB-SDカードのインターフェイスを提供しているだけで、USBで接続されたPCが管理している。
2010.01.28

2013年8月12日月曜日

Finepix F770EXR 内部にゴミ?

散歩中に見かける近所のサルスベリより、我が家のそれは開花が遅く、8月になってから咲き始める。ただ花の色が濃い。
ところが、プログ用に何枚か撮った花の写真の全てに黒い影(シロマル印内)が写っている。8日に仕事で撮った写真は正常。その日、テーブルから滑らせてPタイルの床に落としてしまった。それが原因だろうか。

ズームを動かしても変わらず。 レンズを下向きにしてとんとんと横に軽く叩いたら消えた。センサの上にゴミがついていたことになる。
欠けた部品の可能性もあり。買ってからまだ半年。過酷な使い方はしていないのに、残念な気分。

2013年8月6日火曜日

RealSync で初のエラー

長いこと(10年以上)、バックアップ用のソフトは RealSync を使ってきたが、エラーがでてびっくり。
  • 「”は整数ではありません」とでる
  • それを閉じると、「I/Oエラー(32)」
  • 初期状態のような画面
ネットで調べたら、我がPCも同じように RealSync.dat が 0KB で空っぽになっていた。
  • RealSync.dat を一旦削除
  • RealSync を再起動して、
  • バックアップフォルダの設定をやり直した
  • RealSync.dat のコピーをとっておくことにした
0KB になってた dat ファイルの日付は、PCがトラブって強制的に電源オフした日のような気がする。

2013年8月5日月曜日

PIC C18 メモ(SPI関数)

----------------------------
関係するフラグ
----------------------------
【 BF (Buffer Full Status) 】
  • SSPBUF からデータを読むとL
    ①と③
  • SSPBUF に受信データが届いたら H
  • あるいは、BF=L はまだデータの交換が済んでいない(受信未完了でもある)
【 WCOL (Write Collision) 】
  • スレーブ側の書き込み衝突有りで H
    SSPBUFが空でないのに(BF=Hなのに)次のデータを書き込んだ
  • マスター側では書き込む前に SSPBUF を空読みするか、WCOLをクリアする
【SSPOV】
  • スレーブのオーバーフロー検出で H
    SSPBUF が空でないのに(BF=Hなのに)次のデータが送られてきた
  • マスター側は関係なし
----------------------------
ReadSPI 関数のなかみ【旧】
----------------------------
unsigned char ReadSPI( void )
{
  SSPBUF = 0x00;         //0x00をSSPBUFへ書き込む④
  while( !SSPSTAbits.BF);//BF=H を待つ②
  return( SSPBUF );      //SSPBUFには交換されたデータがある③
}
  • RD=ReadSPI(); で BF=L となり、受信完了③
  • SSPBUF にあったデータが互いに交換された状態②
----------------------------
WriteSPI 関数のなかみ【旧】
----------------------------
unsigned char WriteSPI( unsigned char data_out )
{
  SSPBUF = data_out      //SSPBUFにデータを書き込む④
  if( SSPCON1 & 0x80 )
    return( -1 )         //WCOL=H は送信データの衝突
  else{
    while( !SSPSTAbits.BF);//BF=H を待つ②
  }
  return( 0 );           //正常終了
}
  • WCOLを関数内で見ているので、予めSSPBUFを空読みする①か、WCOLをクリアしておかないと正常終了しない(-1を返してくる)
  • WriteSPI では BF=H の状態で送信完了②
  • WriteSPIを使わずに勝手に書き込む分には問題なく動く(WCOL無視)
----------------------------
マスターとスレーブの通信
----------------------------
  • マスター側は WriteSPI,ReadSPI
  • 書き込み前に BF=L にしておく必要がある(空読み)
  • スレーブ側は予めダミーデータを書いておく
  • 交換終了を知るには、まずBFフラグをLにしておく必要がある
  • BF=H になったらデータの交換終了、スレーブ側は次のアクションへ
2006.11.20
2013.08.09



ReadSPI 関数のなかみ【旧】、WriteSPI 関数のなかみ【旧】、となっているのは、今回再度開いてみたところ変更されていたため。【新】については分析していない。
2013.08.08

PIC C18 メモ(SPI通信)

-----------------------------
スレーブ側からデータを返す場合
-----------------------------
【A案】
マスター側
スレーブ側
WriteSPI(SD);→DataWriteSPI(Dummy);
RD=SSPBUF;
←Dummy
RD=ReadSPI();→0x00WriteSPI(Data);
←Data


Dummy=SSPBUF;(*)
【B案】
マスター側スレーブ側
WriteSPI(SD);→DataSSPBUF=Dummy;
while( !SSPSTAbits.BF);
←Dummy
RD=ReadSPI();→0x00SSPBUF=Data;
while( !SSPSTAbits.BF);
←Data


//Dummy=SSPBUF;(*)


  • マスター側の Write, Read に対してスレーブ側 Read, Write とこだわるとややこしくなる
  • スレーブ側は、BFフラグだけで動くようにした【B案を採用
  • B案は毎度WCOLを見ないので応答が早い
  • (*)印の空読みが無いと、WCOL=H のまま終わる(B案はWCOLを無視し続ける)
---------------------------
マスタースレーブ間の通信(割り込みは使わない)
---------------------------
  • マスタースレーブ間が1対1で、交換するデータが1バイトで済むなら、両者が勝手に読み書きしても構わない
  • ダミーデータは、「受信可」、「受信不可」を示すコードとしておけば、マスター側は次のアクションへ進める
  • マスター側は ReadSPI, WriteSPI を使って操作すればOK
  • スレーブ側が連続的にデータを返したい場合は WriteSPI を使わないで
    while( !SSPSTAbits.BF) だけで操作すればいい
  • 「送信」でも、 空読み(BF=L にする)必須
【実施版】2007.02.17
マスター側スレーブ側
Status=ReadSPI();→0x00SSPBUF=Ready;
while( !SSPSTAbits.BF);
←Ready
WriteSPI(Command);→DataDummy=SSPBUF;
while( !SSPSTAbits.BF);
←Dummy
RD=ReadSPI();→0x00SSPBUF=ReturnData;
while( !SSPSTAbits.BF);
←Data
Dummy=SSPBUF


【通信手順】
  1. スレーブ側は、自身の初期設定、あるいはコマンド処理が終わったら、
    コマンド待ち状態とし、SSPBUFに Ready を書き込む
  2. マスター側は ReadSPI でスレーブの Ready を確認したら、
    WriteSPI でコマンドを書き込む
  3. スレーブ側は、受信したコマンドで分岐する
  4. マスター側は読み書きの都度、スレーブ側の処理時間を待ちながらデータを交換する
【問題点】
  • タイマが入ってくるのでクロック変更された時反映されるようにしておくこと
  • コマンドで分岐した後のデータ交換回数は、両者で取り決めて同時に変更する必要がある
  • データ長が長い場合は、データ個数やりとりしたほうがいい
  • 通信が途絶しているとき(コネクタを抜かれた)に動いていいかどうか
  • 無視して動いた方が都合がいい場合と、そうでない場合とある
  • Ready に使用する文字記号を何にするべきか
2006.11.20
2013.08.09



【実施版】は不具合がでて、「SPI通信の改良」へと続く
2013.08.09

PIC C18 メモ(SPI通信の改良)

-----------------------------
コマンドとデータ交換手順の変更
-----------------------------
マスター側のクロックを上げたら、スレーブ側が反応しない場合が発生、通信が不安定に。マスター側の通信間隔を空けると解決できる。スレーブ側とマスター側の応答処理時間がたまたまうまくいっていたようだ。
"Ready"を予め書き込んでいたが、「Ready だった」のであって、「Readyになった」分けではないので、そこを改めた。

【変更後・スレーブ側の正常応答】
マスター側スレーブ側
WriteSPI(0x00); →0x00 SSPBUF=Busy;
while(!SSPSTAbits.BF);
←Busy
SSPBUF=Command;
while(!SSPSTAbits.BF);
→Command SSPBUF=Ready;
while( !SSPSTAbits.BF);
←Ready
RD=SSPBUF;//(*1)
WriteSPI(Data); →Command SSPBUF=0x00;
while(!SSPSTAbits.BF);
←0x00

【変更後・スレーブ側がビジー】
マスター側スレーブ側
WriteSPI(0x00); →0x00 SSPBUF=Busy;
while(!SSPSTAbits.BF);
←Busy
SSPBUF=Command;
while(!SSPSTAbits.BF);
→Command
←0x00
RD=SSPBUF;//(*2)
  • 変更前は、スレーブが"Ready"にないのにマスター側が勝手に書き込む場合がでる
  • (*1)RD=Ready に変わっていたら通信モードへ
  • (*2)RD=0x00のままなら、スルーする
  • マスター側は、数ms周期でポーリングする
  • スレーブ側はコマンド処理が終わったら、SSPBUFに"Busy"を書き込み、コマンド待ちのアイドルループへ
  • 通信途絶(ケーブル未接続)でもマスター側は立ち往生しない
  • スレーブ側のコマンド処理に入ってからはこれまでと同じ
  • Write/Read の間の待ち時間(20~80us)もこれまでと同じ
    2007.12.19
    2013.08.07



    SPIの相互通信は自己流。後に、uALFATやI2Cデバイスとの接続など経験して、これらにならった方がいいと思える点(改良案のページへ)が多い。
    2011.09.05

    PIC C18 メモ(SPI通信の改良案)

    -----------------------------
    I2C デバイスと比較
    -----------------------------
    【I2C送信側】
    --------------------------------
    1. START条件出力
    2. 出力完了待ち
    3. スレーブアドレス送出
    4. サブアドレス送出
    5. データ送出
    6. ストップ条件
    7. 出力完了待ち



    --------------------------------
    レジスタ(サブアドレス)を直接
    指定して書き込む
    この時待つ必要がない
    送り側は複数のレジスタが
    並んでいるように見える
    --------------------------------
    【SPIマスター側】
    --------------------------------
    1. SS↓
    2. ダミー書き込み
    3. SS↑
    4. スレーブ側の応答待ち
    5. SS↓
    6. コマンド&待ち
    7. データ交換
    8. 完了待ち
    9. 送信データ
    10. SS↑
    --------------------------------
    コマンドの値で分岐(switch)する
    コマンドの処理時間がバラバラ
    両者で同時修正が必須


    --------------------------------
    或るI2Cデバイスの仕様と、自己流のSPI通信手順との対比を上に示す。このI2Cデバイスにはデータストリームモードとして連続してデータを書き込む機能もある。
    -----------------------------
    SPI通信の改良案(未実施)
    -----------------------------
    • コマンドとデータ数とデータ
      のようにコマンドとデータのやり取り部分はコマンドの内容に依存しないようにしておく
    • マスター側の待ち時間を都度調整する必要がないように、通信とコマンド処理を切り離す(データをレジスタへ保存したら通信終了)
    • データを返す場合も、スレーブ側は自分のタイミングでレジスタへ書き込むだけにする(マスター側のタイミングで返信は実行される)

    2011.09.05



    この他参考になるのは、SPIインターフェイスを持つIOエキスパンダ。
    2013.08.13

    PIC C18 メモ(SPI修正履歴)

    -----------------------------
    スレーブ側のプログラムバージョン(参考)
    -----------------------------
    SPI通信手順は、D/A, A/D系を扱うPICの載った基板、フロントパネルのスイッチやLED表示などを扱うPICの載った基板をメイン基板(マスター側)からコントロールするため、自己流で考案した。
    本ブログ(PIC C18 メモ)記載の「スレーブ側」は、このスイッチ監視基板を指す。SPIスレーブ側プログラムの修正履歴をまとめた。
    • 【901v02】 2006.11.27 迄SPI割り込みで処理(バラックセット)
    • 【901v03】 2006.11.27 割り込みを使わない方法へ
    • 【901v05】 2006.12.09 (正規基板)
    • 【901v06】 2006.01.14 SPI通信手順を改良
    • 【901v08】 2007.02.17 SPI CKE=0,CKP=0 をCKP=1へ変更
    • 【A01v01】 2007.12.19 SPI通信手順を変更(基板改版)
    • 【A01v02】 2009.10.05 configulation変更とPICの品種が安価なタイプへ
    • 【A01v03】 2010.11.19 コマンド追加
    【901v02以前】
    SPI受信割り込みを使ったバージョンの不具合理由
    • 割り込み受信の場合は、割り込み許可前に WCOL=L にしておく
    • 複数の割り込み要因がある場合は、割り込みの優先設定、割り込み処理中の割り込み禁止など必要
    【901v03】
    • 割り込みは使わない
    • SPIマスタ側は2つ目の送信をこの待つ必要がある
    • アイドルループを左下の方法から、右へ変更。通信しないと返すべきデータが更新されないので、ループ一回分遅れ、現在の状況が分からない
      →
    ↑ ↓
    ↑ if(タイマ1の処理)
    ↑ while(SPI受信)
    ↑ if(
    タイマ2の処理)
    ↑ ↓
     ←
      →
    ↑ ↓
    ↑ if(
    SPI受信)
    ↑ if(タイマ1の処理)
    ↑ if(タイマ2の処理)
    ↑ ↓
     ←
    ・タイマ1処理は、バックライトタイマ、タイマ2は、スイッチ読み込みとフィルタリング
    ・SPI受信は、コマンド受信と応答

    【901v06】
    • LEDオンオフが任意のタイミングで出来るよう、どのコマンドも都度 Ready へ戻る
    【901v08】2007.02.17
    • SPI設定 CKE=0,CKP=0 をCKP=1へ変更
      (マスター側にuALFATを接続するため)
    【A01v01】

    【901v08】までは試作機段階のもので、製品版の装置に用いられたのは、【A01v01】以降のバージョンである。
    2013.08.07

    2013年8月3日土曜日

    PIC C18 メモ(SPIの絶縁)

    -----------------------------
    SPI フォトカプラの検討
    -----------------------------
    アナログ回路との絶縁を目的として、フォトカプラを使う場合の、クロック設定と部品を選定した。I2Cと違ってSPIの方は入出力が分かれているので絶縁しやすい。
    【フォトカプラ】
    • フォトカプラ 6N137 ・・・相当品多数
    • 10Mbタイプを使用すること
    • RL: 350Ω, IF: 7.5mA, tpLH, tpHL: 60~80ns
    【SPI】
    • 転送クロックは1.25MHz (20MHz/16)
    • CKE=0, CKP=0 で使う
    2006.11.07

    本件は未実施。当初、CKE=0,CKP=0 で使い始めたのはこの時の検討結果が根拠になっている。今の使い方は、CKE=0,CKP=1。
    2013.08.03

    2013年8月2日金曜日

    PIC C18 メモ(A/D測定値の扱い)

    -----------------------------
    atoi の注意
    -----------------------------

    • atoi 関数は16bit を前提にASCII変換する
    • 15bit 以下の分解能で使う場合は、負側の値を変換する必要がある
    • 14bit バイポーラ の場合、0x2000を超えたら0xE000へシフトする
    • 右図参照

    -----------------------------
    A/D値を丸めるときの注意
    -----------------------------
    • バイポーラ値の場合、単純にビットローテートすると、オフセット誤差が片寄ってしまう
    • 特にゼロ付近が目立ってしまうので困る
    • 右図参照
    -----------------------------
    2の補数を取るときの注意
    -----------------------------
    12bit バイポーラの場合
    【正】
    0xFFFF で EX-OR の後、ビット長を戻す
    meas ^= 0xFFFF;
    meas++;
    meas &= 0x0FFF;

    0x0001 -> 0xFFFE -> 0xFFFF -> 0x0FFF  //-1
    0x0000 -> 0xFFFF -> 0x0000 -> 0x0000  //0
    0x0FFF -> 0xF000 -> 0xF001 -> 0x0001  //+1

    【誤】
    meas ^= 0x0FFF;
    meas++;

    0x0001 -> 0x0FFE -> 0x0FFF  //-1
    0x0000 -> 0x0FFF -> 0x1000  //NG
    0x0FFF -> 0x0000 -> 0x0001  //+1

    PIC C18 メモ(USART LF62 応答)

    -----------------------------
    LF62 の応答内容
    -----------------------------
    右の上波形
    [正常接続]
    プロンプトが返るまで約7秒かかる(128MB)
    [受信]
    Ver 03.58VDAPF On-Line:
    Device Detected P2
    No Upgrade
    D:\>
    -----------------------------
    [送信/キーイン]
    DIR\r
    [受信]
    CFILEK~1 DIR
    LLLF62 DIR
    PRIVATE DIR
    LF62TEST.TXT
    D:\>
    -----------------------------
    [送信/キーイン]
    CD LLLF62\r
    [受信]
    D:\>
    -----------------------------
    [送信/キーイン]
    DIR\r
    [受信]
    . DIR
    .. DIR
    TEST1.TXT
    TEST2.TXT
    TEST3.TXT
    D:\>
    -----------------------------
    [送信/キーイン]
    CD ..\r
    [受信]
    D:\>
    -----------------------------
    波形の下(CH1:送信, CH2:受信)
    [送信/コマンドファイル]
    RD LF62TEST.TXT
    DIR
    [受信]
    1234567890
    1234567890
    1234567890
    1234567890
    1234567890
    abef
    D:\>
    -----------------------------
    注】

    • \r はリターンキーの入力
    • 右波形の上(CH1:送信, CH2:受信)は、キーインでファイル読み込みした場合
      \rがトリガポイント

    2007.12.12

    2013年8月1日木曜日

    PIC C18 メモ(USART 接続)

    -----------------------------
    ALFATとの接続と
    シリアルポートのハード設計
    2007.11.24
    -----------------------------
    【シリアルポートのピン接続】

    1. RD
    2. SD
    3. ER, DTR (Data Terminal Ready)
    4. SG (GND)
    5. DSR (Data Set Ready)
    6. RTS (Request to Send)
    7. CTS (Clear to Send)

    【制御線】

    • RTS (out): L は送信要求(使わないときはL)
    • RTS (out): 送信側に停止を要求する時に H
    • CTS (in): L は送信許可(使わないときはL)
    • CTS (in): H では送信しない
    • リターンするときはRTSをCTSへつなぐ(垂れ流し送信の場合など)
    • RTS→CTS
      相手に対して「送信可能である」ことを通知するもの
      このラインが H の時は送信しないで L になるのを待つ
      受信バッファフルで受信出来ないことを表す