秋月電子から3.3V I2C LCD AQM1602Y(バックライト付き背景青、白文字)を購入しました。
この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
*/
* File: main.c
* Author: JH7UBC Keiji Hata
* I2C LCD AQM1602Y
* Created on 2019/08/5
*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.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
#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
#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
#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_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_start(){
SEN = 1;
while(SEN);
}
/* ストップコンディション */
void I2C_stop(){
SSP1IF = 0;
PEN = 1;
while(PEN);
SSP1IF = 0;
}
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);
}
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
}
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
}
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
}
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);
}
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);
}
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);
}
}
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 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);
}
}
LCD_init();
printf("Hello World!");
unsigned char count = 0;
while(1){
LCD_cursor(5,1);
printf("%3d",count);
count++;
__delay_ms(500);
}
}