【dsPIC33FJ128MC802】FIFOメモリAL422を使ってみる。
◆dsPIC33FJ128MC802でFIFOメモリのAL422を使ってみます。
昨年流行ったOV7670+FIFOカメラモジュールのメモリにはAL422が使われていました。
読み込み作業と書き込み作業を別々に行える利点がありますね。
PICの内蔵RAMだけでは不十分なのでAL422を外付けRAMとして今後利用したいと思います。
FIFOとは:先入れ先出し
参考
データーシートを参考にしました。
読み込み方法
制御ピン名<6:0> | PIN | Function |
/RRST | 21 | ReadReset |
RCK | 20 | ReadClock |
/RE | 24 | ReadEnable |
/OE | 22 | OutputEnable |
DO7~DO0 | 15-18,25-28 | DataOutput |
128byte捨て読みが必要。
全ての作業の前に128byte捨て読みが必要見たいです。
page15のReadOperationに記載があります。
128byte捨て読まないと失敗します。実験では半日取られました。
アドレスリセットAddressReset
0番地から読む為にアドレスリセットを行います。
RRST:LOWの時にRCKの立ち上がりでリセットされます。
通常はRRSTはHIGHにしておきます。
詳細は下のタイミングチャートにて・・・
データリード
RRST:HIGHで
RCKが立ち上がり時にはDOはセットされているようです。
私は立ち上がり直前のデータを採用しました。
書き込み方法
制御ピン名<6:0> | PIN | Function |
/WRST | 8 | WriteReset |
WCK | 9 | WriteClock |
/WE | 5 | WriteEnable |
DI7~DI0 | 1-4,11-14 | DataInput |
アドレスリセットAddressReset
0番地から書き込む為にアドレスリセットを行います。
WRST:LOWの時にWCK立ち上がりでアドレスリセットとなります。
通常はWRSTはHIGHにしておきます。
詳細は下のタイミングチャートにて・・・
データライト
WRST:HIGHで
WCK立ち上がり時にDIにセットしておく必要があります。
ソース
仕様:
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) //======================================================================== //=================================================================================
ディスカッション
コメント一覧
まだ、コメントがありません