JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

PIC16F18326 MCC I2C LCD1602表示テスト

2024-01-14 19:45:34 | MPLAB X MCC
 こちら喜多方市熱塩加納町は、1月12日に降った雪が15cmほど積もっています。近くにある日本で一番すいているスキー場「三ノ倉スキー場」が営業を再開しました。

 雪が降ると、なんだか落ち着くようなきがします。炬燵にあたってPICの勉強を再開しました。PIC18Fシリーズの勉強は一旦棚上げして、PIC16F18326の各種テストをします。このPICは、秋月電子でまだ250円で入手でき、サイズ、機能からもコスパの良いPICだと思います。

 PIC16F18326では、AQM0802AとOLEDの表示テストを既にしていますので、定番のI2C LCD1602の表示テストをします。

 回路図です。I2Cのプルアップ抵抗は、LCD1602に内蔵されているので付けていません。


 MPLAB X(v6.15を使いました)とXC8(v2.45)でprojectを作成し、MCCを立ち上げます。
 MCCで各種の設定をします。まず、System moduleでクロックを設定します。今回は下のように設定し、クロックは4MHzです。

 

 I2Cを使いますので、MSSP1 moduleを導入し、次のように設定しました。
 I2C Clockは100KHzです。割り込みを使いますので、Interrupt Drivenにチェックを入れます。


 Interrupt moduleを次のように設定しました。



 これでGenerateし、MCCを終了します。
 生成されたソースリストmain.cを次のように編集しました。
 内容は、これまで当ブログやJH7UBCホームぺージで発表したものと同じです。
---------------------------------------------------------------------------------
/*
 * PIC16F18326 MCC I2C LCD1602 test
 * 2024.1.13
 * JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"

#define I2C_LCD_addr 0x27
#define LCD_EN 0b00000100//Enable
#define LCD_BL 0b00001000//Back Light
#define LCD_CMD 0x00
#define LCD_CHR 0x01
#define LCD_LINE1 0x80
#define LCD_LINE2 0xC0

//I2C LCDに1byteのdataを書き込む
void I2C_write_data(uint8_t data){
I2C1_Write1ByteRegister(I2C_LCD_addr, (data | LCD_EN | LCD_BL),(data | LCD_BL));
__delay_us(100);
}

//I2C LCDにコマンドまたは文字を送る
void LCD_write(uint8_t data, uint8_t mode){
//上位4bitを送る
I2C_write_data((data & 0xF0) | mode);
//下位4bitを送る
I2C_write_data(((data << 4) & 0xF0) | mode);
}

//I2C LCD 初期化
void LCD_init(){
__delay_ms(40);
LCD_write(0x33,LCD_CMD);//8bit mode set 2回
LCD_write(0x32,LCD_CMD);//8bit mode set 1回,4bit mode set
LCD_write(0x06,LCD_CMD);//Entry mode set
LCD_write(0x0C,LCD_CMD);//display ON,cursol OFF,blink OFF
LCD_write(0x28,LCD_CMD);//Function set 4bit mode,2line
LCD_write(0x01,LCD_CMD);//Clear display
__delay_ms(1);
}

void LCD_clear(){
LCD_write(0x01,LCD_CMD);
__delay_ms(1);
}

void LCD_home(){
LCD_write(0x02,LCD_CMD);
__delay_ms(1);
}

void LCD_cursor(uint8_t x,uint8_t y){
if(y == 0){
LCD_write(LCD_LINE1 + x,LCD_CMD);
}
if(y == 1){
LCD_write(LCD_LINE2 + x,LCD_CMD);
}
}

//文字列の表示
void LCD_str(char *str){
while(*str)
LCD_write(*str++,LCD_CHR); //pointer increment
}

//1文字表示
void putch(char ch){
LCD_write(ch,LCD_CHR);
}

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();
     // Enable the Global Interrupts
     INTERRUPT_GlobalInterruptEnable();

     // Enable the Peripheral Interrupts
     INTERRUPT_PeripheralInterruptEnable();

     LCD_init();
     char msg[] = "Hello World!";
     LCD_str(msg);
     int count = 0;
     while (1){
         LCD_cursor(2,1);
         printf("%3d",count);
         count++;
         __delay_ms(1000);
     }
}
---------------------------------------------------------------------------------
 printf()関数を使っていますので、このままコンパイル(build)するとエラーがでますので、project propertiesを開き、XC8 Global OptionsのC StandardをC90に変更します。
 PICKit3でPICに書き込み、ブレッドボードでテストしました。
 1行目に「Hell World!」が表示され、2行目に数字がカウントアップされました。