はじめに

当サイトでは、がた老さんが作られたI2Cを持たないATtiny用のUSIを利用したI2Cライブラリィを改良(改悪)して公開している。

木村さんからTinyI2CMasterの使い方の問い合わせのメールをいただいた。
使い方がわかりにくいとのこと、確かに公開しているライブラリィはI2Cデバイスをドライバを作るためのソフトウェアであって、使用例としてパッケージに一部ドライバを同封しているがこれはおまけである。

TinyI2CMasterとは

さて肝心のTinyI2CMasterだが、改めて書くが、これはハードウェアの抽象化・I2Cプロトコルの抽象化を実現したソフトウエアです。

構成は以下の通り

+----------------+
|    各ドライバ    | ==> 各人が用意
+----------------+
        ↓↑
+----------------+
|    中層レイア    |
+----------------+ ==> ここがTinyI2CMasterライブラリィ
|    下層レイア    |
+----------------+

下層レイア部分のソフトウェアは、USIのハードウェアやポートを直接弄る関数群です。これはがた老さんが書かれました。
I2Cのプロトコルは複雑で下層レイア部分のソフトウェアを組み合わせて実現します。
これが中層レイアのソフト群です。中層レイア部分に当たるソフトウェアは、デットロックしないよう考慮したI2Cデバイスの読み出し・書き込み関数と、レジスタ経由でデータの送受信を行うI2Cデバイス専用の関数で構成されてます。
これはばんとが書きました。

TinyI2CMasterライブラリィ関数説明

■void TinyI2C_Master_init( void )

機能: USIインタフェースの初期化(対応ポートも初期化)
引数: なし
戻値: なし

【補足説明】
プロジェクトで適切なMPU(ATtiny2313等)が選択されていれば、適切なポートが選択される。
対応MPUや対応ポートなどはヘッダファイルを参照するのこと。
ポートなどハードウェアを初期化する。詳細はソースを参照すること。

【分類】
下層レイアに含まれる関数

■uint8_t TinyI2C_start( void )

機能: スタートコンディション送信
引数: なし
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
I2Cバスにスタートコンディションを発行する。
詳細はソースを参照すること。

【分類】
下層レイアに含まれる関数

■uint8_t TinyI2C_stop( void )

機能: ストップコンディションの送信
引数: なし
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
I2Cバスにストップコンディションを発行する。
詳細はソースを参照すること。

【分類】
下層レイアに含まれる関数

■uint8_t TinyI2C_read( uint8_t more )

機能: I2Cのパスからの1バイト読み込み
引数: uint8_t more: more が MORE_READのときACK送信、それ以外はNACK送信
戻値: 読み込まれた1バイトのデータ

【補足説明】
I2Cのパスからの1バイト読み込みをする。更にデータを読み込むときにはACKを送信する。
詳細はソースを参照すること。

【分類】
下層レイアに含まれる関数

■uint8_t TinyI2C_write( uint8_t data )

機能: I2Cバスへの1バイト書き込み
引数: uint8_t data 書き込むデータ
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
詳細はソースを参照すること。

【分類】
下層レイアに含まれる関数

■uint8_t TinyI2C_Transfer( uint8_t data )

機能: USIインタフェースによるデータ送受信 8ビットも1ビットも同じ
引数: uint8_t data: 送受信データ
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
詳細はソースを参照すること。

【分類】
下層レイアに含まれる関数

■uint8_t TinyI2C_read_data(uint8_t slave_7bit_addr, void* data, int size, uint8_t send_stop )

機能: データ連続読み込み
引数: uint8_t slave_7bit_addr : ターゲットの7ビットアドレス
void* data : 読み込むデータ
int size : 読み込むデータサイズ
uint8_t send_stop : 非0なら読込後にSTOPコンディション送信する
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
I2Cプロトコルに従ってターゲットデバイスからデータを受信する。
リトライ3回(デフォルト)でデットロックを回避している。
詳細はソースを参照すること。

【分類】
中間レイアに含まれる関数

■uint8_t TinyI2C_write_data(uint8_t slave_7bit_addr, void* data, int size, uint8_t send_stop)

機能: データ連続書き込み
引数: uint8_t slave_7bit_addr : ターゲットの7ビットアドレス
void* data : 書き込むデータ
int size : 書き込むデータサイズ
uint8_t send_stop : 非0なら読込後にSTOPコンディション送信する
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
I2Cプロトコルに従ってターゲットデバイスにデータを送信する。
リトライ3回(デフォルト)でデットロックを回避している。
詳細はソースを参照すること。

【分類】
中間レイアに含まれる関数

■uint8_t TinyI2C_readReg( uint8_t slave_7bit_addr, uint8_t mem_addr, uint8_t *data )

機能: I2Cデバイスのレジスタ読み込み
引数: uint8_t slave_7bit_addr : ターゲットの7ビットアドレス
uint8_t mem_addr : レジスタのメモリアドレス
uint8_t* data : 読み込むデータ
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
レジスタアドレス送信すればレジスタデータが戻ってくるI2Cデバイス専用である。
詳細はソースを参照すること。

【分類】
中間レイアに含まれる関数

■uint8_t TinyI2C_masksetRegBit( uint8_t slave_7bit_addr, uint8_t mem_addr, uint8_t mask, uint8_t set_bit )

機能: レジスタマスク書き込み
引数: uint8_t slave_7bit_addr : ターゲットの7ビットアドレス
uint8_t mem_addr : レジスタのメモリアドレス
uint8_t mask : 設定するビットのマスクデータ
uint8_t set_bit : 設定データ
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
レジスタアドレス送信すればレジスタデータが戻ってくるI2Cデバイス専用である。
レジスタのマスクされた特定ビットのみを書き換えることができる。
詳細はソースを参照すること。

【分類】
中間レイアに含まれる関数

■uint8_t TinyI2C_setRegBit( uint8_t slave_7bit_addr, uint8_t mem_addr, uint8_t set_bit, uint8_t set_clear )

機能: 特定ビット設定
引数: uint8_t slave_7bit_addr : ターゲットの7ビットアドレス
uint8_t mem_addr : レジスタのメモリアドレス
uint8_t set_bit : 設定するビットの位置
uint8_t set_clear : 0ならビットクリア 非0ならビットセット
戻値: 0=正常終了 それ以外I2C通信エラー

【補足説明】
レジスタ経由でデータの送受信を行うI2Cデバイス専用の関数である。
レジスタアドレス送信すればレジスタデータが戻ってくるI2Cデバイス専用である。
レジスタの特定の1ビットのみを書き換えることができる。
詳細はソースを参照すること。

【分類】
中間レイアに含まれる関数

ドライバは各自が用意

I2Cプロトコルの規定はあるがI2Cデバイスの使い方には規定はない。
ハードウェアメーカが独自に実装しているので、各自がTinyI2CMasterの関数を用いてデバイスドライバを書く必要がある。

例題1 RTC8564ドライバ

リアルタイムクロックRTC8564は、レジスタを介して設定・時刻データの取得をする典型的なデバイスである。RTC8564は日本メーカー製なので、日本語のデータシート・アプリケーションノートが存在するので、全機能が使えるドライバを書いた。

データシート
http://www.epsondevice.com/docs/qd/ja/DownloadServlet?id=ID000711

アプリケーションノート
http://www.epsondevice.com/docs/qd/ja/DownloadServlet?id=ID000514

詳細はソースを見ていただきたい。

例題2 ST7032iドライバ

ST7032iはRTC8564のようなレジスタというものはない。ST7032iで表示させるにはHD44780と同じ制御コードで表示を行えるが、データモード・コマンドモードの信号をI2Cバス上に送ることにより表示する。

ST7032iドライバのソースは、壊れたXP環境からサルベージしたものである。
もしかしたら間違えがあるかもしれないのだが公開する。

まずはヘッダファイル(ST7032i.h)

#ifndef __ST7032I__H__
#define __ST7032I__H__

#include <stdbool.h>

#define ST7032I_ADDR	0x3E

//#define STRAWBERRY_LINUX_16x2_LCD
#undef STRAWBERRY_LINUX_16x2_LCD

#undef USE_ST7032I_INIT_PORT
#undef USE_ST7032I_WAKEUP

#ifdef USE_ST7032I_INIT_PORT
	#define ST7032i_WAKE_UP_DDR		DDRB
	#define ST7032i_WAKE_UP_DDR_NO	DDB0
	#define	ST7032i_WAKE_UP_PORT	PORTB
	#define	ST7032i_WAKE_UP_PORT_NO	PORTB1
#endif

//======= Command/flag defenitions =======
#define LCD_CLEARDISPLAY			0x01		// Command (HD44780)			Page 21
#define LCD_RETURNHOME				0x02		// Command (HD44780)

// flags for display entry mode
#define LCD_ENTRYMODESET			0x04		// Command (HD44780)
#define LCD_ENTRYSHIFTINCREMENT		0x01		// Setting (HD44780)*
#define LCD_ENTRYSHIFTDECREMENT		0x00		// Setting (HD44780)
#define LCD_ENTRYLEFT 				0x02		// Setting (HD44780)*
#define LCD_ENTRYRIGHT				0x00		// Setting (HD44780)

// flags for display on/off control
#define LCD_DISPLAYCONTROL			0x08		// Command (HD44780)			Page 22
#define LCD_DISPLAYON 				0x04		// Setting (HD44780)*
#define LCD_DISPLAYOFF 				0x00		// Setting (HD44780)
#define LCD_CURSORON 				0x02		// Setting (HD44780)
#define LCD_CURSOROFF 				0x00		// Setting (HD44780)*
#define LCD_BLINKON 				0x01		// Setting (HD44780)
#define LCD_BLINKOFF 				0x00		// Setting (HD44780)*

// flags for display/cursor shift
#define LCD_CURSORSHIFT				0x10		// Command (HD44780)

#define LCD_DISPLAYMOVE				0x08		// Setting (HD44780)
#define LCD_CURSORMOVE				0x00		// Setting (HD44780)
#define LCD_MOVERIGHT				0x04		// Setting (HD44780)
#define LCD_MOVELEFT				0x00		// Setting (HD44780)

#define LCD_FUNCTIONSET 			0x20		// Command (HD44780)			Page 23
#define LCD_INSTRUCTION_SET_BASIC	0x00		// Setting (ST7032)
#define LCD_INSTRUCTION_SET_EXTENDED 0x01		// Setting (ST7032)
#define LCD_2LINE					0x08		// Setting (HD44780)*
#define LCD_1LINE					0x00		// Setting (HD44780)
#define LCD_8BITMODE				0x10		// Setting (HD44780)*
//#define LCD_4BITMODE				0x00		// Setting (HD44780)	Not used in I2C mode
//#define LCD_5x10DOTS 				0x04		// Setting (HD44780)	Not supported by ST7032
#define LCD_5x8DOTS					0x00		// Setting (HD44780)*

#define LCD_SETCGRAMADDR			0x40		// Command (HD44780)			Page 24
#define LCD_SETDDRAMADDR			0x80		// Command (HD44780)

#define LCD_BIAS_OSC_CONTROL		0x10		// Command (ST7032)				Page 26
#define LCD_BIAS1_4 				0x08		// Setting (ST7032)
#define LCD_BIAS1_5 				0x00		// Setting (ST7032)*

// Internal frequency adjust for VDD = 3.0 V
#define LCD_OSC_122				0x00		// Setting (ST7032)
#define LCD_OSC_131				0x01		// Setting (ST7032)
#define LCD_OSC_144				0x02		// Setting (ST7032)
#define LCD_OSC_161				0x03		// Setting (ST7032)
#define LCD_OSC_183				0x04		// Setting (ST7032)
#define LCD_OSC_221				0x05		// Setting (ST7032)
#define LCD_OSC_274				0x06		// Setting (ST7032)
#define LCD_OSC_347				0x07		// Setting (ST7032)

// Internal frequency adjust for VDD = 5.0 V
#define LCD_OSC_120				0x00		// Setting (ST7032)
#define LCD_OSC_133				0x01		// Setting (ST7032)
#define LCD_OSC_149				0x02		// Setting (ST7032)
#define LCD_OSC_167				0x03		// Setting (ST7032)
#define LCD_OSC_192				0x04		// Setting (ST7032)*
#define LCD_OSC_227				0x05		// Setting (ST7032)
#define LCD_OSC_277				0x06		// Setting (ST7032)
#define LCD_OSC_347				0x07		// Setting (ST7032)

#define ICON_RAMADDRESSSET			0x40		// Command (ST7032)

#define LCD_ICON_CONTRAST_HIGH_BYTE	0x50		// Command (ST7032)
#define LCD_ICON_ON					0x08		// Setting (ST7032)
#define LCD_ICON_OFF				0x00		// Setting (ST7032)
#define LCD_BOOSTER_ON				0x04		// Setting (ST7032)*
#define LCD_BOOSTER_OFF				0x00		// Setting (ST7032)
#define LCD_CONTRAST_HIGH_BYTE_MASK	0x03		// Only used for bit masking (ST7032)

#define LCD_FOLLOWER_CONTROL		0x60		// Command (ST7032)				Page 27
#define LCD_FOLLOWER_ON				0x08		// Setting (ST7032)*
#define LCD_FOLLOWER_OFF			0x00		// Setting (ST7032)
#define LCD_Rab_1_00				0x00		// Setting (ST7032)
#define LCD_Rab_1_25				0x01		// Setting (ST7032)
#define LCD_Rab_1_50				0x02		// Setting (ST7032)
#define LCD_Rab_1_80				0x03		// Setting (ST7032)
#define LCD_Rab_2_00				0x04		// Setting (ST7032)*
#define LCD_Rab_2_50				0x05		// Setting (ST7032)
#define LCD_Rab_3_00				0x06		// Setting (ST7032)
#define LCD_Rab_3_75				0x07		// Setting (ST7032)

#define LCD_CONTRAST_LOW_BYTE			0x70		// Command (ST7032)
#define LCD_CONTRAST_LOW_BYTE_MASK		0x0F		// Only used for bit masking (ST7032)

#define ST7032_NUM_LINES 			2

//======= End of command/flag defenitions =======

/*======================================*/
/*  関数定義					        */
/*======================================*/
extern uint8_t ST7032i_Write( uint8_t data, uint8_t mode );
extern void ST7032i_Init( void );
extern void ST7032i_Clear( void );
extern void ST7032i_Home( void );
extern void ST7032i_setCursor(uint8_t col, uint8_t row);
extern void ST7032i_onDisplay( void );
extern void ST7032i_offDisplay( void );
extern void ST7032i_onCursor( void );
extern void ST7032i_offCursor( void );
extern void ST7032i_onBlink( void );
extern void ST7032i_offBlink( void );
extern void ST7032i_scrollDisplayLeft( void );
extern void ST7032i_scrollDisplayRight( void );
extern void ST7032i_rightToLeft( void );
extern void ST7032i_onAutoscroll( void );
extern void ST7032i_offAutoscroll( void );
extern void ST7032i_createChar(uint8_t location, uint8_t charmap[]);
extern void ST7032i_setContrast(uint8_t new_val);
extern void ST7032i_puts(const char *s);
extern void ST7032i_puts_p(const char *progmem_s);

#define ST7032i_WriteCmd(data)		ST7032i_Write(data,0x00)
#define ST7032i_WriteData(data)		ST7032i_Write(data,0x40)
#define ST7032i_putc(data)			ST7032i_Write(data,0x40)

#ifdef STRAWBERRY_LINUX_16x2_LCD
extern void ST7032i_Icon( uint8_t icon, bool flag );
extern void ST7032i_Power_Icon(uint8_t power, bool flag);

#define ST7032i_ANTENA_Icon(flag)	ST7032i_Icon(0, flag)
#define ST7032i_Tel_Icon(flag)		ST7032i_Icon(1, flag)
#define ST7032i_Denpa_Icon(flag)	ST7032i_Icon(2, flag)
#define ST7032i_ExitPower_Icon(flag)	ST7032i_Icon(3, flag)
#define ST7032i_Up_Icon(flag)		ST7032i_Icon(4, flag)
#define ST7032i_Down_Icon(flag)		ST7032i_Icon(5, flag)
#define ST7032i_KeyLock_Icon(flag)	ST7032i_Icon(6, flag)
#define ST7032i_Mute_Icon(flag)		ST7032i_Icon(7, flag)
#define ST7032i_Coin_Icon(flag)		ST7032i_Icon(8, flag)
#endif

#endif

そしてソースファイル(ST7032i.c)

//=============================================================================
// File Name    : ST7032i.c
//
// Title        : ST7032i I2C LCD ドライバ
// Revision     : 0.1
// Notes        :
// Target MCU   : AVR ATtiny
// Tool Chain   :
//
// Revision History:
// When         Who         Description of change
// -----------  ----------- -----------------------
// 2013/02/06   ばんと      修正完了
//=============================================================================

/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "delay.h"
#include "ST7032i.h"
#include "TinyI2CMaster.h"

/* local typedef -------------------------------------------------------------*/
//アイコンのアドレスとビットの関係
#ifdef STRAWBERRY_LINUX_16x2_LCD
typedef struct
{
    uint8_t adr;
    uint8_t data;
} T_ICON;
#endif

/* local define --------------------------------------------------------------*/
/* local macro ---------------------------------------------------------------*/
/* local variables -----------------------------------------------------------*/
uint8_t _display_basic;
uint8_t _display_extended;
uint8_t _displaymode;
uint8_t _displaycontrol;
uint8_t _rab;

#ifdef STRAWBERRY_LINUX_16x2_LCD
const uint8_t Icon_Table[9][2] =
{
    {0x00, 0b10000},
    {0x02, 0b10000},
    {0x04, 0b10000},
    {0x06, 0b10000},
    {0x07, 0b10000},
    {0x07, 0b01000},
    {0x09, 0b10000},
    {0x0B, 0b10000},
    {0x0F, 0b10000}
};
#endif

/* local function prototypes -------------------------------------------------*/

/*======================================*/
/*  ST7032i 書き込み関数				*/
/*======================================*/
uint8_t ST7032i_Write( uint8_t data, uint8_t mode )
{
    uint8_t buf[2];

    buf[0] = mode;				// モード
    buf[1] = data;				// データ

    return TinyI2C_write_data(ST7032I_ADDR, buf, sizeof(buf), SEND_STOP));
}


/*======================================*/
/*  ST7032i ポート初期化関数			*/
/*======================================*/
#ifdef USE_ST7032I_INIT_PORT
void ST7032i_InitPort( void )
{
    ST7032i_WAKE_UP_DDR = _BV(ST7032i_WAKE_UP_DDR_NO);		//
    ST7032i_WAKE_UP_PORT &= ~_BV(ST7032i_WAKE_UP_PORT_NO);	//

    wait_ms(1);
}
#endif

/*======================================*/
/*  ST7032i ウェイクアップ関数			*/
/*======================================*/
#ifdef USE_ST7032I_WAKEUP
void ST7032i_WakeUp( void )
{
    ST7032i_WAKE_UP_PORT &= ~_BV(ST7032i_WAKE_UP_PORT_NO);
    wait_ms(1);

    ST7032i_WAKE_UP_PORT |= _BV(ST7032i_WAKE_UP_PORT_NO);
    wait_ms(10);
}
#endif

/*======================================*/
/*  ST7032i 初期化関数                  */
/*======================================*/
void ST7032i_Init( void )
{
    uint8_t contrast = 45;

    _display_basic = LCD_INSTRUCTION_SET_BASIC | LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
    _display_extended = LCD_INSTRUCTION_SET_EXTENDED | LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
    _displaycontrol = LCD_DISPLAYON;
    _display_basic |= LCD_2LINE;
    _display_extended |= LCD_2LINE;

#ifdef USE_ST7032I_INIT_PORT
    ST7032i_InitPort( );
#endif

#ifdef USE_ST7032I_WAKEUP
    ST7032i_WakeUp( );
#endif
    wait_ms(40);

    // function set  basic
    ST7032i_WriteCmd(LCD_FUNCTIONSET | _display_basic );
    wait_ms(30);

    // function set extended
    ST7032i_WriteCmd(LCD_FUNCTIONSET | _display_extended);
    wait_ms(30);

    // interval osc
    ST7032i_WriteCmd(LCD_BIAS_OSC_CONTROL | LCD_BIAS1_5 | LCD_OSC_192);
    wait_ms(30);

    // contrast low nible
    ST7032i_WriteCmd(LCD_CONTRAST_LOW_BYTE | (contrast & LCD_CONTRAST_LOW_BYTE_MASK));
    wait_ms(30);

    // contrast high nible / icon / power
    ST7032i_WriteCmd(LCD_ICON_CONTRAST_HIGH_BYTE | LCD_ICON_ON | LCD_BOOSTER_ON | (contrast >> 4 & LCD_CONTRAST_HIGH_BYTE_MASK));
    wait_ms(30);

    // follower control
    _rab = LCD_Rab_2_00;
    ST7032i_WriteCmd(LCD_FOLLOWER_CONTROL | LCD_FOLLOWER_ON | _rab);
    wait_ms(200);

    // function set basic
    ST7032i_WriteCmd(LCD_FUNCTIONSET | _display_basic);
    wait_ms(30);

    // display on
    ST7032i_WriteCmd(LCD_DISPLAYCONTROL |  LCD_DISPLAYON |  LCD_CURSOROFF | LCD_BLINKOFF );
    wait_ms(30);

    // entry mode set
    _displaymode=LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
    ST7032i_WriteCmd(LCD_ENTRYMODESET | _displaymode);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i 画面消去関数                */
/*======================================*/
void ST7032i_Clear( void )
{
    ST7032i_WriteCmd(LCD_CLEARDISPLAY);
    wait_ms(2);
}

/*======================================*/
/*  ST7032i ホームポジション関数		*/
/*======================================*/
void ST7032i_Home( void )
{
    ST7032i_WriteCmd(LCD_RETURNHOME);  // set cursor position to zero
    wait_ms(2);  // this command takes a long time!
}

/*======================================*/
/*  ST7032i カーソル表示関数			*/
/*======================================*/
void ST7032i_setCursor(uint8_t col, uint8_t row)
{
    int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };

    if ( row > ST7032_NUM_LINES )
    {
        row = ST7032_NUM_LINES - 1;    // we count rows starting w/0
    }
    ST7032i_WriteCmd(LCD_SETDDRAMADDR | (col + row_offsets[row]));
    wait_ms(30);
}

/*======================================*/
/*  ST7032i 表示オン関数		        */
/*======================================*/
void ST7032i_onDisplay( void )
{
    _displaycontrol |= LCD_DISPLAYON;
    ST7032i_WriteCmd(LCD_DISPLAYCONTROL | _displaycontrol);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i 表示オフ関数		        */
/*======================================*/
void ST7032i_offDisplay( void )
{
    _displaycontrol &= ~LCD_DISPLAYON;
    ST7032i_WriteCmd(LCD_DISPLAYCONTROL | _displaycontrol);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i カーソルオン関数	        */
/*======================================*/
void ST7032i_onCursor( void )
{
    _displaycontrol |= LCD_CURSORON;
    ST7032i_WriteCmd(LCD_DISPLAYCONTROL | _displaycontrol);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i カーソルオフ関数	        */
/*======================================*/
void ST7032i_offCursor( void )
{
    _displaycontrol &= ~LCD_CURSORON;
    ST7032i_WriteCmd(LCD_DISPLAYCONTROL | _displaycontrol);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i ブリンクオン関数	        */
/*======================================*/
void ST7032i_onBlink( void )
{
    _displaycontrol |= LCD_BLINKON;
    ST7032i_WriteCmd(LCD_DISPLAYCONTROL | _displaycontrol);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i ブリンクオフ関数	        */
/*======================================*/
void ST7032i_offBlink( void )
{
    _displaycontrol &= ~LCD_BLINKON;
    ST7032i_WriteCmd(LCD_DISPLAYCONTROL | _displaycontrol);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i 左スクロール関数	        */
/*======================================*/
// These commands scroll the display without changing the RAM
void ST7032i_scrollDisplayLeft( void )
{
    ST7032i_WriteCmd(LCD_FUNCTIONSET | _display_basic);
    wait_ms(30);

    ST7032i_WriteCmd(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i 右スクロール関数	        */
/*======================================*/
void ST7032i_scrollDisplayRight( void )
{
    ST7032i_WriteCmd(LCD_FUNCTIONSET | _display_basic);
    wait_ms(30);

    ST7032i_WriteCmd(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i 左→右・文字あふれ関数		*/
/*======================================*/
// This is for text that flows Left to Right
void ST7032i_leftToRight( void )
{
    _displaymode |= LCD_ENTRYLEFT;
    ST7032i_WriteCmd(LCD_ENTRYMODESET | _displaymode);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i 右→左・文字あふれ関数		*/
/*======================================*/
// This is for text that flows Right to Left
void ST7032i_rightToLeft( void )
{
    _displaymode &= ~LCD_ENTRYLEFT;
    ST7032i_WriteCmd(LCD_ENTRYMODESET | _displaymode);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i オートスクロール・オン関数	*/
/*======================================*/
// This will 'right justify' text from the cursor
void ST7032i_onAutoscroll( void )
{
    _displaymode |= LCD_ENTRYSHIFTINCREMENT;
    ST7032i_WriteCmd(LCD_ENTRYMODESET | _displaymode);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i オートスクロール・オフ関数	*/
/*======================================*/
// This will 'left justify' text from the cursor
void ST7032i_offAutoscroll( void )
{
    _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
    ST7032i_WriteCmd(LCD_ENTRYMODESET | _displaymode);
    wait_ms(30);
}

/*======================================*/
/*  ST7032i ユーザ文字作成関数			*/
/*======================================*/
// Allows us to fill the first 8 CGRAM locations with custom characters
void ST7032i_createChar(uint8_t location, uint8_t charmap[])
{
    int i;

    location &= 0x7; // we only have 8 locations 0-7
    ST7032i_WriteCmd(LCD_SETCGRAMADDR | (location << 3));
    wait_ms(30);

    for (i=0; i<8; i++)
    {
        ST7032i_WriteData(charmap[i]);
        wait_ms(30);
    }
}

/*======================================*/
/*  ST7032i コントラスト設定関数		*/
/*======================================*/
void ST7032i_setContrast(uint8_t new_val)
{
    ST7032i_WriteCmd(LCD_FUNCTIONSET | _display_extended);
    wait_ms(30);	//Needed ??

    ST7032i_WriteCmd(LCD_ICON_CONTRAST_HIGH_BYTE | LCD_ICON_ON | LCD_BOOSTER_ON | (new_val >> 4 & LCD_CONTRAST_HIGH_BYTE_MASK));
    wait_ms(30);

    ST7032i_WriteCmd(LCD_CONTRAST_LOW_BYTE | (new_val & LCD_CONTRAST_LOW_BYTE_MASK));
    wait_ms(30);
}

/*======================================*/
/*  文字例出力関数                      */
/*======================================*/
void ST7032i_puts(const char *s)
{
    register char c;

    while ((c = *s++))
    {
        ST7032i_WriteData(c);
    }
}

/*======================================*/
/*  文字例出力関数2						*/
/*======================================*/
void ST7032i_puts_p(const char *progmem_s)
/* print string from program memory on lcd (no auto linefeed) */
{
    register char c;

    while ( (c = pgm_read_byte(progmem_s++)) )
    {
        ST7032i_WriteData(c);
    }

}/* lcd_puts_p */

#ifdef STRAWBERRY_LINUX_16x2_LCD
/*======================================*/
/*  アイコン表示関数					*/
/*======================================*/
/**
  * @brief  Put icon. value is to be 0 - 12
  * @param  numbet : icon number
  * @retval None
  */
void ST7032i_Icon(uint8_t number, bool flag)
{
    ST7032i_WriteCmd(0b00111001);	// コマンド

    //icon address set
    ST7032i_WriteCmd(0b01000000 | Icon_Table[number][0] );

    if(flag)
    {
        //icon data set
        ST7032i_WriteData(Icon_Table[number][1]);
    }
    else
    {
        //icon data reset
        ST7032i_WriteData(0x00);
    }
    ST7032i_WriteCmd(0b00111000);	//
}

/*======================================*/
/*  電源アイコン表示関数				*/
/*======================================*/
void ST7032i_Power_Icon(uint8_t power, bool flag)
{
    uint8_t tmp;

    tmp = 0b00010;	// 枠
    switch(power)
    {
    case 0:
        break;
    case 1:
        tmp |= 0b10000;
        break;
    case 2:
        tmp |= 0b11000;
        break;
    case 3:
        tmp |= 0b11100;
        break;
    default:
        break;
    }

    ST7032i_WriteCmd(0b00111001);	// コマンド
    //icon address set
    ST7032i_WriteCmd(0b01000000 | 0x0D );
    //icon data set
    if(flag)
    {
        ST7032i_WriteData(tmp);
    }
    else
    {
        ST7032i_WriteData(0x00);
    }
    ST7032i_WriteCmd(0b00111000);	//
}
#endif

応用

RTC8564ドライバとST7032iドライバを使うなら、以下のように書けば動くだろう。

#include <avr/io.h>
#include "TinyI2CMaster.h"
#include "ST7032i.h"
#include "RTC8564.h"
#include "delay.h"

int main(void)
{
    char buf[10];
    RTC_TIME rtc_time;

    TinyI2C_Master_init();
    ST7032i_Init();
    ST7032i_setContrast(30);

    RTC8564_backup_return();

    ST7032i_setCursor(0,0);
    ST7032i_puts("TEST!");

    /* 時刻合わせ */
    rtc_time.year = 2013;
    rtc_time.month = 10;
    rtc_time.day = 8;
    rtc_time.hour = 11;
    rtc_time.min = 5;
    rtc_time.sec = 0;
    RTC8564_adjust( &rtc_time );

    while(1)
    {
        //TODO:: Please write your application code

        RTC8564_now(&rtc_time);

        xsprintf_p(buf,PSTR("%02d-%02d-%02d"), rtc_time.year-2000, rtc_time.month, rtc_time.day );
        ST7032i_setCursor(0, 0);
        ST7032i_puts(buf);

        xsprintf_p(buf,PSTR("%02d:%02d:%02d"), rtc_time.hour, rtc_time.min, rtc_time.sec );
        ST7032i_setCursor(0, 1);
        ST7032i_puts(buf);

        wait_sec(1);
    }
}

ライブラリィのダウンロード先

AVR Tiny用 I2Cマスタライブラリィ (1916 ダウンロード)