2015年01月27日

PICマイコンデバッグ裏技

今回はPICマイコンでデバッグする際に役立つ裏技?をご紹介します。

デバッグの方法としてデバッガー使ったり、LEDで確認したり、
LCDを接続して表示させたり・・・


ご存じな方もいらっしゃると思いますが、
おススメな方法としてマイコンでもprintfでデバッグです。


PIC16FやdsPICで簡単にprintfが使えてしまいます。
といってもデフォルトではマイコンに画面なんてありません。
画面の代わりにUartとして出力されます。







メモリを多く消費してしまうという問題点はありますが、
Uartの初期化だけ済ませればそのままprintfが使えます。


また、秋月やaitendoでUart<->USB変換モジュールがあるため、
そのままUartをRS232Cの電圧レベルに変換なしにTTLレベルで変換できます。


USB-UART変換モジュール [USB2UART-CP2102]
http://www.aitendo.com/product/2890




マイコンのUARTのTXをUSB変換モジュールのRXに接続。
またGNDを接続すればケーブル2本でパソコンに接続できます。

パソコン側にはTeraTerm等のターミナルソフトを用いて表示させます。


debug_image_tt.jpg
実際にプロジェクションボールのマイコン処理情報をPC上に表示させた例

Uartの表示が通信として間に合うように0.2秒ごとに
割り込みを入れて必要な情報を表示させています。


マイコン側とパソコン側でボーレートを合わせる必要がありますが、
初期化だけで簡単にprintfが使えるのはなかなか便利です。



以下に参考プログラム例を示します。

_____________________________
PIC16等の8bitPICの場合
_____________________________
//グローバル関数として宣言しておく
void putch(char data) {
while( ! TXIF) // check buffer
continue; // wait till ready
TXREG = data; // send data
}


//Main関数内で初期化する
    //Uart Initialize
    SYNC = 0;
    BRGH = 0;
    BRG16 = 0;
    SPBRG = 51;//ボーレートはマイコンのクロックに応じて変更

    //TXSTA
    CSRC = 1;
    TX9 = 0;
    TXEN = 1;
    SYNC = 0;
    BRGH = 0;

    //RCSTA

    SPEN = 1;    
    RX9 = 0;        
    SREN = 0;    
    CREN = 1;    
    ADDEN = 0;    
    
_____________________________
dsPIC30F等の16bitPICの場合
_____________________________

//UART 初期化 Main関数の初期化時にinit_uart()を実行させる
 void init_uart(void)
{
 
 unsigned int config1 = UART_EN & UART_IDLE_CON & 0xFFE7 & UART_NO_PAR_8BIT & UART_1STOPBIT
                     & UART_DIS_WAKE & UART_DIS_LOOPBACK & UART_DIS_ABAUD;
 
 unsigned int config2 = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL & UART_TX_ENABLE & UART_INT_RX_CHAR
                     & UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR;
 
//ボーレートはマイコンのクロックに応じて変更
 OpenUART1(config1,config2,191);
}

_____________________________
dsPIC33F等の16bitPICの場合(ピン配置の設定を追加)
_____________________________

 //UART 初期化 Main関数の初期化時にinit_uart()を実行させる
 void init_uart(void)
{
 
 unsigned int config1 = UART_EN & UART_IDLE_CON & UART_IrDA_DISABLE & UART_MODE_FLOW &
 UART_UEN_00 & UART_DIS_WAKE & UART_DIS_LOOPBACK & UART_DIS_ABAUD &
 UART_UXRX_IDLE_ONE & UART_BRGH_SIXTEEN & UART_NO_PAR_8BIT & UART_1STOPBIT;
 
 unsigned int config2 = UART_INT_TX & UART_IrDA_POL_INV_ZERO & UART_SYNC_BREAK_DISABLED &
 UART_TX_ENABLE & UART_INT_RX_CHAR & UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR;
 

    //UART1の設定    PIC33FのI/Oピン割付 初期化 割込設定
    TRISB = TRISB & 0xFF7F;//RB7-U1RX RB6-U1TX    
    RPINR18 = 7;// RP7をU1RXに設定 入力マップ
    RPOR3bits.RP6R = 3;// RP6をU1TXに設定 出力マップ
    //ボーレートはマイコンのクロックに応じて変更
    OpenUART1(config1,config2, 246);

 }

Crescentは上記のプログラムに対していかなる責任も負いません。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする

2015年01月11日

PIC fgets関数


今回は大量のデータをマイコンに入れたい場合の手法をご紹介します。

マイコンでロギングする際にSDカードに情報を書き込む方法がよく使われています。

一方で座標情報やパラメータ設定など大量のデータを読み込みたい場合にも
SDカードを用いて実現することができます。

特にプロジェクションボールで用いる描画の座標情報や
ロボット等のパラメータ情報をそのままマイコンの変数に
1つ1つ代入するのは面倒なのでこの方法がおススメです。


SDカードを使えばPC上で入力したエクセルCSVファイルを
読み込んで簡単に変数に代入することが可能となります。


SDカードに書き込むロギングの情報がネット上にいくらでもありますが
逆のSDカードから読み込むという方法の情報が非常に少ないです。




C言語でファイル操作をしたことがあれば、fgetcやfgets関数はお馴染みなはず。
ここで問題なのはマイクロチップから配布されているSD書き込みMDDFileSystem
スタックにはfread関数と同じ動きをするFSfread関数、fwrite関数と同じ動きをする
FSfwrite関数はありますが、fgetcやfgets関数がないということです。

PICで使用可能なfgetcやfgets関数を作ったのでご紹介します。
既に先人で公開されている方http://www.freeml.com/bl/9519095/55560/がおられましたが、
一部コードが化けていたため、再度作りなおしてみました。


以下に参考としてソースを記述。
char *FSfgets(volatile char *s,volatile int n,FSFILE * stream){
          char *const head = s;        // 先頭ポインタを保存
          for (; n > 1; n--) {

             int c =FSfgetc(stream);    // 1文字入力
             if(c == EOF)break;
                *s = c;                    // 配列に代入
                s++;                    // sを進める
             if (c == '\n')break;
          }
          // 入力失敗のとき
          if (s == head || FSerror()){
               return NULL;
        }
          *s = NULL;
          return head;
         //return s;
}

int FSfgetc(FSFILE *fp){
   volatile char c;
   if(FSfread(&c,1,1,fp) != 1){
            //while(1);
   }
   return (int)c;
}

コメントアウト部分は必要に応じて変更してください。


また、実際に以下のCSVデータをintで読み込む関数をご紹介します。
データ例
 1,23,34
 1,24,25
 1,25,26
    ・
    ・
    ・


以下に参考としてソースを記述。

void setpath(struct path* pR, char* str) {
    int i = 0;
    // 最初の","を探す
    char* pStr = strtok(&str[0], "\",\"");
    while (pStr) {
      switch (i) {
                 case 0:
                       pR->pow = atoi(pStr);
                       break;
         case 1:
                       pR->x = atoi(pStr);
                       break;
         case 2:
                       pR->y = atoi(pStr);
                       break;
                  default:
                       break;
               }
       i++;
            // ","を探す
            pStr = strtok(NULL, "\",\"");
            if (pStr == NULL ) {
              // ","がない場合、最後の"を探す
                pStr = strtok(NULL, "\"\n");
            }
        }
 
}

これらの関数を組み合わせることでCSVファイルからマイコン上の変数に代入できます。
ただ、最後に残る問題はマイコンのRAM容量が限られるため、
dsPIC33Fでもint型400個以上の変数だと容量オーバーしてコンパイルできないんです...
そこをどう回避するかが今後の課題かもしれません。
【ソースに間違い等あっても何もCrescentは責任は負いません】



posted by Crescent at 00:00| Comment(0) | TrackBack(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする

2015年01月05日

モータードライバ裏技

前回はおススメなモータドライバL298Nをご紹介しました。

今回はモータドライバ回路を作成する際の裏技?をご紹介します。



L298Nを使う際やモータドライバを自作する際に地味に面倒なのが

フライホイールダイオードの回路です。


MOSFETやトランジスタに内蔵している場合でも一応、

外付けでフライホイールダイオードを付けとく場合も多いと思います。


SBD_fixed.jpg

図はモータドライバからの出力回路の抜粋です。

1つのHブリッジに対して4つもダイオードが必要なためなかなか面倒です。



L298N_diode2.jpg

実際にチマチマ、ショットキーバリアダイオード(SBD)を

4つ付けた例(白枠に4つSBDがあります)


チップSBDだと場合によって半田にミスって短絡していることもしばしば...笑





そこで、今回おススメな裏技!!

【4つのフライホイールダイオードをダイオードブリッジ1つで代用!】

です。





回路をご覧ください。

L298N_diode3.jpg


先ほど示したHブリッジのスイッチング素子部分に4つダイオードを付ける場合と

回路が等価になります。



ダイオードブリッジの交流側をモータ出力の2端子へ接続。

一方の+をモータ電源のVCC、-をモータ電源のGNDに接続して使用します。


特に秋月ではSBDのダイオードブリッジも販売されているため、

そのまま置き換えが可能です。


ショットキーバリアダイオードブリッジ(60V2A) SDI260




値段の高いSBDを4つ必要な費用とチマチマ付ける手間を考えると、

ワンチップで済む安さと素晴らしさ!


知ってる人はなかなか少ないと思います。


これを思いついたとき、

モータドライバの回路パターンがかなり簡単になるので

自分でちょっと感動しちゃいました(*^^)
posted by Crescent at 00:00| Comment(2) | TrackBack(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする

2014年12月23日

Microchip MDDによるSDカード読み書き

Microchip MDDによるSDカード読み書きについて
躓いた点についてメモ書き。

FSIO.hとspi.hの両方をヘッダとしてインクルードできない問題。

spi.hをインクルードすると、SDカードのイニシャライズに失敗してしまう。
んで、spi.hをインクルードしなければイニシャライズがうまくいくという。

メインで使用するdsPIC33Fを使用する際にこの問題にぶつかりました。


結論から言えば、spi.h内のdefineのmaster_enableが悪さしてました。
spi.hのmaster_enable0とかに少し書き換えて使用すると問題なく共存できました。

spiが2モジュール使用したい場合や
1モジュールでSDカードの読み込みだけして、
以降はspiでSDカード以外の通信する場合にこの方法が有効かも。

もしかしたら、ヘッダのインクルードの順番にもよるかもしれないが…
それにしても初期ではdsPIC33F用のspi設定がなく、
dsPIC33Eをdefineして、dsPIC33Eとして運用しないといけないとか
なんとまあ不親切さを感じます笑

最近のMPLABX用ではSDカード読み書きライブラリが刷新されているので、
このような問題はないと思います。
使い慣れたヘッダファイルを使いたい方には上記を参考にされればと思います。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする