フラッシュメモリでのみ動作するPICは、たいていROMデバッグ |
PIC18F2550のモニタを作る |
ポートのソフト操作による完全非同期のシリアル送受信は可能か? |
PIC18F2550で、一定間隔の割り込みを発生させる |
; 1秒間に約38400回のインターバル割り込みを発生させる設定 clrf T1CON ; タイマー1停止 movlw 0x67 ; 0xCF=19200/4 ==> 4800bps, 0x67=38400/4 ==> 9600bps movwf CCPR1L ; タイマー1コンペアマッチの値 movlw 0x00 movwf CCPR1H ; 上位ビットは0 clrf CCP1CON ; 最初にクリア bsf CCP1CON,CCP1M3 ; タイマー1コンペアマッチ bsf CCP1CON,CCP1M1 ; タイマー1コンペアマッチ bsf CCP1CON,CCP1M0 ; タイマー1コンペアマッチ bsf RCON,IPEN ; 優先割り込みを設定 bsf IPR1,CCP1IP ; Timer1 を優先割り込みに設定 bcf PIR1,CCP1IF ; Timer1 の割り込みフラグをクリア bsf PIE1,CCP1IE ; Timer1 の割り込み許可 bsf INTCON,GIEH ; グローバル割り込み許可 bsf INTCON,GIEL ; グローバル割り込み許可 clrf TMR1H ; Timer1 クリア clrf TMR1L ; Timer1 クリア bsf T1CON,TMR1ON ; Timer1 カウントスタート、以後約26μ秒間隔で割り込みが発生。 |
割り込み処理でソフトウエアUSARTを実現する |
モニタの仕様とコマンド書式 |
コマンドの内容 | 書式 | 引数の説明 |
メモリの表示 d コマンド | dx,y | x は表示したいメモリの先頭アドレス、y は終わりのアドレス |
メモリの変更 s コマンド | sx(,y) | x は変更したいメモリの先頭アドレス、y を追加すると、x のアドレスに y を書いて終わり |
メモリのコピー m コマンド | mx,y,z | x は元の先頭アドレス、y はコピー先のアドレス、z はバイト数 |
m コマンドのオプション | mx,y,z,u | 引数 u = 0x1 でコピー元だけアドレスを更新、u = 0x10 でコピー先だけアドレスを更新 |
メモリの比較 v コマンド | vx,y,z | x は元の先頭アドレス、y は比較先のアドレス、z はバイト数 |
コマンド入力中の修正 | バックスペース | 入力中の1ラインで1文字戻す |
s コマンド実行中のオプション1 | 'n' 1文字入力 | n コマンドでアドレスだけ次に進める |
s コマンド実行中のオプション2 | 'r' 1文字入力 | r コマンドでアドレスだけ前に戻す |
d コマンド実行中のオプション | 任意1文字入力 | メモリダンプを止めてその場で待機。何か入力で再開。ctrl C では中断、終了 |
v コマンド実行中のオプション | 任意1文字入力 | メモリ比較を止めてその場で待機。何か入力で再開。ctrl C では中断、終了 |
簡単なモニタ機能でSDカードの操作をしてみる |
PIC18F2550ポート | PICピン番号 | SDカードピン番号 | SDカードの信号の意味 | プルアップ |
GND | 19 | 3と6 | GND | - |
VDD | 20 | 4 | VDD | - |
SDO 出力(RC7) | 18 | 7 | CMD(DI)入力 | 22kでプルアップ |
SDI 入力(RB0) | 21 | 2 | DAT0(DO)出力 | 22kでプルアップ |
SCK 出力(RB1) | 22 | 5 | CLK 入力 | - |
RB2 出力(RB2) | 23 | 1 | CS 入力 | - |
PIC18F2550ポート | レジスタ名 | アドレス | 設定データ |
ポートC、RC7 出力 | TRISC | 0xF94 | 0x79 |
ポートB、RB0 入力 | TRISB | 0xF93 | 0xF9 |
ポートB、RB1 出力 | TRISB | 0xF93 | 0xF9 |
ポートB、RB2 出力 | TRISB | 0xF93 | 0xF9 |
レジスタ名 | アドレス | 設定データ | 設定の意味 |
SSPSTAT | 0xFC7 | 0x00 | 送信データは、クロックの立下りで更新 |
SSPCON1 | 0xFC6 | 0x32 | SPIをマスターモードに設定。クロックは、Foscの1/64 |
PIC-Mon>sf94,79 (enter) PIC-Mon>sf93,f9 (enter) PIC-Mon>sfc7,0 (enter) PIC-Mon>sfc6,32 (enter) これで、SPIモードの初期化が完了 |
SDカードへのコマンドとレスポンスのタイミング |
SDHCにも対応できるSDカードの初期化は、次の手順になります。 |
モニタにSDカードの操作プログラムを追加 |
PIC-Mon>c40,0,95 (enter) で、CMD0を、パラメータ0x00000000で、CRC7が0x95で出す。 PIC-Mon>r (enter) で、0xFFをSPIに出し、受信データをヘキサで表示する。 PIC-Mon>r200 (enter) で、0xFFを0x200回出し、受信データを、RAMの0x200番地以後に書く PIC-Mon>w4d (enter) で、SPIで、0x4Dを出す。 PIC-Mon>w200 (enter) で、RAMの0x400番地のデータを、順番に0x200バイトSPIに出力する。 PIC-Mon>i (enter) で、CSをHighにして、0xFFを10回SPIで出力する。 PIC-Mon>u (enter) で、CSをHighにして、0xFFを1回SPIで出力する。 |
パソコンから送信したデータをRAMに書く機能をモニタに入れる |
CMD17に対して、0x00の後、いつまでも0xFEを返さないカードがある?? |
CCSを使って、C言語で開発 ( CCS PCH C Compiler, Version 4.076 ) |
PIC18F2550ポート | PICピン番号 | SDカードピン番号 | SDカードの信号の意味 | プルアップ |
GND | 19 | 3と6 | GND | - |
VDD | 20 | 4 | VDD | - |
出力(RC0) | 11 | 7 | CMD(DI)入力 | 22kでプルアップ |
入力(RB0) | 21 | 2 | DAT0(DO)出力 | 22kでプルアップ |
SCK 出力(RB1) | 22 | 5 | CLK 入力 | - |
RB2 出力(RB2) | 23 | 1 | CS 入力 | - |
PIC18F2550ポート | PICピン番号 | FA1A4M | FA1A4M | DSUB9、クロス |
PC6 TXD | 17 → | ベース | コレクタ、プルアップ1k | 3番ピン、RXD |
PC7 RXD | 18 ← | コレクタ、プルアップ4.7k | ベース | 2番ピン、TXD |
CCSを使って、C言語でSDカード操作モニタをまず作ってみる Version 4.076 |
PIC18F_MON>Si ここで Enter キーを押します
|
PIC18F_MON>Si
CMD0: 01 CMD8: 01 CMD58: 00FF8000 ACMD41: 0500 CMD58: C0FF8000 PIC18F_MON> |
PIC18F_MON>Sm ここで Enter キーを押します
|
PIC18F_MON>Sm MBR_start = 0x00002000, MBR_volsects = 0x00F05800 MBR partiton type = 0x0B FAT0_start = 0x00002022, FAT_size = 0x00000783 sectors DIR_start = 0x00002F28, Sectors per cluster = 0x00000040 file start = 0x00002F68, FAT type = FAT32 ここで、MBR_volsects は、このSDカードで使えるセクタ数、 DIR_start は、このSDカードのファイルシステムの、ルートディレクトリの 物理セクタ番号を示しています。この値のセクタを読むと、次の表になります。 その他、FAT32の情報を表示しています。 |
PIC18F_MON>Sr2f28,0 ここで Enter キーを押すと、0x2F28 セクタ
をバッファー0に読みます。バッファーの先頭の物理アドレスは0x22です。 |
PIC18F_MON> と表示した後、
|
PIC18F_MON>d0,80 ここで Enter キーを押します
これは、バッファーの論理アドレス(物理は0x22)から、0x80バイトのメモリの表示です。 |
0022 44 30 30 30 30 20 20 20 54 58 54 20 00 00 0A 4C [D0000 TXT ...L] 0032 6A 40 00 00 00 00 0A 4C 6A 40 03 00 00 00 00 02 [j@.....Lj@......] 0042 44 30 30 30 31 20 20 20 54 58 54 20 00 00 0A 4C [D0001 TXT ...L] 0052 6A 40 00 00 00 00 0A 4C 6A 40 03 04 00 00 00 02 [j@.....Lj@......] 0062 44 30 30 30 32 20 20 20 54 58 54 20 00 00 0A 4C [D0002 TXT ...L] 0072 6A 40 00 00 00 00 0A 4C 6A 40 03 08 00 00 00 02 [j@.....Lj@......] 0082 44 30 30 30 33 20 20 20 54 58 54 20 00 00 0A 4C [D0003 TXT ...L] 0092 6A 40 00 00 00 00 0A 4C 6A 40 03 0C 00 00 00 02 [j@.....Lj@......] PIC18F_MON> これはちょうど、このSDカードのルートディレクトリのセクタを読んだことになります。 コマンドとして、 d0,80 と、0番地から指定しているにもかかわらず、0x0022 番地から 表示されているのは、d0 では、メモリの0番地からではなく、SDカード用のバッファーの 先頭番地の指定になっているからです。 RAMの0番地から表示したい場合は、dm0,80 と、'm' を付加すると、RAMの絶対番地になります。 |
PIC18F_MON>Sd ここで Enter キーを押します
|
PIC18F_MON>Sd 0033554432 00002F68 D0000.TXT 0033554432 00012F68 D0001.TXT 0033554432 00022F68 D0002.TXT 0033554432 00032F68 D0003.TXT 0033554432 00042F68 D0004.TXT 0033554432 00052F68 D0005.TXT 0033554432 00062F68 D0006.TXT 0033554432 00072F68 D0007.TXT 0033554432 00082F68 D0008.TXT 0033554432 00092F68 D0009.TXT 0033554432 000A2F68 D0010.TXT 0033554432 000B2F68 D0011.TXT 0033554432 000C2F68 D0012.TXT 0033554432 000D2F68 D0013.TXT 0033554432 000E2F68 D0014.TXT 0033554432 000F2F68 D0015.TXT PIC18F_MON> ここで、左から、ファイルのサイズ(10進)、 ファイルの先頭の物理セクタ番号、ファイル名となっています。 表示できるのは、ルートディレクトリのみです。 この例では、すべて32MBのファイルで、中身は不定です。 つまり、何も書いていないのです。 PIC18F_MON>F10 ( enter ) で作成したものです。 約2分ほどかかります。 |
ファイル情報だけ書いておいた、中身を書いてないSDカードのファイルに、データを書く |
PICを正規の5Vで動作させるため、基板を新しく作成。 ↑ ここまでの解説では、PICも3.3Vで動作させていた |
PIC18F2550ポート | PICピン番号 | SDカードピン番号 | SDカードの信号の意味 | プルアップ |
GND | 19 | 3と6 | GND | - |
VDD 5V | 20 | 4 | VDD 3.3V | - |
出力(RC0) | 11 | 7 | CMD(DI)入力 | 4.7kでプルアップ |
入力(RB0) | 21 | 2 | DAT0(DO)出力 | 4.7kでプルアップ |
SCK 出力(RB1) | 22 | 5 | CLK 入力 | 4.7kでプルアップ |
RB2 出力(RB2) | 23 | 1 | CS 入力 | 4.7kでプルアップ |
新たに作成した基板で、ニッケル水素電池の充電中の電圧をSDカードに記録 |
PIC18F_MON>Si ここで Enter キーを押します
|
PIC18F_MON>Si
CMD0: 01 CMD8: 01 CMD58: 00FF8000 ACMD41: 0500 CMD58: C0FF8000 PIC18F_MON> |
PIC18F_MON>Sm ここで Enter キーを押します
|
PIC18F_MON>Sm MBR_start = 0x00002000, MBR_volsects = 0x00F05800 MBR partiton type = 0x0B FAT0_start = 0x00002022, FAT_size = 0x00000783 sectors DIR_start = 0x00002F28, Sectors per cluster = 0x00000040 file start = 0x00002F68, FAT type = FAT32 |
PIC18F_MON>l3,1 ここで Enter キーを押します
|
PIC18F_MON>l3,1 PIC18F_MON> ここで、 l3.1 は、ロガーを3モード(A/D読み取り、且つSDカードに記録)で開始し、 D0001.TXT ファイルの先頭から記録するという指示です。 タスクを起動するという呼び方は、タイマー割り込みでA/Dを読み取り、バッファーに記録し、 モニタのキー入力待ちの空き時間で、512バイト溜まったか否かをチェックして、 モニタ機能は残したまま、SDカードに記録するからです。 もっとも、モニタで操作できるのは、その処理はメモリ操作のみが対象で、1秒以内に終わる ものだけです。A/Dコンバーター、SDカードなどの操作はできません。 ログの終了は、 PIC18F_MON>l0 ( enter ) で、モード0を指示するだけです。この指示で、 マルチライト中のCMD25を終了させ、書き残しデータをSDカードにフラッシュします。 突然電源を切ると、書き込み中の最大0x20セクタ(16kB)が書けないことになります。 |
押しボタンスイッチによる操作で、スタンドアロンで動作させる |
測定の項目 | 測定結果 |
最大ピーク電流 | 87mA |
通常ライト中の電流。約2m秒間 | 約50mA |
最大ライトビジー時間/1セクタ | 170msec |
データ転送中の電流 SPI 転送 | 約12mA |
データ転送中の時間 SPI 転送 | 約32 m秒/1セクタ(1秒に1回) |
6時間の総合mAh | 3.1mAh (11256mA*秒) |
PIC24FJxxを、無償版のCコンパイラ、C30で開発 |
64GBのSDカード、SDXCを操作してみた |