PIC12F1822 AQM1602Y 表示テスト
JH7UBC 2019.08.06
秋月電子から販売されている3.3V I2C LCD AQM1602Y(バックライト付き、青背景、白文字)をPIC12F1822で表示するテストです。
このLCDを使うときには、下の図のように若干の外付け部品が必要です。(I2Cのプルアップ抵抗を含む)
そこで、ユニバーサル基板を使って、モジュール化しました。
表面です。
裏面です。
AQM1602をコントロールするICは、AQM0802Aと同じで、ST7032iです。
I2Cアドレスも0x7C(0x3E+0)と同じなので、AQM0802A用のプログラムをそのまま使うことができます。
ただし、AQM0802A,AQM1602Yともコントラストは、ソフトで設定しますので、そこは調整が必要です。
コントラストの調整は、拡張コマンドPower/ICONcontrol/Contrast setのC5,C4とContrast setのC3,C2,C1,C0の6ビットで設定します。
AQM0802Aの場合は、C5,C4,C3,C2,C1,C0=100000=32程度ですが、
今回AQM1602Yで調べてみるとC5,C4,C3,C2,C1,C0=101010=42程度で文字が良く見えました。
つまり、コントラスト調整用に拡張コマンドとして、7Aと56を送れば良いことになります。
1行目に「Hello World!」、2行目に0~255をカウントアップする数字を表示してみました。
PIC12F1822とAQM1602Yの接続は、下の図の通りです。電源は乾電池2本としました。
プログラムです。MPLABX v5.05を使い、XC8 v2.05でコンパイルしました。
/*
* File: main.c * Author: JH7UBC Keiji Hata * I2C LCD AQM1602Y * Created on 2019/08/5 */ #include <stdio.h>
#include <stdlib.h> #include <xc.h> // CONFIG1
#pragma config FOSC = INTOSC #pragma config WDTE = OFF #pragma config PWRTE = ON #pragma config MCLRE = OFF #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = ON #pragma config CLKOUTEN = OFF #pragma config IESO = OFF #pragma config FCMEN = OFF // CONFIG2
#pragma config WRT = OFF #pragma config PLLEN = ON #pragma config STVREN = ON #pragma config BORV = HI #pragma config LVP = OFF #define _XTAL_FREQ 32000000
#define LCD_addr 0x7C //3E+0 #define LCD_LINE1 0x80 #define LCD_LINE2 0xC0 /* I2C 初期化*/
void I2C_init(){ SSP1CON1 = 0x28; //SSPEN = 1,I2C Master Mode SSP1STATbits.SMP = 1; //標準速度モード(100KHz) SSP1ADD = 0x4F; //Fosc/(4*Clock)-1 Clock=100kHz,Fosc=32MHz } /* スタートコンディション */
void I2C_start(){ SEN = 1; while(SEN); } /* ストップコンディション */
void I2C_stop(){ SSP1IF = 0; PEN = 1;
while(PEN); SSP1IF = 0; } /* I2Cに1byte送信 */
void I2C_write(unsigned char dat){ SSP1IF = 0; SSP1BUF = dat; while(!SSP1IF); } /* write command */
void LCD_cmd(unsigned char cmd){ I2C_start(); //start condition I2C_write(LCD_addr); //send slave address I2C_write(0x00); //send control byte I2C_write(cmd); //send command I2C_stop(); //stop condition } /* write charactor */
void LCD_char(unsigned char dat){ I2C_start(); //start condition I2C_write(LCD_addr); //send slave address I2C_write(0x40); //send control byte I2C_write(dat); //send data I2C_stop(); //stop condition } /* 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(0x7A); //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 } /* Clear Display */
void LCD_clear(){ LCD_cmd(0x01); __delay_ms(1); __delay_us(80); } /* Return Home `*/
void LCD_home(){ LCD_cmd(0x02); __delay_ms(1); __delay_us(80); } /* Cursor x,y */
void LCD_cursor(unsigned x,unsigned y){ if(y == 0){ LCD_cmd(LCD_LINE1+x); } if(y == 1){ LCD_cmd(LCD_LINE2+x); } } /* write 1 charactor to LCD */
void putch(unsigned char ch){ LCD_char(ch); } void main() { OSCCON = 0b01110000 ; // 内部クロック8MHz ANSELA = 0b00000000 ; // アナログは使用しない TRISA = 0b00000110 ; // RA1,RA2は入力、他は出力 PORTA = 0b00000000 ; // 出力ピンの初期化 I2C_init(); LCD_init(); printf("Hello World!"); unsigned char count = 0; while(1){ LCD_cursor(5,1); printf("%3d",count); count++; __delay_ms(500); } } |