PICマイコンの使い方

PICマイコンの8bitマイコンから32bitマイコンまで使いこなすぞ! 周辺機能やアセンブラ、C言語を使いこなすぞ。ARMには負けないぞ! 頼みの綱はPIC32MZだ!たのしみだなー

dsPIC33FJ128MC802

【dsPIC33FJ128MC802】PMP接続のDMA転送でaitendoの1.44インチ液晶TFT(ZY-FGD)を使ってみる。その3

◆dsPIC33FJ128MC802でaitendoの1.44インチTFT液晶ZY-FGD1442701V1-PCBをPMP接続でDMA転送してみます。
①gifをgomplayerで画像ファイルを抜き取り
②gimpで16bitBMPに変換
③VC++で作ったアプリケーションでBMPファイルを都合のいいように編集
④BMPヘッダをカットしてリトルエディアンをビッグエディアンに変更する。
⑤SDカードに保存しPICからMicroChipのFATシステムAN1045を使ってDMAのメモリ一杯分の1024byteをread
⑥そのまんまPMPのDMA転送する。(4行分)
だいたい12fpsぐらいでした。
動画1

動画2


動画3


動画4


スパゲティー状態:
1.44インチTFT液晶ZY-FGD1442701V1-PCB

【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。


◆dsPIC33FJ128MC802でaitendoの1.44インチTFT液晶ZY-FGD1442701V1-PCBをPMP接続でDMA転送してみます。



1)参考
パクる気満々で色々ググってもPICマイコンでPMPのDMA転送をやられている方がいらっしゃらないようで・・・
挙句には自分のサイトが出てきてしまいました。これはチャレンジするしかない!
以前の作成した記事PMPのDMA転送をつかってみる。aitendoの1.44インチ液晶TFT(ZY-FGD)をPMP接続で使ってみる!を組み合わせてちょっと変えれば出来ます。その他マイクロチップ社のリファレンスマニュアルを参考にしました。
2)PMPの設定
PMPのリファレンスDS70299のP28の35-5にDMAサポートの記載がちょろっとあります。
PMP_DMAのサポート
①「PMMODEbits.IRQM = 0b01」にする。
重要:PMP書き込み後に割り込み発生をかけます。
実際にはこの機能を利用して割り込みフラグをチェックしてDMA転送完了を知ります。
ほかの機能は前回と同様なので省きます。
3)DMAの設定(チャンネル0を使用する。)
 ①「DMA0CONbits.SIZE = 1」
byte転送にします。(0でword転送)
 ②「DMA0CONbits.DIR = 0」
転送方向をRAM→peripheralにします。
 ③「DMA0CONbits.HALF = 0」
フルブロック転送したら割り込みにします。
 ④「DMA0CONbits.MODE = 0b01」
転送はワンショットモード。
 ⑤「DMA0CNT = 255」
転送したbyte数を入れます。ただし「0」は「1byte」なのでn-1で設定します。
最大で9bit=1024byte設定可能です。
 ⑥「unsigned int tex_buf[256]__attribute__((space(dma)));」
転送バッファーを用意します。サイズはunsigned int型です。DS70215のpage18を参照。
 ⑦「DMA0PAD = (volatile unsigned int)&PMDIN1;」
peripheralAddressを指示します。
 ⑧「DMA0STA = __builtin_dmaoffset(tex_buf);」
DMA転送開始Addressを指示します。

DMA転送ルーチン
①PMADDRbits.ADDR0をセットします。
②tex_buf[]にデータを入れる。
③DMA0CONbits.CHENをセットしDMA0をENABLEにします。
④DMA0REQbits.FORCEをセットし強制転送を開始します。
⑤勝手にWRはパタパタします。
⑥ADDR0を固定すれば連続書き込みが可能!!
⑦CPUを介さないDMA転送といえど書き込み完了を待つ必要があります。
超重要:IFS0bits.DMA0IFをチェックして転送が完了したか否かを判断します。
これがわからずに1日費やしてしまいました。

PMPのDMA設定プログラム

//== DMA_PMP ========================================================
DMA0CON = 0x0000; //clear
DMA0CONbits.SIZE = 1; //<14>byte_send
DMA0CONbits.DIR = 1; //<13>write_mode
DMA0CONbits.HALF = 0; //<12>full_block
DMA0CONbits.MODE = 0b01; //<1-0>one_shot
DMA0CNT = 255; //block_size_254byte
DMA0REQbits.IRQSEL = 0b0101101; //PMP_peripheral
DMA0PAD = (volatile unsigned int)&PMDIN1; //peripheral_address
DMA0STA = __builtin_dmaoffset(tex_buf); //DMA_start_address
DMA0CONbits.CHEN = 0; //dma_disable







4)メインのプログラム

LCDの初期化等は省きます。aitendoのままです。

ブルーバック後、任意の個所に赤ラインを描画します。

LCDに256byte連続でDMA転送してます。

//== interrupt_function_prototype ================================================
void __attribute__((interrupt,auto_psv)) _DMA0Interrupt(void); //DMA0_Interrupt
//== DMA_PMP ====================================================================
unsigned int tex_buf[256]__attribute__((space(dma))); //dma_buffer
unsigned char *st_pointer; //line_pointer
unsigned char st_box[256]; //line_data
//== main ==================================================================
int main(void)
{
//== クロックの設定 ======================================================
//== Fcy=Fosc/2=7.37M*((PLLFBD+2)/(N2*N1))/2=39.61MHz ================
PLLFBDbits.PLLDIV = 41; //M=PLLFBD+2
CLKDIVbits.PLLPOST = 0; //N2=2
CLKDIVbits.PLLPRE = 0; //N1=2
OSCTUN = 0; //TuneFRC:7.37MHz
RCONbits.SWDTEN = 0; //Disable Watch Dog
while(OSCCONbits.LOCK != 1); //wait for PLL Lock
//== AD切り替え ==========================================================
AD1PCFGL = 0xffff; //全digital
//=== TRISA ===========================================================
TRISA = 0x0000; //initial_
//== TRISB =============================================================
TRISB = 0x0000; //input:
//== PMP_Initialize ===================================================
PMMODE = 0x0000;
PMMODEbits.MODE = 0b11; //<9-8>MastarMode_1
PMMODEbits.IRQM = 0b01; //<15-14>dma_interrupt_request
PMCON = 0x0000;
//== port_select ====
//== R/W:PMRD/PMWR ==
PMCONbits.PTRDEN = 1; //<8>PMRD/PMWR_enable
PMCONbits.RDSP = 1; //<0>PMRD/PMWR
//== RS:PMA0 ========
PMAENbits.PTEN0 = 1; //<0>PMA0_enable
//== CN_Initialize ===================================================
//== DMA_PMP ========================================================
DMA0CON = 0x0000; //clear
DMA0CONbits.SIZE = 1; //<14>byte_send
DMA0CONbits.DIR = 1; //<13>write_mode
DMA0CONbits.HALF = 0; //<12>full_block
DMA0CONbits.MODE = 0b01; //<1-0>one_shot
DMA0CNT = 255; //block_size_254byte
DMA0REQbits.IRQSEL = 0b0101101; //PMP_peripheral
DMA0PAD = (volatile unsigned int)&PMDIN1; //peripheral_address
DMA0STA = __builtin_dmaoffset(tex_buf); //DMA_start_address
//== 前処理 =====================================================
PMCONbits.PMPEN = 1; //<15>PMP_enable
DMA0CONbits.CHEN = 0; //dma_disable
zy_init(); //sb1602_init()
st_pointer = &st_box[0]; //first_byte_set
zy_full_set(0x00,0x1f); //blueback
//== while文 ===========================================================
while(1)
{
zy_line(st_pointer); //line_out
}//while(1)
}//int main(void)
//== set ===================================================
unsigned char st_box[256] =
{
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00
};
//==========================================================
void zy_line(unsigned char *byte)
{
zy_write(0,0x2a); //x_address
zy_write(1,0x00); //start
zy_write(1,0x02);
zy_write(1,0x00); //end
zy_write(1,0x81);
zy_write(0,0x2b); //y_address
zy_write(1,0x00); //start
zy_write(1,0x0f);
zy_write(1,0x00); //end
zy_write(1,0x0f);
zy_write(0,0x2c); //memory_write
//check_pin
LATAbits.LATA0 = !LATAbits.LATA0;
//array_copy
memcpy(tex_buf,byte,sizeof(tex_buf));
//pmp+dma_sending
PMADDRbits.ADDR0 = 1; //write_mode
IFS0bits.DMA0IF = 0; //flag_off
//force_dma_one_times
DMA0CONbits.CHEN = 1; //DMA0_enable
DMA0REQbits.FORCE = 1; //One_times
//dma_sending_wait
while(IFS0bits.DMA0IF == 0); //send_wait
//check_pin
LATAbits.LATA0 = !LATAbits.LATA0;
}//void zy_line()
//======================================================================
//== zy_fgd Write 0:cmd/1:data ====================================================
void zy_write(unsigned flag, unsigned char data)
{
//command_mode
if(flag == 0)
{PMADDRbits.ADDR0 = 0;} //command_mode/cd_low
//data_mode
else{PMADDRbits.ADDR0 = 1;} //data_mode
//PMP
while(PMMODEbits.BUSY == 1); //PMP_OK?
PMDIN1 = data;
}//void zy_write(unsigned flag, unsigned char data)







5)波形の確認
黄色がWRの挙動です。ピンクはRA1に接続してます。1ライン転送毎に切り替えてます。
1ライン分256byteDMA転送するのに19.34μsecかかり、(1byte転送は大体50nsecでした。)
DMA転送バッファーにコピーするのに13.12μsecかかりました。
TOTALで32.84μsecかかりました。PMP接続と比較すると2.5倍速くなりました。
1f3858c2.png

6)実行の様子(PMP接続の時と変わりません。)
aitendoの1.44インチ液晶TFT(ZY-FGD)PMP接続DMA転送1ライン出力

7)回路図(PMP接続の時と変わりません。)
28b9ed33.png


【dsPIC33FJ128MC802】aitendoの1.44インチ液晶TFT(ZY-FGD)をPMP接続で使ってみる!


◆dsPIC33FJ128MC802でaitendoの1.44インチTFT液晶ZY-FGD1442701V1-PCBを使ってみます。
液晶はaitendoで購入できます。
PMP接続自体はスピードアップにはつながりませんが後のDMA転送時に便利です。



1)参考
以前の作成した記事PMPを使ってみる。秋月LCD-SD1602と接続。をちょっと変更するだけでできます。

2)PMPの設定
PICでLCDコントローラの例
「書き込みenable」がないのでPMENBとの接続は必要ありません。

1.パラレルポートモード選択をマスタモード1設定
①「PMMODEbits.MODE = 0b11」にする。

2.読み/書きイネーブルPTRDENを有効にする。
 ①「PMCONbits.PTRDEN = 1」にして
 ②「PMCONbits.RDSP = 1」します。
 ③pin24がPMRD/PMWRになります。

 ④LCDのRWと接続します。
 ⑤ただし読み込みRDは使わないので未接続です。

書き込みのとき・・・
①PMADDRbits.ADDR0をセットします。
②PMDIN1にデータを入れる。
③勝手にWRはパタパタします。
④ADDR0を固定すれば連続書き込みが可能!!

読み込みのとき・・・
①PMADDRbits.ADDR0をリセットします。
②PMDIN1から読み出します。
③今回は使いません。

PMP設定のプログラム

//== PMP_Initialize ===================================================
PMMODE = 0x0000;
PMMODEbits.MODE = 0b11; //<9:8>MastarMode_1
PMCON = 0x0000;
//== port_select ====
//== R/W:PMRD/PMWR ==
PMCONbits.PTRDEN = 1; //<8>PMRD/PMWR_enable
PMCONbits.RDSP = 1; //<0>PMRD/PMWR
//== E:PMENB ========
//PMCONbits.PTWREN = 1; //<9>PMWR/PMENB_enable
//PMCONbits.WRSP = 1; //<1>PMENB
//== CD:PMA0 ========
PMAENbits.PTEN0 = 1; //<0>PMA0_enable
PMCONbits.PMPEN = 1; //<15>PMP_enable







3)メインのプログラム

LCDの初期化等は省きます。

ブルーバック後、任意の個所に赤ラインを描画します。

256byte連続で書き込みます。

    unsigned char *st_pointer;      //line_pointer
unsigned char st_box[256]; //line_data

void zy_write(unsigned flag, unsigned char data); //(flag:0:command/1:data)
void zy_full_set(unsigned char h_byte, unsigned char l_byte);
void zy_line(unsigned char *byte); //line_out

st_pointer = &st_box[0]; //first_byte_set
zy_full_set(0x00,0x1f); //blueback
//== while文 ===========================================================
while(1)
{
zy_line(st_pointer); //line_out
}//while(1)

//== set ===================================================
unsigned char st_box[256] =
{
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,0xf8,0x00,
0xf8,0x00,0xf8,0x00,0xf8,0x00
};
//==========================================================

//== zy_fgd Write 0:cmd/1:data ====================================================
void zy_write(unsigned flag, unsigned char data)
{
//zy_cs = 0;
//command_mode
if(flag == 0)
{PMADDRbits.ADDR0 = 0;} //command_mode/cd_low
//data_mode
else{PMADDRbits.ADDR0 = 1;} //data_mode
//PMP
while(PMMODEbits.BUSY == 1); //PMP_OK?
PMDIN1 = data;
}//void zy_write(unsigned flag, unsigned char data)
//== zy_fgd_full_set ============================================
void zy_full_set(unsigned char h_byte, unsigned char l_byte)
{
unsigned int i;
for(i=0; i<16384; i++)
{
zy_write(1,h_byte);
zy_write(1,l_byte);
}
}//void zy_full_set(unsigned char h_byte, unsigned char l_byte);
//=================================================================================

void zy_line(unsigned char *byte)
{
zy_write(0,0x2a); //x_address
zy_write(1,0x00); //start
zy_write(1,0x02);
zy_write(1,0x00); //end
zy_write(1,0x81);
zy_write(0,0x2b); //y_address
zy_write(1,0x00); //start
zy_write(1,0x04);
zy_write(1,0x00); //end
zy_write(1,0x04);
zy_write(0,0x2c); //memory_write
//check_pin
LATAbits.LATA0 = !LATAbits.LATA0;
PMADDRbits.ADDR0 = 1; //data_mode_set
unsigned char count;
for(count=0; count<256; count++)
{
PMDIN1 = *(byte+count); //auto_increment
//byte++;
}//for(count=0; count<128; count++)+
//check_pin
LATAbits.LATA0 = !LATAbits.LATA0;
}//void zy_line()
//======================================================================







4)波形の確認

黄色がWRの挙動です。ピンクはRA1に接続してます。1ライン転送毎に切り替えてます。

1ライン描画するのに84μsecかかりました。

2437654c.png








5)実行の様子
aitendoの1.44インチ液晶TFT(ZY-FGD)PMP接続1ライン出力

6)動画をとってみました。
SDカードから連続的にBMPデータを書き込み続けてみました。

ちなみにDMA転送だと超早いです。

7)回路図
28b9ed33.png


次回はPMPのDMA転送です。転送スピードが3倍程度速くなります!

【dsPIC33FJ128MC802】デジタルポテンションメータAD5245を使ってみる。


◆dsPIC33FJ128MC802でアナログデバイスのデジタルポテンションメータAD5245を使ってみます。
抵抗値をI2C制御で変更できるので様々や用途で活躍できると思います。



本デバイスはREAD/WRITE可能ですが、WRITEのみにチャレンジしてみたいと思います。
パッケージがSOT-23ですがピッチが狭いので半田付けが大変です。
bc0650e5.jpg

1)AD5245仕様
・256段階
・抵抗値:5kΩ/10kΩ/50kΩ/100kΩ
・電源:2.7V~5.5V

2)参考
データーシートを参考にしました。

3)WRITE書き込み
c53f9d08.png
StartBIT→「SLAVE_ADDRESS」→ACK→「Instruction」→ACK→「data」→Ack→StopBIT
■SlaveAddress:01011000(書き込み時/AD0pinをLOW時)
■Instruction:00000000

4)ソース
仕様:
8bitレジスタに毎回+1加算してAD5245に書き込み。
Wピンをオシロで確認
80fa290b.png



ソースは前後かなり端折りましたのでご注意ください。


//== AD5245 ======================================================================
void ad_5245_write(unsigned char data); //write
unsigned char data;
//=====================================================================
while(1)
{
sprintf(string_box,"%03u",data);
sb1602_string_write(string_box,1,4); //bmp_data_write
ad_5245_write(data);
delay_ms(10);
data++;
}//while(1)
}//int main(void)

//== SB1602 Write ====================================================
void ad_5245_write(unsigned char data)
{
//StartBIT
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
I2C1CONbits.SEN = 1; //start_bit
while(I2C1CONbits.SEN); //start_wait
//address
I2C1TRN = 0b01011000; //slave_address
while(I2C1STATbits.TBF); //transmit_wait
while(I2C1STATbits.ACKSTAT); //ACK_CHECK
//mode_select
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
I2C1TRN = 0b00000000; //command_write
while(I2C1STATbits.TBF); //transmit_wait
while(I2C1STATbits.ACKSTAT); //ack_check
//data
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
I2C1TRN = data; //transmit
while(I2C1STATbits.TBF); //transmit_wait
while(I2C1STATbits.ACKSTAT); //ack_check
//StopBIT
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
I2C1CONbits.PEN = 1; //stop_bit
while(I2C1CONbits.PEN); //stop_bit_wait
}//void ad5245_data_write(unsigned char data)
//========================================================================


5)回路図
AD0pin:LOW
0dfaf959.png

【dsPIC33FJ128MC802】FIFOメモリAL422を使ってみる。

◆dsPIC33FJ128MC802でFIFOメモリのAL422を使ってみます。
昨年流行ったOV7670+FIFOカメラモジュールのメモリにはAL422が使われていました。
読み込み作業と書き込み作業を別々に行える利点がありますね。
PICの内蔵RAMだけでは不十分なのでAL422を外付けRAMとして今後利用したいと思います。
FIFOとは:先入れ先出し



1)参考
データーシートを参考にしました。

2)READ読み込み









制御ピン名<6:0>PIN機能
/RRST21ReadReset
RCK20ReadClock
/RE24ReadEnable
/OE22OutputEnable
DO7~015-18,25-28DataOutput


128byte捨て読みが必要。
全ての作業の前に128byte捨て読みが必要見たいです。
page15のReadOperationに記載があります。
128byte捨て読まないと失敗します。実験では半日取られました。

②アドレスリセットAddressReset
0番地から読む為にアドレスリセットを行います。
RRST:LOWの時にRCKの立ち上がりでリセットされます。
通常はRRSTはHIGHにしておきます。
詳細は下のタイミングチャートにて・・・

③データリード
RRST:HIGHで
RCKが立ち上がり時にはDOはセットされているようです。
私は立ち上がり直前のデータを採用しました。

deac160d.png

3)Write書き込み








制御ピン名<6:0>PIN機能
/WRST8WriteReset
WCK9WriteClock
/WE5WriteEnable
DI7~01-4,11-14DataInput


①アドレスリセットAddressReset
0番地から書き込む為にアドレスリセットを行います。
WRST:LOWの時にWCK立ち上がりでアドレスリセットとなります。
通常はWRSTはHIGHにしておきます。
詳細は下のタイミングチャートにて・・・

②データライト
WRST:HIGHで
WCK立ち上がり時にDIにセットしておく必要があります。

b052a3fb.png

4)ソース
仕様:
PORTAから書き込み(書き込んだら加算)
PORTBから読み込みといった具合です。
①捨て読み128byte
②書き込み128byte
③読み込み128byte
④LCDに読み込んだ最初の10byteを書き込む
繰り返し②~④
//=========================================================
// TEST
//=========================================================
//== ヘッダファイル ============================================
#include <p33fj128mc802.h>
#include <stdio.h>

//== define =============================================================
#define SB1602_RE LATBbits.LATB10
#define WCK LATBbits.LATB11
#define WRST LATBbits.LATB12
#define RCK LATBbits.LATB13
#define RRST LATBbits.LATB14
#define bit_0 LATBbits.LATA0
#define bit_1 LATBbits.LATA1
#define bit_2 LATBbits.LATA2
//== configuration ======================================================
_FBS(BSS_NO_FLASH //No Boot program Flash segment
& BWRP_WRPROTECT_OFF); //Boot Segment may be written
_FGS(GSS_OFF //User program memory is not code-protected
& GWRP_OFF); //User program memory is not write-protected
_FOSCSEL(FNOSC_FRCPLL //Internal Fast RC (FRC) w/ PLL
& IESO_OFF); //Start-up device with user-selected oscillator source
_FOSC(FCKSM_CSDCMD //Both Clock Switching and Fail-Safe Clock Monitor are disabled
& IOL1WAY_ON // Allow Only One Re-configuration
& OSCIOFNC_ON //OSC2 pin has digital I/O function
& POSCMD_NONE); //Primary Oscillator Disabled
_FWDT(FWDTEN_OFF); //Watchdog timer enabled/disabled by user software
_FPOR(FPWRT_PWR128 //PowerOnReset_128ms
& ALTI2C_OFF); //I2C mapped to SDA1/SCL1 pins
_FICD(JTAGEN_OFF //JTAG is Disabled
& ICS_PGD1); //Communicate on PGC1/EMUC1 and PGD1/EMUD1
//== interrupt_function_prototype ================================================

//== Sb1602_LCD用プロトタイプ =========================================================
void sb1602_init(void); //sb1602初期化
void sb1602_write(unsigned flag, unsigned char data); //(flag:0:command/1:data)
//== sb1602文字列書き込み(配列 + 行目 + 出力数) =======================================
void sb1602_string_write(char *data, char line, unsigned char count);
//== DRAM_write ==================================================================
void dram_line_write(void);
void dram_line_read(char *data);
void dram_sute_read(void);
//== MyTimer =====================================================================
void delay_us(unsigned int usec); //Timer1を利用したusec関数
void delay_ms(unsigned int msec); //msec関数
//== StringBox ===================================================================
unsigned char akiLCD_RAM[48][200];
char rev_data[4]; //uart_rex
char test_box[10] = "test_mode";
char test_box2[130] = "xxxxxxxxxx";
//== main ==================================================================
int main(void)
{
//== クロックの設定 ======================================================
//== Fcy=Fosc/2=7.37M*((PLLFBD+2)/(N2*N1))/2=39.61MHz ================
PLLFBDbits.PLLDIV = 41; //M=PLLFBD+2
CLKDIVbits.PLLPOST = 0; //N2=2
CLKDIVbits.PLLPRE = 0; //N1=2
OSCTUN = 0; //TuneFRC:7.37MHz
RCONbits.SWDTEN = 0; //Disable Watch Dog
while(OSCCONbits.LOCK != 1); //wait for PLL Lock
//== AD切り替え ==========================================================
AD1PCFGL = 0xffff; //全digital
//=== TRISA ===========================================================
TRISA = 0x0000; //initial_
//== TRISB =============================================================
TRISB = 0x0000; //input:
//== i2c設定 ============================================================
I2C1CON = 0x0000; //初期クリア
I2C1CONbits.I2CEN = 1; //15_I2C_ENABLE
I2C1BRG = 0x18b; //100kHz
//== TIMER1設定 =========================================================
T1CONbits.TON = 0; //<15>Timer1_OFF
T1CONbits.TSIDL = 1; //<13>アイドルモード:Sleep中は停止
T1CONbits.TGATE = 0; //<6>ゲート積算時間:OFF
T1CONbits.TCKPS = 0B00; //<5:4>_PS1:1
T1CONbits.TCS = 0; //<2>クロックソース:内部
IEC0bits.T1IE = 0; //割り込み拒否
IPC0bits.T1IP = 0; //優先レベル0
//== 前処理 =====================================================
WCK = 1;
WRST = 1;
RCK = 1;
RRST = 1;
PORTA = 0;
TRISBbits.TRISB0 = 1; //
TRISBbits.TRISB1 = 1; //
TRISBbits.TRISB2 = 1; //
sb1602_init(); //LCD初期化
sb1602_string_write(test_box,1,9);
sb1602_string_write(test_box2,2,10);
delay_ms(1000);
//== ram_clean ======
dram_sute_read();
//== while文 ===========================================================
while(1)
{
//sb1602_string_write(test_box,2,9);
dram_line_write();
dram_line_read(test_box2);
sb1602_string_write(test_box,1,9);
sb1602_string_write(test_box2,2,16);
//sb1602_string_write(rev_data,2,4);
test_box[0] = test_box[0]+1;
delay_ms(1000);
}//while(1)
}//int main(void)


//== delay_us関数 =================================================================
void delay_us(unsigned int usec)
{
TMR1 = 0; //TMR1=0
T1CONbits.TON = 1; //Timer1_start
PR1 = 39; //PR1値:((目的値1usec)/(1サイクル:0.0025usec*PS)-1)=39
unsigned int i;
for(i=0; i<usec; i++)
{ //タイマーフラグ待ち
while(!IFS0bits.T1IF); //Timer1割り込みフラグチェック(IFS0bits.T1IF==0)
IFS0bits.T1IF = 0; //割り込みフラグ下ろす
}//for(i=0; i<usec; i++)
}//void delay_usec();
//== delay_ms関数 ==================================================================
void delay_ms(unsigned int msec)
{
unsigned int i;
for(i=0; i<msec; i++)
{
delay_us(1000); //call:1000usec
}//for
}//void delay_ms

//== dram_line_write ======================================================
void dram_line_write(void)
{
//== address rest ===
WRST = 0;
WCK = 0;
WCK = 1;
WRST = 1;
//== data 1 ==
PORTA = 0;
unsigned char i;
for(i=0; i<128; i++)
{
WCK = 0;
//data_set
WCK = 1;
PORTA++;
}
//== end ========
}//dram_line_write
//== dram_line_read ======================================================
void dram_line_read(char *data)
{
//== start ======================
RRST = 0;
RCK = 0;
RCK = 1;
RRST = 1;
//================================
unsigned char i;
for(i=0; i<128; i++)
{
RCK = 0;
data[i] = 0x30 + PORTB;
RCK = 1;
//data[i] = (PORTB & 0b00000111) + 0x30;
//data[i] = 0x30 + PORTB;
}
//== end =======================
}//dram_line_read
//== dram_sute_read ======================================================
void dram_sute_read()
{
//== start ======================
RRST = 0;
RCK = 0;
RCK = 1;
RRST = 1;
//================================
unsigned char i;
for(i=0; i<128; i++)
{
RCK = 0;
RCK = 1;
asm("nop");
}
//== end =======================
}//dram_sute_read
//== SB1602 initialize ===================================================
void sb1602_init(void)
{
delay_ms(100); //40msec
SB1602_RE = 0;
delay_ms(300);
SB1602_RE = 1; //RESET
delay_ms(300);
sb1602_write(0,0x38); //cmd_Function
delay_ms(1); //1msec
sb1602_write(0,0x39); //cmd_拡張Function
delay_ms(1); //1msec
sb1602_write(0,0x14); //cmd_Internal_OSC
delay_ms(1); //1msec
sb1602_write(0,0x7F); //cmd_Contrast
delay_ms(1); //1msec
sb1602_write(0,0x5f); //cmd_PowerIconContrast
delay_ms(1); //1msec
sb1602_write(0,0x6a); //cmd_FollowerControl(RightNibble:3.0V_b/3.3V_a)
delay_ms(250); //200msec
sb1602_write(0,0x0C); //cmd_DisplayOn
delay_ms(1); //1msec
sb1602_write(0,0x01); //cmd_ClearDisplay
delay_ms(1); //1msec
}//sb1602_init(void)
//== SB1602 Write ====================================================
void sb1602_write(unsigned flag, unsigned char data)
{
//StartBIT
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
I2C1CONbits.SEN = 1; //StartBIT
while(I2C1CONbits.SEN); //Start待ち
//address
I2C1TRN = 0x7c; //ADDRESS
while(I2C1STATbits.TBF); //送信待ち
while(I2C1STATbits.ACKSTAT); //ACK_CHECK
//mode_select
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
//command_mode
if(flag == 0)
{I2C1TRN = 0x00;} //control/RS=0
//data_mode
else
{I2C1TRN = 0x40;} //data/RS=1
while(I2C1STATbits.TBF); //送信待ち
while(I2C1STATbits.ACKSTAT); //ACK_CHECK
//data
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
I2C1TRN = data; //送信データ
while(I2C1STATbits.TBF); //送信待ち
while(I2C1STATbits.ACKSTAT); //ACK_CHECK
//StopBIT
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
I2C1CONbits.PEN = 1; //StopBIT
while(I2C1CONbits.PEN); //Stop待ち
}//void sb1602_data_write(unsigned char data)
//== SC1602 String_Write ====================================================
void sb1602_string_write(char *data, char line, unsigned char count)
{
if(line == 1) //cmd_1行目
{sb1602_write(0,0x80);}
else if(line == 2) //cmd_2行目
{sb1602_write(0,0xC0);}
unsigned int i;
for(i=0; i<count; i++)
{
sb1602_write(1,data[i]); //data_write
}//for(i=0; i<count; i++)
}//void sb1602_string_write(unsigned char *data, unsigned char count)
//========================================================================

//=================================================================================



5)回路図
入力、出力ともに3bit用意しました。
0~7まで数えることが出来ます。
b29d0200.png
ギャラリー
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
メッセージはこちちらからお願いします。

名前
メール
本文
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

ブログパーツ
  • SEOブログパーツ
にほんブログ村 その他趣味ブログ 電子工作へ
にほんブログ村
アクセスカウンタ
アクセスランキング