2013年5月26日日曜日

PIC C18 メモ( #define の活用 )

-----------------------------
#define の活用
-----------------------------
#ifdef Global-Define
#define extern /**/  //extern を消す
#else
#define extern Extern  //Exturn へ置換
#endif

文字の置換だけなので、「消す」こともできるという例

2013.06.25

PIC C18 メモ( enum の活用 )

-----------------------------
enum の活用(一般)
-----------------------------
enum xxxx { HL, LL, WAIT };
  • HL=0, LL=1 =WAIT=2 が自動的に定義される
  • C18では char 型
  • 連続した値の #define の代用
  • xxxx はタグ名、省略可
enum xxxx { HL, LL, WAIT } yyyy;
enum { HL, LL, WAIT } yyyy;
enum { HL, LL, WAIT };
  • yyyy は変数名、省略可
  • このまま変数名として使用でき、その変数には、他の値を代入することもできてしまう
typedef enum xxxx { HL, LL, WAIT } yyyy;
typedef enum { HL, LL, WAIT } yyyy;
typedef enum { HL, LL, WAIT };
  • 型の別名宣言により、yyyy joken = WAIT; のように型名として使える
      -----------------------------
      enum の活用(配列の要素名)
      -----------------------------
      enum type { Atype, Btype, Ctype, TYPEmax };
      • #define TYPEmax     4
        を別に定義する必要がなくなる
      • 配列の要素名と個数を同時に一個所で定義できる
      ------------------ -----------
      enum の活用(ビット指定)
      -----------------------------
      enum switch { Asw=0x01, Bsw=0x02, Csw=0x04, Dsw=0x08 };
      • 対応するスイッチのビット指定も一個所でできる
      2009.8 - 2013.05.26

      PIC C18 メモ(割り込みを使った一文字受信ができない)

      -----------------------------
      割り込みコンテキスト保存
      2006.11.20
      -----------------------------
      static char ReturnData;        //これを割り込み側で読み取るのは可

      static char ReceiveData;        //受信データをここへ返してほしい
      #pragma inturrupt Ack_spi;
      void Ack_spi(void)
      {
       RcvData=SSPBUF;
      };
      • 上のようにグローバル変数に受信バッファからRcvData へ保存しても
        割り込み処理(ISR)側で割り込み処理ルーチンから外れるとクリアされてしまう
      • プロトタイプ宣言に save=RcvData を書き加えるだけでいい
        #pragma inturrupt Ack_spi save=RcvData;

      凡人なので日本語マニュアルに例題まで上げて何ページも割いて解説してあるにもかかわらず、その場面になって調べないと身につかないというお粗末。
      2013.05.26

      2013年5月25日土曜日

      PIC C18 メモ(内蔵のEEPROMを使う)

      -----------------------------
      EEPROMを使う
      2006.09.24, 2009.05.05, 2013.05.25
      -----------------------------
      • 書き換え回数制限がある
      • EEPROM 書き込み前に割り込みを無効化しておくこと
      • 書き込むデータをバイトアクセス可能なように「共用体」で定義しておく
      • 書き換えるときの事を考えた(For文で簡単にできるような)データの並びにしておく
      -----------------------------
      EEPROM プログラム時に初期値を書込む
      2009.05.21
      -----------------------------
      #pragma romdata ee=0xF00000
      const rom struct {
      int Term[ 5 ];
      char No;
      }ee_Data[ 3 ] = {
      { 200,130,400,260,100,3, },
      { 130,70,320,200,100,2, },
      { 100,0,450,320,100,1, },
      };
      #pragma romdata
      プログラミング時に直接EEPROMに書き込める。上は構造体の配列の定義と代入をしているが、共用体でバイト単位にFOR文で一気にEEPROMの読み書きができるようにしておいたほうがいい。
      その必要がなければ、ずらずら書けばいい。要は、#pragma romdata ee=0xF00000 でEEPPROM 領域の指定ができるということ。
      -----------------------------
      EEPROM アドレス計算
      2012.08
      -----------------------------
      unsigned int e_adr = eDATA_HEAD;    //EEPROM領域の書き込み開始アドレス
      unsigned int max = sizeof( sData );      //書き込むRAM領域データ本体のサイズ
      char *s_adr = ( char * )&sData;          //sData本体の先頭アドレスをキャストして取得(*1)

      #define したデータ個数などの定数を足したり掛けたりして求めていたが、これだと一発。 for 文で読み書きする。また、(*1)の方法をとれば、sData をバイト単位で読み出せるような共用体の定義をしておく必要はない。

      初めの頃の作品は、直接EEPROMのアドレスに初期値を書き込む方法がわからず、リセット時に EEPROM から読み込んだ先頭番地が FF (プログラミング前)なら、ROMデータとして作成したデフォルト値をその時点で書き込むという、手の込んだ方法を採っている。(笑)

      2013年5月24日金曜日

      PIC C18 メモ(構造体の活用とtypedef)

      -----------------------------
      構造体の活用
      -----------------------------
      参考書の例題で、氏名、性別、身長、体重、にくくり、配列(管理番号)でまとめ、構造体でレコードを構成する。 このように、まとまったデータの固まりは、できるだけ整理して構造体形式に落とし込むべき。
      • ヘッダファイルで typedef で宣言して使用する
      • 構造体を引数にして渡す事ができる
      • 関連するデータを一体化できるので、変更の時分かり易い
      • 使い方がわかるとすごく便利
      • 規模が大きくなると必須
      プログラムの作り込みが進むにつれて、あるいは、リリース後いくつかの改造を経たりしていると、データの並びが整理されて、拡張性や、修正のしやすさなどを考え、例え冗長となっても、プログラムの方の負担が大きく減る方向の構造になってくる。
      -----------------------------
      typedef
      -----------------------------
      typedef は、自分で「型」の名前を定義できるので、このような構造体を使う場合は、型名を予め定義しておくとよい。
      構造体のデータは、関数の引数に使える。このときにtypedef宣言した型名を使用することになる。引数が3つ以上になるようなデータ構造は、構造体にしてみることを考えた方がいい。
      (最初の頃の疑問や小細工が、いとも簡単に解決した思い出が)
      2010.02 - 2013.07.03

      2013年5月23日木曜日

      PIC C18 メモ(関数を作る時に)

      -----------------------------
      関数を作るときの注意点
      -----------------------------
      1. IN-OUT, Write-Read の様に、対に考えて作成していくこと
        • 呼び出す側の上位のコードが読みやすくなる
        • 一つにまとめて引数で指定(例ON, OFF)した方がいい場合と、別々の関数とした方がいい場合に分かれる
        • 共通の処理ループだったり、エラーの処理がわかりやすい
      2. グローバル変数を下位レベルの関数で使わないこと
        • 効率が落ちる欠点がある
        • 直接呼び出して操作した方が簡単だが、後で訳が分からなくなる
        • 上位から渡してやる手順とした方が、関数の使い回しが容易である
      3. 関数から文字列を返すことはできない
        • 返してもらう文字列用のバッファを準備して、そこへ入れてもらう
          (ポインタを渡して戻り値を入れてもらう。ただしバッファの長さには要注意)
        • 標準ライブラリの関数等と同じような引数の並べ方ににすること
          strcpy( こっちへ, こっちから )
      - 2013.07.03

      2013年5月22日水曜日

      PIC C18 メモ(ピン割り当て)

      -----------------------------
      ピン割り当てを考える時のチェックリスト
      -----------------------------

      1. 内部クロックが使えないか考えて
        • OSC ピンが RA6,RA7 として使用できる
      2. ADCON1 の設定は必須
        • 起動時の初期値がアナログ入力になっている
        • RA,RB,RE ポート設定に絡む
      3. PORTA
        • RA4 はオープンドレイン
        • 入力向きのポート(スイッチ等に割り当てる)
      4. PORTB
        • アナログ入力も可
        • 弱プルアップがデフォルト( INTCON2bits.RBPU )
        • RB0,1,2 が外部入力割り込みとして使用できる
        • RB5,6,7 は ICSP で使用する( RB5 は LVP の時 L )
        • RB6,7 はプルアップしないこと( ICSP )
      5. PORTC
        • 内臓モジュールが混在しているので BSF,BCF は注意
        • 入力はシュミットトリガ
      6. PORTD
        • 8bit 並列通信として PORTE と組み合わせて使える(パラレルスレーブポート,PSP)
      7. PORTE
        • MCLR と RE3 共用
        • ADCON1 の設定必須
      2006.10.27

      2013年5月20日月曜日

      PIC 割り込みを使わないわけ

      できるだけ割り込みを使わないプログラムを心がけている。従って「イベントドリブン」ではなく、入力やタイマをポーリングする方式で、4~10ms でループを構成する。従ってスイッチ入力はループ回数を数えて反応するような作り方にしている。
      波形の暴れなど気にしたこともないデジタル屋の作ったバスボード上で動くマイコン応用システムで、割り込み入力に飛び込むノイズで手痛い目にあった。システムの中に、高電圧波形を外部出力する回路が有り、これがノイズ源となった。
      使う場合は、割り込みを許可と不許可のタイミングを意識しないと。

      2013年5月19日日曜日

      PIC C18 メモ (ビット操作)

      -----------------------------
      指定ビットのみ反転する
      -----------------------------
      以下は、簡略化のため 4bit で表現

      対象ビット列 dest: 0001
      指定ビット   mask: 0010

       0001 0001
      &1101 &0010
      ----- -----
       0001 0000
         ~0010
         -----
          0010


       0001
      ~0010
      -----
       0011


      式で表すと
      dest=( dest & ~mask ) | ((dest & mask) ~mask)

      ~(チルダ)は、各ビットを反転させる
      !(エクスクラメーション)の、「否定」とは違うので注意

      -----------------------------
      ビット反転と負数(2の補数)
      -----------------------------
       a(HEX)= FC FD FE FF 00 01 02
       a(DEC)= -4 -3 -2 -1  0  1  2

      ~a(HEX)= 03 02 01 00 FF FE FD
      ~a(DEC)=  3  2  1  0 -1 -2 -3


      反転しただけでは、ゼロの位置が移動してしまう。・・・・・+1すると負数になる(2の補数)

      2008.01.16

      2013年5月18日土曜日

      PIC C18 メモ (アップダウンカウンタ)

      -----------------------------
      アップダウンカウンタ
      2009.08.20
      -----------------------------
      0 から MAX-1 の間でアップダウンカウントする。アップダウンボタンでの循環操作に使う、ループカウンタ。

      char LoopCount( const char MAX, const char odd );
      {
          static char Count;
          Count += odd;
          if( Count > MAX ){
              Count = 1;
          }
          else if( count <= 0 ){
              Count = MAX;
          }
          return Count - 1;
      }

      【使い方】
      ゼロクリアの時の引数     MAX=1, odd=0
      プラス1する時の引数     MAX=max, odd=1
      マイナス1したい場合     MAX=max, odd=-1
      現在値を取得する時     MAX=max,odd=0
      2009.08.20 付メモから

      2013年5月15日水曜日

      PIC C18 割り込み遅延

      • Microchip C18 (Version 3.4.5)
      • PIC18F2321
      • クロックは 20MHz
      • 外部入力割り込み INT0(RB0) の立ち下がりエッジ
      • 割り込みは 31kHz 周期
      • 割り込みをカウントし、580発目で RA3ポートに L を出力
      • Hに戻すのは、590発目
      という条件で、出力までの時間(遅延+処理)のテストをした。
      • 4usくらいで反応する
      • 0.2us( 4x1/20MHz )のゆらぎが発生する(完全同期は不可)
      ところが、プログラムを書き換えたりしているうちに、応答時間が 12us と遅くなってしまった。
      (波形上)(青波形が割り込み入力)

      設定を変えてみたり、ネットで探ってみたが解決できず困った。Disassembly Listing View を追うと ISR に入るまでずいぶんとステップが入っている。

      答えはC コンパイラ ユーザーズガイド(日本語版有り)にちゃんとあった。ISR に入るまでコンテキストの退避がすべての項目で実行されている模様。

      最初は何も記述せず済んでいたのだが、nosave=XXX を書き加えないとならないハメになっようだ。

      #pragma interrupt isr nosave=xxx,yyy,zzz

      とISRセクション宣言部分に記述する。
      WREG,BSR,STATUS 以外を nosave と記述した場合、8us に。 ISR からカウント関数呼び出しせず直接記述し直すと 4us となって、最もシンプルな形の応答時間(波形下)に戻った。

      ISR: 割り込みサービスルーチンの事
      ポートに出力するまでの 4us は、短縮の余地が残っている

      【おまけ1】
      ポートに出力するだけの一行しかない関数(名前をつけてわかりやすくしたいため)でも、CALL命令で正直にコンパイルされるため、かなりステップがかさむ事が分かった。必要なら、#defineで見た目だけポートの名前を変えるなどした方がいいのかも。
      【おまけ2】
      テスト用の基板を使ってオシロで測定していたが、Debugger->SelectTool->MPLAB SIM を使っても割り込み処理の時間計測ができる事が分かった。画面上で、割り込み信号を与えることもできる。

      2013年5月14日火曜日

      iphone4 USB-Dock ケーブル修理(再)

      Dockコネクタの根元が、前回修理から半年持たずにちぎれた。頻繁に充電するみたいだし、コードが30センチくらいと短いので、充電しながら使ったりするとストレスが根元にかかる。

      シリコンゴムをピンセットで剥がすと、コネクタのピンの根元(前回撮った左写真の○印個所)が折れている。iphone の充電が空状態だったので、とりあえずハンダ付けして応急処置した。


      潔くギブアップして、代わりの新品ケーブルを購入。マイクロUSBとやらの形状がいまいちよく分からず、ケーブル付にして正解だった。
      最近購入したデジカメの付属USBケーブル(写真の下)のものをマイクロUSBと思い込んでしまっていた。
      写真の中がマイクロ USB で、写真の上がミニ USB だ。
      USB-Dockケーブルの方が安価にあるが、構造的に長持ちしそうにないということでアダプタ式に。

      2013年5月12日日曜日

      CAD Eagle バージョンアップ(費用)

      一年ぶりに使うことになった。立ち上げるとバージョンアップを勧めてくる。6.4.0 までバージョンが進んでいた。
      ダウンロードしてインストールしてみた。ライセンスを尋ねてくるので、入力してみるが、受け付けてくれない。無料バージョンで使うのでなければ、バージョンアップ料金を払わないとならないようだ。
      国内代理店へ見積もり依頼したら、すぐに回答があった。
      スタンダードライセンスを再取得するには数万円かかる。グレードを落とせば7千円くらい。
      費用対効果が分からない。
      旧バージョンはそのまま残っているので、今回の案件は旧版で作業した。一年ぶりの割には思ったよりスムースに入れた。ただ、やっぱり新しい部品を登録して、使えるようになるまでが一番時間がかかる。
      電源ラインをきれいに通せるようレイアウトに時間をかけた。パターンの方は自動配線を使うこともなくすいすいと終わってしまった

      おまけ
      部品面側でサーマルランドを形成させない、あるいはグランド接続の信号ピンを後で使えるように、部品面側にパターンを作らないようにする方法を見いだした。部品面のパターン禁止域(tRestrict)にて太さ0.1mm程度のリングで囲ってしまえばいい。