2014-06-20に投稿

PIC32MX220F032BでキャラクタLCD

先日PIC12でキャラクタLCDが出来たので
PIC32でも色々試してみたいと思いLCDを試すことに。

とりあえず成功したプログラムをパパっと移植して実行。
…動かない。

よくよく見ると3.3VじゃLCDが動作しないので
余っていたHT7750と4x4基板で5V変換基板をごちゃごちゃに作った。
DSC_0297

しかしこれでも動かない。
1日悩んで色々調べてみるが、
なんとなくPICの動作が早すぎてダメなんじゃないかと思い
SD1602のデータシートを見たり色々と調べてみた。

どうもやはりPICのクロックが早すぎる場合は
ちょいちょいdelayを入れてあげないとダメっぽい気がしたので
色々な情報を参考に入れてみたところ動くようになった。

|c|

include <xc.h>

include <plib.h>

pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF

pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_8

define SYS_FREQ (80000000L)

define LCD_RS BIT_0

define LCD_EN BIT_1

define LCD_D4 BIT_11

define LCD_D5 BIT_13

define LCD_D6 BIT_14

define LCD_D7 BIT_15

void __delay_us(WORD us)
{
DWORD start = _CP0_GET_COUNT();
DWORD end = start + SYS_FREQ / 10000000 / 2 * us;
// DWORD end = start + SYS_FREQ / 1000000 / 2 * us;
if (end > start) while (_CP0_GET_COUNT() < end);
else while (_CP0_GET_COUNT() > start || _CP0_GET_COUNT() < end);
}

void __delay_ms(unsigned int msec) //1msec遅延関数
{
unsigned int i;

for(i=0; i&lt;msec; i++) {
    __delay_us(1000);
}

}

void lcdStrobe() {
mPORTASetBits(LCD_EN);
__delay_us(1);
mPORTAClearBits(LCD_EN);
}

void lcdSetBit(int bt, char value) {
if (value == 1) {
mPORTBSetBits(bt);
} else {
mPORTBClearBits(bt);
}
}

void lcdCommand(unsigned char c)
{
mPORTAClearBits(LCD_RS);
lcdSetBit(LCD_D4, c & 1);
lcdSetBit(LCD_D5, (c >> 1) & 1);
lcdSetBit(LCD_D6, (c >> 2) & 1);
lcdSetBit(LCD_D7, (c >> 3) & 1);
lcdStrobe();
__delay_us(50);
}

void lcdWrite(unsigned char c)
{
lcdSetBit(LCD_D4, (c >> 4) & 1);
lcdSetBit(LCD_D5, (c >> 5) & 1);
lcdSetBit(LCD_D6, (c >> 6) & 1);
lcdSetBit(LCD_D7, (c >> 7) & 1);
lcdStrobe();
lcdSetBit(LCD_D4, c & 1);
lcdSetBit(LCD_D5, (c >> 1) & 1);
lcdSetBit(LCD_D6, (c >> 2) & 1);
lcdSetBit(LCD_D7, (c >> 3) & 1);
lcdStrobe();
__delay_us(50);
}

/*******************************************************************************
* lcd_setCursor - LCDモジュール画面内のカーソル位置を移動する処理 *
* col : 横(列)方向のカーソル位置(0-15) *
* row : 縦(行)方向のカーソル位置(0-1) *
********************************************************************************/
void lcdSetCursor(int col, int row)
{
int row_offsets[] = { 0x00, 0x40 } ;

 mPORTAClearBits(LCD_RS);
 lcdWrite(0x80 | (col + row_offsets[row])) ; // Set DDRAM Adddress : 00H-0FH,40H-4FH

}

void lcdClear(void)
{
mPORTAClearBits(LCD_RS);
lcdWrite(0x01) ; // Clear Display : 画面全体に20Hのスペースで表示、カーソルはcol=0,row=0に移動
__delay_ms(2) ; // LCDが処理(1.53ms)するのを待ちます
}

void lcdPutc(char c) {
mPORTASetBits(LCD_RS);
lcdWrite(c);
}

void lcdPuts(const char s) {
mPORTASetBits(LCD_RS);
while(
s) {
lcdWrite(*s++);
}
}

void lcdInit()
{
mPORTAClearBits(LCD_RS | LCD_EN);

__delay_ms(40) ;    // 電源ON後15msまで待ってから初期化

// LCDの立上げ時のチェックデータ(イニシャライズ処理用)を設定
lcdCommand(0x03) ;
__delay_ms(5) ;
lcdCommand(0x02) ;
__delay_ms(5) ;
// LCDにコマンドを発行します
lcdWrite(0x28) ;   // function set   : データ線は4本・表示は2行・フォントは5x8ドット
lcdWrite(0x0c) ;   // display control: 画面表示はON・カーソル表示はOFF・カーソル点滅はOFF
lcdClear() ;       // Clear Display  : 画面をクリアし、カーソル位置はcol=0,row=0
lcdWrite(0x06) ;   // entry mode set : 文字を表示した次にカーソルを移動するを指示

}

int main(void)
{
char s[17];

SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
mJTAGPortEnable(DEBUG_JTAGPORT_OFF);

mPORTASetPinsDigitalOut(LCD_RS | LCD_EN);
mPORTBSetPinsDigitalOut(LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7);
lcdInit();
lcdPuts("Monitor");

int i = 0;
while(1)
{
    __delay_ms(1000);
    itoa(s, i++, 10);
    lcdSetCursor(0, 1);
    lcdPuts("          ");
    lcdSetCursor(0, 1);
    lcdPuts(s);
}

}
||

delayの関数はどっかの情報を参考にしたのだが、
指定の10倍くらいのdelayになってしまっていたのでちょっと変更してある。
なぜそのようなプログラムになっていたかも、計算してもよくわからない。
今の状態も適当に合わせてあるだけ。
計算して作ってみても全然合わなかったので…。

VoをGNDに繋いでいるせいか、コントラストがなさすぎて文字が見えにくい。
斜めから見るとよく見えるのだが。
PIC18の時はそんなことなかったのでなんかの設定が上手くできていないせいかもしれないが
そのへんは試してないのでよくわからない。

ほんとは内蔵の8MHzで動かしたかったのだが、
ちょいっとconfigをいじってみたらすぐ動かなくなるので
とりあえずは断念した。
8MHzで動かせたらdelay省けるところもあるっぽい。

しかしPIC32MXはプログラムとか情報が少なくてきつい…。

ツイッターでシェア
みんなに共有、忘れないようにメモ

だら@Crieit開発者

Crieitの開発者です。 Webエンジニアです(在宅)。大体10年ちょい。 記事でわかりにくいところがあればDMで質問していただくか、案件発注してください。 業務依頼、同業種の方からのコンタクトなどお気軽にご連絡ください。 業務経験有:PHP, MySQL, Laravel, React, Flutter, Vue.js, Node, RoR 趣味:Elixir, Phoenix, Nuxt, Express, GCP, AWS等色々 PHPフレームワークちいたんの作者

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント