【dsPIC33FJ128MC802】秋月LCDキャラクタモジュールSD1602を使ってみる。(8bitモード)
◆dsPIC33FJ128MC802で秋月LCDキャラクタモジュールを8bitモードで使ってみます。
1)パーツ
超小型LCDキャラクタディスプレイモジュール(16×2行バックライト・オレンジ)
ブレッドボードで実験がしやすい1列ピン仕様です。
電源は5V仕様ですがInputVoltage:HIGH=2.2Vなので、3.3VのdsPICでも直でつなげそうです。
2)接続
LCD_SD1602 | dsPIC | memo |
---|---|---|
4_RS | RB8 | Command/Data |
5_R/W | RB9 | Read/Write |
6_E | RB10 | ENABLE |
7_DB0 | RB0 | DATAbit0 |
8_DB1 | RB1 | DATAbit1 |
9_DB2 | RB2 | DATAbit2 |
10_DB3 | RB3 | DATAbit3 |
11_DB4 | RB4 | DATAbit4 |
12_DB5 | RB5 | DATAbit5 |
13_DB6 | RB6 | DATAbit6 |
14_DB7 | RB7 | DATAbit7 |
データ転送にポートBの下位をつかいました。
3)イニシャライズ
仕様書通りに設定しました。ソースではwaitは適当にしちゃいました。
仕様書で2回目のFunction後は100sとなってますが、おそらく100msの間違え!?
STEP | MEMO | Code |
---|---|---|
1 | wait15ms | — |
2 | FunctionSET | 0x30 |
3 | wait4.1ms | — |
4 | FunctionSET | 0x30 |
5 | wait100ms | — |
6 | FunctionSET | 0x30 |
7 | 8BitMode | 0x38 |
8 | Entry | 0x06 |
9 | Clear | 0x01 |
10 | DisplayON | 0x0C |
4)ビジーフラグのチェック
LCDにコマンド/データを書き込んだ後
次の書き込みが可能か否かを判断するために
ビジーフラグをチェックする必要があります。
ビジーフラグチェックの代わりに100μsecほど待ってもokです。
RS | RD/WR | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 |
---|---|---|---|---|---|---|---|---|---|
0 | 1:RD | BF | — | — | — | — | — | — | — |
■フロー
1)DB7に接続したピンを入力に切り替える。
2)コマンドモード
3)リードモード
4)Eanbleをパタパタ
5)DB7の出力をチェックする。
・DB7:0になるまで2~5を繰り返す。
終わったら
6)DB7に接続したピンを出力に切り替える。
ビジーフラグのチェックには「do-while文」で実現しました。
5)ソース
ためしに文字列を表示してみました。
//========================================================= // TEST //========================================================= //== ヘッダファイル ============================================ #include <p33fj128mc802.h> #include <stdio.h> //== define ============================================================= #define SD1602_RS LATBbits.LATB8 #define SD1602_RW LATBbits.LATB9 #define SD1602_E LATBbits.LATB10 //== 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 ================================================ void __attribute__((interrupt,no_auto_psv)) _U1RXInterrupt(void); //UART_RX_Interrupt void __attribute__((interrupt,auto_psv)) _DMA0Interrupt(void); //DMA0_Interrupt //== DMA_UART ==================================================================== unsigned int rex_buf[10]__attribute__((space(dma))); //10byte //== UART ======================================================================== char U1RXstring(void); //receive_string void U1TXstring(char *string, unsigned char count); //tex_string //== SD1602LCD用プロトタイプ ========================================================= void sd1602_init(void); //sd1602初期化 void sd1602_cmd_write(unsigned char data); //sd1602コマンド書き込み void sd1602_data_write(unsigned char data); //sd1602データ書き込み //== sd1602文字列書き込み(配列 + 行目 + 出力数) ======================================= void sd1602_string_write(char *data, char line, unsigned char count); //== 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"; //== original_struct ====================================================== struct{ unsigned pwm_out : 1; unsigned fan : 1; unsigned lamp : 1; }st_flag; //== 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設定 ============================================================ //== 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 //== UART1設定 ========================================================= //== CN_Initialize =================================================== //== DMA_UART ======================================================== //== 前処理 ====================================================== sd1602_init(); //LCD初期化 sd1602_cmd_write(0x80); //== while文 =========================================================== while(1) { sd1602_string_write(test_box,2,9); sd1602_string_write(test_box,1,9); delay_ms(100); }//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 //== SD1602 initialize =================================================== void sd1602_init(void) { delay_ms(100); //100msec sd1602_cmd_write(0x30); //Function_set delay_ms(10); //4.1msec sd1602_cmd_write(0x30); //Function_set delay_ms(100); //100msec sd1602_cmd_write(0x30); //Function_set delay_ms(10); sd1602_cmd_write(0x38); //N=1:2line delay_ms(10); sd1602_cmd_write(0x06); //EntryMode delay_ms(1); sd1602_cmd_write(0x01); //ClearDisplay delay_ms(10); sd1602_cmd_write(0x0c); //DisplayOn delay_ms(1); } //sd1602_init(void) //== SD1602 Command Write =================================================== void sd1602_cmd_write(unsigned char data) { PORTB = data; //data_out SD1602_RS = 0; //command_mode delay_us(10); SD1602_RW = 0; //write SD1602_E = 1; //enable_toggle delay_us(10); SD1602_E = 0; //busy_check TRISBbits.TRISB7 = 1; //input do{ SD1602_RS = 0; //command_mode SD1602_RW = 1; //read_mode SD1602_E = 1; delay_us(10); SD1602_E = 0; }while(PORTBbits.RB7 == 0); SD1602_RW = 0; TRISBbits.TRISB7 = 0; //output delay_us(10); }//void sd1602_cmd_write(unsigned char data) //== SD1602 Data_Write ==================================================== void sd1602_data_write(unsigned char data) { PORTB = data; //data_out SD1602_RS = 1; //data_mode delay_us(10); SD1602_RW = 0; //write SD1602_E = 1; //enable_toggle delay_us(10); SD1602_E = 0; //busy_check TRISBbits.TRISB7 = 1; //input do{ SD1602_RS = 0; //command_mode SD1602_RW = 1; //read_mode SD1602_E = 1; delay_us(10); SD1602_E = 0; }while(PORTBbits.RB7 == 0); SD1602_RW = 0; TRISBbits.TRISB7 = 0; //output delay_us(10); }//void sd1602_data_write(unsigned char data) //== SD1602 String_Write ==================================================== void sd1602_string_write(char *data, char line, unsigned char count) { if(line == 1) //1行目 {sd1602_cmd_write(0x80);} else if(line == 2) //2行目 {sd1602_cmd_write(0xC0);} unsigned int i; for(i=0; i<count; i++) { sd1602_data_write(data[i]); }//for(i=0; i<count; i++) }//void sd1602_string_write(unsigned char *data, unsigned char count) //======================================================================== //=================================================================================
ディスカッション
コメント一覧
まだ、コメントがありません