PIC12F1822 I2C LCD AQM0802A表示テスト

2021.05.18 JH7UBC


PIC12F1822を使って、MPLAB X MCCでI2C設定をして、I2C LCD AQM0802Aに文字を表示するテストを行いました。
まず、projectを作成してから、MCCで各種設定を行います。MCCを開いて、System Moduleの設定を行います。

INTOSC,FOSCとし、クロックは16MHzとしました。
Low Voltage programingのチェックははずし、RA3は、GPIOとしました

I2C通信を使うために、Divice Resourceまたは、Avilable ResourceからMSSPを追加します。
Interrupt Drivenにチェックを入れます。
Serial ProtocolをI2Cにセットします。
Modeは、Masterにセット、クロックは100000Hz(100kHz)とします。

割込みを使うので、Interrupt Moduleの設定を行います。
下のように、チェックを入れました。

Pin Moduleには、ちゃんとRA1がSCL、RA2がSDAが設定されています。
一応ウィークプルアップ(WPU)にチェックを入れ、RegistrersでnWPUEN enableにしておきます。

Generateをクリックして、設定終了です。MCCを閉じて、プログラミングをします。各種設定ファイルとmain.cが生成されます。
PIC12F1822とAQM0802Aモジュールの接続回路図です。電源は乾電池を使います。

MCCを使ってAQM0802Aを表示した例は、Web上では例は少なく、どのようにプログラミングするのか頭を悩ませました。
そんな中、KazHatブログというサイトの記事が参考になりました。(というか、コピーさせていただきました)

AQM0802Aをコントロールするには、I2Cスレーブアドレス(AQM0802Aの場合、0x3e)に続いて、
コントロールバイト(コマンドの場合0x00、データの場合00x40)を送り、次にコマンドまたはデータを送ります。

このフォーマットを実現するためには、mcc_generated_files/examples/i2c_master_example.cの中の
I2C_Write1ByteRegister(i2c_address_t address, uint8_t reg, uint8_t data)という関数を使います。

試しに、i2c_address = 0x3e,reg = 0x40,data = 0x41としてAQM0802Aに送信した場合のI2C信号を見てみました。
I2Cアドレスは、bit0にwriteの0が加わって、0x7cとして送信されます。OKです。

以前にMCCを使わないで組んだプログラムとKazHatさんのプログラムを合わせたような次のようなプログラムでテストしました。
printf()関数を使っていますので、projectのpropertiesで、XC8 Global OptionsのC standerdをC90にしてコンパイルします。
/*
* PIC12F1822 MCC I2C LCD AQM0802A
* 2021.05.17
* JH7UBC Keiji Hata
*/

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

#define I2CLCD_AQM0802A 0x3e

//-------- send character ------------------------
void LCD_dat(char chr)
{
I2C_Write1ByteRegister(I2CLCD_AQM0802A, 0x40, chr);
__delay_us(30); // 30us
}

//-------- send command -------------------------
void LCD_cmd(char cmd)
{
I2C_Write1ByteRegister(I2CLCD_AQM0802A, 0x00, cmd);
if(cmd & 0xFC) // bit6 = 1
__delay_us(30); // 30us
else
__delay_ms(2); // 2ms Clear or Home
}

//-------- clear LCD--------------------------
void LCD_clr(void){
LCD_cmd(0x01);
}

//--------- Home -----------------------------
void LCD_home(void){
LCD_cmd(0x02);
}

//--------- Cursor X,Y -----------------------
void LCD_cursor(unsigned char x,unsigned char y){
if (y == 0)
LCD_cmd(0x80 + x);
if (y == 1)
LCD_cmd(0xc0 + x);
}

//-------- display strings -------------------------
void LCD_str(char *str){
while(*str)
LCD_dat(*str++); //pointer increment
}

//-------- write 1 character to LCD ----------------
void putch(unsigned char ch){
LCD_dat(ch);
}

//-------- LCD initialize ---------------------------
void LCD_init(){
__delay_ms(40); //40ms wait
LCD_cmd(0x38); //8bit,2line
LCD_cmd(0x39); //IS=1 : extention mode set
LCD_cmd(0x14); //Internal OSC Frequency
LCD_cmd(0x70); //Contrast set
LCD_cmd(0x56); //Power/ICON/Contrast Control
LCD_cmd(0x6C); //Follower control
__delay_ms(200);//200ms wait
LCD_cmd(0x38); //IS=0 : extention mode cancel
LCD_cmd(0x0C); //Display ON
LCD_cmd(0x01); //Clear Display
__delay_ms(2); //wait more than 1.08ms
}

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

LCD_init();

char msg[] = "Hello!";
LCD_str(msg);

unsigned char count = 0;

while (1)
{
LCD_cursor(2,1);
printf("%3d",count);
count++;
__delay_ms(1000);
}
}

ブレッドボードと文字が表示された様子です。

一応、表示できましたが、PIC12F1822のプログラムメモリ2K Wordsのうち85%を使ってしまいました。データメモリは128byteのうち77%を使いました。
ちなみに、同等のプログラムをMCCを使わないで組んだ場合は、プログラムメモリーの37%、データメモリの27%を使いました。

つまり、MCCを使うと設定が簡略化させる分メモリーをたくさん使うということですね。メモリ容量の大きいPIC向きということでしょうか。

inserted by FC2 system