◆dsPIC33FJ128MC802で秋月LCDキャラクタモジュールを8bitモードで使ってみます。



1)パーツ
超小型LCDキャラクタディスプレイモジュール(16×2行バックライト・オレンジ)
ブレッドボードで実験がしやすい1列ピン仕様です。
電源は5V仕様ですがInputVoltage:HIGH=2.2Vなので、3.3VのdsPICでも直でつなげそうです。

2)接続













LCD_SD1602dsPICmemo
4_RSRB8Command/Data
5_R/WRB9Read/Write
6_ERB10ENABLE
7_DB0RB0DATAbit0
8_DB1RB1DATAbit1
9_DB2RB2DATAbit2
10_DB3RB3DATAbit3
11_DB4RB4DATAbit4
12_DB5RB5DATAbit5
13_DB6RB6DATAbit6
14_DB7RB7DATAbit7

データ転送にポートBの下位をつかいました。

3)イニシャライズ
仕様書通りに設定しました。ソースではwaitは適当にしちゃいました。
仕様書で2回目のFunction後は100sとなってますが、おそらく100msの間違え!?












STEPMEMOCode
1wait15ms---
2FunctionSET0x30
3wait4.1ms---
4FunctionSET0x30
5wait100ms---
6FunctionSET0x30
78BitMode0x38
8Entry0x06
9Clear0x01
10DisplayON0x0C


4)ビジーフラグのチェック
LCDにコマンド/データを書き込んだ後
次の書き込みが可能か否かを判断するために
ビジーフラグをチェックする必要があります。
ビジーフラグチェックの代わりに100μsecほど待ってもokです。





RSRD/WRDB7DB6DB5DB4DB3DB2DB1DB0
01:RDBF---------------------

■フロー
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)
//========================================================================

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



6)実験の様子
LEDをつかわなかったので暗くてわかんない。
写真

7)回路図
a3da4246.png