I2C薄型液晶ディスプレイ(LCD)・AQM1602XAの使い方
表示したいものは日時、ADコンバータの測定値(10個)、気温(4個)、気圧(3個)、湿度、周波数/周期など20項目くらいあるので今使っているACM1602の16文字2行ではまったく足りません。そこで焼け石に水ですがLCDをもう一つサブディスプレイ的に追加しようと思います。
秋月に小さなバックライトなしのディスプレイがありお値段もそんなに高いものではなかったので買ってきました。
これがもう泣きたくなるくらい動きませんでした。
クロックが高すぎる、コマンド送出のタイミングに問題がある、....いろいろ考えたり試したりしたのですが、単に製品についているプログラム例に不備(私の理解不足?)があっただけでした (^^;;
--------
例によってきむしげさん(きむ茶工房ガレージハウス)の記事「秋月電子I2C接続小型LCDモジュールに表示を行うの」は参考になります。詳細な解説つきです。
ACM1602みたいなのは使ったことがあるから要点だけ知りたいという方はMt. Rubbleさんの「Arduino YunでLCD(I2C接続)を制御する。」の方がいいかもしれません。
=======
秋月電子通商の「I2C接続小型キャラクタLCDモジュール(3.3V/5V)ピッチ変換キット 」を使ったのですがまずLCDを変換基板に取り付ける必要があります(感覚的にはLCDに変換基板を取り付けるわけですが)
秋月の写真と見比べていただくとわかるのですが、変換基板を逆向き(裏返し)に取り付けています。実装したときの強度とかスペースを考えてわざとこうしています。別に間違ったわけではないです。
裏側から見るとこうなります。
ピン番号の向きとか自信が持てないときは参考にしてください。
テスト風景です。接続するのはSCL、SDAと電源(VSS、VDD)だけですからI2Cは簡単です。
右上の赤いかたまりは「24ビットバイナリーカウンター(12STAGEリップルキャリー・バイナリー・カウンター TC4040BP+SN74HC4040AP)」で作ったバイナリカウンタです。12bitカウンタ2台に分けてI2Cのクロックとデータを監視しています。どういうデータが送られているかなんてわからないのですが、なんとなくデータを送られていそうだということぐらいは確認できます。
記事の最後にソースを付けておきます。
「I2Cのソース - PIC12F1822/16F1705/16F1938/18F26K22 - LCD(ACM1602)を例にして」にあるI2Cライブラリを使うことを前提にしています。
ソースにも書いてあるように全体的にきむしげさん(「きむ茶工房ガレージハウス」) のソースのパクリです。
ソースは四機種分ありますが、今回はPIC18F26K22だけしか確かめていません。他のでもたぶん動くと思います。そう言えばCG RAMの書き込みも確かめていません(ふだん使わないもので....)
ソースで注意した方がいいところは赤でマークしてあります。
-------
関連
全般
「記事一覧(測定、電子工作、天文計算)」
「趣味の電子工作」
「PIC」
「趣味の実験」
「趣味の気象観測」
PIC
「PIC+SPI+I2C 自記温湿度計+気圧計+8ch電圧計+周波数カウンタ(技術要素一覧)」
「PIC+SPI+I2C 自記温湿度計+気圧計+8ch電圧計のソース - main()」
------------------------
AQM1602lib.h
// 秋月電子通商 AQM1602XA-RN-GBW
// I2C接続薄型16文字x2行液晶
// Sitronix ST7032 CONTROLED
// ソースは次のサイトのものを参考にさせていただきました。
// きむ茶工房ガレージハウス
// http://www.geocities.jp/zattouka/GarageHouse/Top.htm
// Mt. Rubble
// Arduino YunでLCD(I2C接続)を制御する。
// http://blogs.yahoo.co.jp/mattsu1045/55280011.html
#ifndef _AQM1602_H_
#define _AQM1602_H_
#define LCD_ADRES 0x3E
void LCD_Clear(void) ;
void LCD_SetCursor(int col, int row) ;
void LCD_Putc(char c) ;
void LCD_Puts(const char * s) ;
void LCD_CreateChar(int p,char *dt) ;
void LCD_Init() ;
#endif /* AQM1602LIB_H */
AQM1602lib.c
// 秋月電子通商 AQM1602XA-RN-GBW
// I2C接続薄型16文字x2行液晶
// Sitronix ST7032 CONTROLED
// ソースは次のサイトのものを参考にさせていただきました。
// きむ茶工房ガレージハウス
// http://www.geocities.jp/zattouka/GarageHouse/Top.htm
// Mt. Rubble
// Arduino YunでLCD(I2C接続)を制御する。
// http://blogs.yahoo.co.jp/mattsu1045/55280011.html
/*******************************************************************************
* skI2CLCDlib - I2C接続LCD関数ライブラリ *
* このライブラリは秋月電子通商 AQM1602XA-RN-GBW用です。 *
* *
* LCD_Init - LCDの初期化を行う処理 *
* LCD_Clear - LCDモジュールの画面を消す処理 *
* LCD_SetCursor - LCDモジュール画面内のカーソル位置を移動する処理 *
* LCD_Putc - LCDにデータを1バイト出力する処理 *
* LCD_Puts - LCDに文字列データを出力する処理 *
* LCD_CreateChar - オリジナルのキャラクタを登録します *
* *
*******************************************************************************/
#include <xc.h>
#include "MyDef.h"
#include "I2Clib.h"
#include "AQM1602lib.h"
// LCDにコマンドを発行する処理
void command(unsigned char c)
{
int ans ;
ans = I2C_Start(LCD_ADRES,RW_0); // スタートコンディションを発行する
if (ans == 0) {
// command word の送信
I2C_Send(0b00000000) ; // control byte の送信(コマンドを指定)
I2C_Send(c) ; // data byte の送信
}
I2C_Stop() ; // ストップコンディションを発行する
}
/*******************************************************************************
* LCD_Clear( ) *
* LCDモジュールの画面を消す処理 *
*******************************************************************************/
void LCD_Clear(void)
{
command(0x01) ; // Clear Display
__delay_ms(2) ;
}
/*******************************************************************************
* LCD_SetCursor(col,row) *
* LCDモジュール画面内のカーソル位置を移動する処理 *
* *
* col : 横(列)方向のカーソル位置(0-7) *
* row : 縦(行)方向のカーソル位置(0-1) *
*******************************************************************************/
void LCD_SetCursor(int col, int row)
{
int row_offsets[] = { 0x00, 0x40 } ;
// Set DDRAM Adddress : 00H-0FH,40H-4FH
command(0x80 | (col + row_offsets[row])) ;
}
/*******************************************************************************
* LCD_Putc(c) *
* 文字列は、NULL(0x00)まで繰返し出力します。 *
* *
* c : 出力する文字データを指定 *
*******************************************************************************/
void LCD_Putc(char c)
{
int ans ;
ans = I2C_Start(LCD_ADRES,RW_0); // スタートコンディションを発行する
if (ans == 0) {
// command word の送信
I2C_Send(0b01000000) ; // control byte の送信(データを指定)
I2C_Send(c) ; // data byte の送信
}
I2C_Stop() ; // ストップコンディションを発行する
}
/*******************************************************************************
* LCD_Puts(*s) *
* LCDに文字列データを出力する処理 *
* 文字列は、NULL(0x00)まで繰返し出力します。 *
* *
* *s : 出力する文字列のデータを格納した場所のアドレスを指定 *
*******************************************************************************/
void LCD_Puts(const char * s)
{
int ans ;
while(*s) {
LCD_Putc(*s++);
}
}
/*******************************************************************************
* LCD_CreateChar(p,*dt) *
* オリジナルのキャラクタを登録します *
* *
* p : 登録する場所の指定(0〜5の6ヶ所のみ) *
* p : 登録する場所の指定(0〜5の6ヶ所のみ) *
* *dt : 登録したいキャラクタのデータを格納したバッファを指定 *
********************************************************************************/
// **** 未検証です ****
void LCD_CreateChar(int p,char *dt)
{
command(0x40 | p << 3 );
__delay_ms(5) ;
for (int i=0; i < 8; i++) {
LCD_Putc(*dt++);
}
}
/*******************************************************************************
* LCD_Init( ) *
* LCDの初期化を行う処理 *
*******************************************************************************/
void LCD_Init()
{
__delay_ms(40) ;
// Function set
command(0x38);
// Function set
command(0x39);
// Internal OSC frequency
command(0x14);
// Contrast set
// command(0x73); // 3.3V
command(0x76); // 5V
// POWER/ICON/Contrast control
// command(0x56); // 3.3V
command(0x54); // 5V
// Follower control
command(0x6C);
// Function set
command(0x38);
// Display ON/OFF control
command(0x0C);
// Clear Display
command(0x01);
__delay_ms(2) ;
// Entry Mode
command(0x06);
}
main.c
#include <xc.h>
#include "MyDef.h"
#include "I2CLib.h"
#include "AQM1602lib.h"
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\12f1822.html
#ifdef _12F1822
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#endif
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\16f1705.html
#ifdef _16F1705
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#endif
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\16f1938.html
#ifdef _16F1938
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#endif
// C:\Program Files (x86)\Microchip\xc8\v1.32\docs\chips\18f26k22.html
#ifdef _18F26K22
#pragma config FOSC = INTIO67
#pragma config WDTEN = OFF
#endif
void interrupt InterFunction( void )
{
// I2C関連の割り込み処理
InterI2C() ;
}
void main()
{
unsigned short i=0;
int j;
#ifdef _12F1822
OSCCON = 0b01111010 ; // 16MHz
ANSELA = 0b00000000 ;
#endif
#ifdef _16F1705
OSCCON = 0b01110010 ; // 8MHz
ANSELC = 0b00000000 ;
RC0PPS = 0x10;
RC1PPS = 0x11;
#endif
#ifdef _16F1938
OSCCON = 0b01110010 ; // 8MHz
#endif
#ifdef _18F26K22
OSCCON = 0b01110010 ; // 16MHz
// for I2C
ANSELCbits.ANSC3 = 0;
ANSELCbits.ANSC4 = 0;
#endif
InitI2C_Master() ;
LCD_Init() ;
LCD_Clear();
while(1) {
LCD_Putc((i & 0x3f) + 0x30);
for( j=0; j < 12; j++ ) __delay_ms(40);
i++;
if( ( i & 0x1f ) == 0x10 ) {
LCD_SetCursor(0, 1);
} else if(( i & 0x1f ) == 0x00 ) {
LCD_Clear();
}
}
}
// PIC18F26K22
// 01 /MCLR .....(1), Pull-up 10k
// 02 RA0/AN0
// 03 RA1/AN1
// 04 RA2/AN2/DACOUT
// 05 RA3/AN3
// 06 RA4
// 07 RA5/AN4
// 08 VSS
// 09 RA7
// 10 RA6/OSC2/CLKO
// 11 RC0
// 12 RC1
// 13 RC2
// 14 RC3/SCL1.....I2C Clock, Pull-up 5k
// 15 RC4/SDA1.....I2C Data, Pull-up 5k
// 16 RC5/SDO1
// 17 RC6/TX1
// 18 RC7/RX1
// 19 VSS .....(3)
// 20 VDD .....(2)
// 21 RB0/INT0
// 22 RB1/SCL2
// 23 RB2/SDA2
// 24 RB3/SDO2
// 25 RB4
// 26 RB5
// 27 RB6/TX2/PGC .....(5)
// 28 RB7/RX2/PGD .....(4)
MyDef.h
/*
* File: MyDef.h
* Author: Seppina
*
* Created on 2014/11/22, 14:38
*/
#ifndef MYDEF_H
#define MYDEF_H
// http://www.microchip.jp/docs/41406B_JP.pdf
#ifdef _12F1822
#define _XTAL_FREQ 16000000
#define MySSPADD 0x27
#define SSPIE SSP1IE
#define SSPIF SSP1IF
#define BCLIE BCL1IE
#define BCLIF BCL1IF
#endif
// http://ww1.microchip.com/downloads/en/DeviceDoc/40001729A.pdf
// http://ww1.microchip.com/downloads/jp/DeviceDoc/40001722A_JP.pdf
// (下は16F1703のものですが参考になります。これもきむしげさん情報です)
#ifdef _16F1705
#define _XTAL_FREQ 8000000
#define MySSPADD 0x13
#define SSPIE SSP1IE
#define SSPIF SSP1IF
#define BCLIE BCL1IE
#define BCLIF BCL1IF
#endif
// http://ww1.microchip.com/downloads/en/DeviceDoc/40001574C.pdf
#ifdef _16F1938
#define _XTAL_FREQ 8000000
#define MySSPADD 0x13
#endif
// http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
#ifdef _18F26K22
#define _XTAL_FREQ 16000000
#define MySSPADD 0x27
#endif
#endif /* MYDEF_H */
« 誤解している人が多そうなコンデンサの“ESR”の意味 | トップページ | PICでSPI - SDカードの書き込みエラーの話 »
「趣味の電子工作」カテゴリの記事
- PICで作る100MHz周波数カウンタ検証用XOR(エクスクルーシブオア)逓倍器(2016.03.08)
- 150MHz(~200MHz?)周波数カウンター用プリスケーラー(1/4分周器)(2016.03.06)
- 測温抵抗体(Pt100、白金薄膜温度センサー)の抵抗値を温度に変換する(平方根を使わない)計算式(2016.03.01)
- GPS/JJY(標準電波)を基準周波数源とするためのPLLの詳細(2016.02.27)
- GPS受信モジュール1PPS対決 - GE-612T vs GM-5157A(2016.02.21)
この記事へのコメントは終了しました。
« 誤解している人が多そうなコンデンサの“ESR”の意味 | トップページ | PICでSPI - SDカードの書き込みエラーの話 »
コメント