-
Notifications
You must be signed in to change notification settings - Fork 0
/
skI2CLCDlib.c
396 lines (384 loc) · 20.3 KB
/
skI2CLCDlib.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
/*******************************************************************************
* skI2CLCDlib - I2C接続LCD関数ライブラリ *
* ST7032iのコントローラ(8文字x2行/16文字x2行)タイプならOKです。 *
* *
* LCD_Init - LCDの初期化を行う処理 *
* LCD_Clear - LCDモジュールの画面を消し初期状態に戻す処理 *
* LCD_SetCursor - LCDモジュール画面内のカーソル位置を移動する処理 *
* LCD_Putc - LCDにデータを1バイト出力する処理 *
* LCD_Puts - LCDに文字列データを出力する処理 *
* LCD_CreateChar - オリジナルのキャラクタを登録します *
* (以下はVr2.00にて追加) *
* LCD_Contrast - LCDのコントラスト調整を行う処理 *
* LCD_IconClear - 全部のアイコン表示を消す処理 *
* LCD_IconOnOff - 指定アイコンの表示ON/OFFを行う処理 *
* LCD_PageSet - ページ画面の切り替えを行う処理 *
* LCD_PageClear - 現在表示中のページ画面内の消去を行う処理 *
* LCD_PageSetCursor - 現在表示中のページ画面内でのカーソル設定を行う処理 *
* LCD_PageNowNo - 現在表示中のページ画面番号を返す処理 *
* *
* メモ:__delay_us() and __delay_ms() を使用しているので "skI2CLCDlib.h" に *
* "#define _XTAL_FREQ 8000000"が記述されています、 *
* 8MHz以外のCPUクロックにする人は書き換えましょう。 *
* ============================================================================ *
* VERSION DATE BY CHANGE/COMMENT *
* ---------------------------------------------------------------------------- *
* 1.00 2013-07-25 きむ茶工房(きむしげ) Create *
* 1.01 2014-08-29 きむ茶工房(きむしげ) 18F25K22でも動作(delay_msの所変更)*
* 1.02 2015-02-02 きむ茶工房(きむしげ) 64MHzまで対応((delay_msの所変更) *
* 2.00 2015-03-01 きむ茶工房(きむしげ) ST7032iコントローラLCDに対応 *
* ============================================================================ *
* PIC 12F1822 16F1827 18F25K22 (このライブラリ自体は他のPICでもOKと思います) *
* MPLAB IDE(V8.63) MPLAB X(v2.15) *
* MPLAB(R) XC8 C Compiler Version 1.00/1.32 *
*******************************************************************************/
#include "mcc_generated_files/mcc.h"
#include <xc.h>
#include "skI2Clib.h"
#include "skS11059-02DT.h"
#include "skI2CLCDlib.h"
#include "My_I2C.h"
static int LCD_ColumnSu ; // 制御対象LCDの表示可能文字数(8/16)
static int LCD_NowPage ; // 現在表示中ページ画面の番号を保存する変数
static unsigned int FuncSet_DT ; // "function set"のコマンド設定内容
static unsigned int ContSet_DT ; // "Contrast set"のコマンド設定内容
// 指定数値 x 10ms 程待つ
void Wait10ms(unsigned int num)
{
do {
__delay_ms(10) ; // 10msプログラムの一時停止
} while(--num != 0);
}
// 約27us程待つ
void Wait27us(void)
{
__delay_us(30) ;
}
// LCDにコマンドを発行する処理
void LCD_Command(unsigned char c)
{
// I2C1_Write1ByteRegister(ST7032_ADRES, 0x00, c);
// if (c & 0xFC) // 上位6ビットに1がある命令の場合
// __delay_us(30); // >26.3us
// else
// __delay_ms(2); // >1.08ms ClearおよびHomeコマンド
int ans ;
ans = I2C_Start(ST7032_ADRES,RW_0); // スタートコンディションを発行する
if (ans == 0) {
// command word の送信
I2C_Send(0b10000000) ; // control byte の送信(コマンドを指定)
I2C_Send(c) ; // data byte の送信
}
I2C_Stop() ; // ストップコンディションを発行する
__delay_us(30); // >26.3us
// I2C_SSPCON1= 0x08;
}
/*******************************************************************************
* LCD_Clear( ) *
* LCDモジュールの画面を消し初期状態に戻す処理 *
* 全てのDisplay Data RAM(2x40byte)に20Hのスペースを書き込みます。 *
* ページ画面も初期状態に戻す *
*******************************************************************************/
void LCD_Clear(void)
{
LCD_Command(0x01) ; // Clear Display : 画面全体に20Hのスペースで表示、カーソルはcol=0,row=0に移動
__delay_us(1100) ; // LCDが処理(1.08ms)するのを待ちます
LCD_Command(0x02) ; // Return Home : 画面を初期ポジションに戻す
__delay_us(1100) ; // LCDが処理(1.08ms)するのを待ちます
LCD_NowPage = 0 ; // 初期ページ画面は0ページとする
__delay_ms(5);
}
/*******************************************************************************
* LCD_SetCursor(col,row) *
* LCDモジュール画面内のカーソル位置を移動する処理 *
* 実際のDisplay Data RAMは2x40byteのエリアが有ります。(但し2-line display) *
* 指定位置の数値データ内容チェックは行っていないので数値は正しく設定する事。*
* *
* col : 横(列)方向のカーソル位置(0-39) *
* row : 縦(行)方向のカーソル位置(0-1) *
*******************************************************************************/
void LCD_SetCursor(int col, int row)
{
int row_offsets[] = { 0x00, 0x40 } ;
LCD_Command(0x80 | (col + row_offsets[row])) ; // Set DDRAM Adddress : 00H-27H,40H-67H
}
/*******************************************************************************
* LCD_Putc(c) *
* LCDにデータを1バイト出力する処理 *
* *
* c : 出力する文字データを指定 *
*******************************************************************************/
void LCD_Putc(char c)
{
// I2C1_Write1ByteRegister(ST7032_ADRES, 0x40, c); //RS=1
// __delay_us(30); // >26.3us
int ans ;
// printf("4-1\r\n");
ans = I2C_Start(ST7032_ADRES,RW_0); // スタートコンディションを発行する
// printf("4-2\r\n");
if (ans == 0) {
// command word の送信
I2C_Send(0b01000000) ; // control byte の送信(データを指定)
I2C_Send(c) ; // data byte の送信
}
I2C_Stop() ; // ストップコンディションを発行する
__delay_us(30); // >26.3us
}
/*******************************************************************************
* LCD_PutChar(c) *
* LCDに登録したCHARを出力する処理 *
* *
* c : 出力する登録CHARを指定 *
*******************************************************************************/
void LCD_PutChar(char c)
{
int ans ;
// I2C_SSPCON1= 0x28;
ans = I2C_Start(ST7032_ADRES,RW_0); // スタートコンディションを発行する
if (ans == 0) {
// command word の送信
I2C_Send(0b11000000) ; // control byte の送信(データを指定)
I2C_Send(c) ; // data byte の送信
}
I2C_Stop() ; // ストップコンディションを発行する
Wait27us() ;
// I2C_SSPCON1= 0x08;
}
/*******************************************************************************
* LCD_Puts(*s) *
* LCDに文字列データを出力する処理 *
* 文字列は、NULL(0x00)まで繰返し出力します。 *
* *
* *s : 出力する文字列のデータを格納した場所のアドレスを指定 *
*******************************************************************************/
void LCD_Puts(const char * s)
{
//// while (*s) //文字列の終わり(00)まで継続
//// LCD_Putc(*s++); //文字出力しポインタ+1
int ans ;
// I2C_SSPCON1= 0x28;
// I2C_SSPIE = 1 ; // SSP(I2C)割り込みを許可する
// I2C_BCLIE = 1 ; // MSSP(I2C)バス衝突割り込みを許可する
// I2C_SSPIF = 0 ; // SSP(I2C)割り込みフラグをクリアする
// I2C_BCLIF = 0 ; // MSSP(I2C)バス衝突割り込みフラグをクリアする
ans = I2C_Start(ST7032_ADRES,RW_0); // スタートコンディションを発行する
if (ans == 0) {
I2C_Send(0b01000000) ; // control byte の送信(データを指定)
while(*s) {
I2C_Send(*s++) ; // data byte の送信(連続送信)
__delay_ms(10);
}
}
I2C_Stop() ; // ストップコンディションを発行する
// I2C_SSPCON1= 0x08;
}
/*******************************************************************************
* LCD_CreateChar(p,*dt) *
* オリジナルのキャラクタを登録します *
* *
* p : 登録する場所の指定(0~5の6ヶ所のみ)(LCDによっては0-15の16ヶ所有) *
* *dt : 登録したいキャラクタのデータを格納したバッファを指定 *
********************************************************************************/
void LCD_CreateChar(int p,char *dt)
{
int x ;
x = I2C_Start(ST7032_ADRES,RW_0); // スタートコンディションを発行する
if (x == 0) {
// LCDにキャラ保存先のアドレスを指示する
I2C_Send(0b10000000) ; // control byte の送信(コマンドを指定)
I2C_Send(0x40 | (p << 3)) ;
Wait27us() ;
// LCDにキャラデータを送信する
I2C_Send(0b01000000) ; // control byte の送信(データを指定)
for (x=0; x < 7; x++) {
I2C_Send(*dt++) ;
Wait27us() ;
}
}
I2C_Stop() ; // ストップコンディションを発行する
// I2C_SSPCON1= 0x08;
}
/*******************************************************************************
* LCD_IconClear( ) *
* 全部のアイコン表示を消す処理(アイコン対応LCDのみ) *
*******************************************************************************/
void LCD_IconClear(void)
{
int x ;
// 拡張コマンドの設定を有効にする
LCD_Command(0x39) ;
x = I2C_Start(ST7032_ADRES,RW_0); // スタートコンディションを発行する
if (x == 0) {
// LCDのアイコンアドレスを指示する
I2C_Send(0b10000000) ; // control byte の送信(コマンドを指定)
I2C_Send(0x40) ; // data byte の送信
Wait27us() ;
// アイコンのデータビットを指定する
I2C_Send(0b01000000) ; // control byte の送信(データを指定)
for (x=0x40 ; x<0x50 ; x++) {
I2C_Send(0x00) ;
Wait27us() ;
}
}
I2C_Stop() ; // ストップコンディションを発行する
// 拡張コマンドを設定を無効にする
LCD_Command(FuncSet_DT) ;
}
/*******************************************************************************
* LCD_IconOnOff(flag,dt) *
* 指定アイコンの表示ON/OFFを行う処理(アイコン対応LCDのみ) *
* 消すのはアドレス単位で全て消去、例えば△▽を表示していれば両方消えます。 *
* *
* flag : 指定したアイコンの表示をするしない(1=ON 0=OFF) *
* dt : アイコンのアドレスとビットを指定します *
* "skI2CLCDlib.hのdefine宣言で指定します。 *
*******************************************************************************/
void LCD_IconOnOff(int flag, unsigned int dt)
{
int ans ;
// 拡張コマンドの設定を有効にする
LCD_Command(0x39) ;
ans = I2C_Start(ST7032_ADRES,RW_0); // スタートコンディションを発行する
if (ans == 0) {
// LCDのアイコンアドレスを指示する
I2C_Send(0b10000000) ; // control byte の送信(コマンドを指定)
I2C_Send(dt >> 8) ; // data byte の送信
Wait27us() ;
// アイコンのデータビットを指定する
I2C_Send(0b11000000) ; // control byte の送信(データを指定)
if (flag == 1) I2C_Send(dt & 0x00FF) ;
else I2C_Send(0x00) ;
}
I2C_Stop() ; // ストップコンディションを発行する
Wait27us() ;
// 拡張コマンドを設定を無効にする
LCD_Command(FuncSet_DT) ;
}
/*******************************************************************************
* ans = LCD_PageSet(no) *
* ページ画面の切り替えを行う処理 *
* *
* no : 表示するページ画面の番号を指定(8x2なら0-4/16x2なら0-1) *
* ans : 0=正常 -1=指定したページページ番号がおかしい *
*******************************************************************************/
int LCD_PageSet(int no)
{
int ans, c , c2 ;
ans = -1 ;
if (LCD_NowPage != no) { // 指定ページと現在のページが異なるなら処理する
// 指定ページの先頭DDRAM位置を計算する
c = no * LCD_ColumnSu ;
// 指定ページ - 現在ページ の差は?
c2 = c - (LCD_NowPage * LCD_ColumnSu) ;
if (c < (40/LCD_ColumnSu)*LCD_ColumnSu) { // 指定ページは有効範囲なら処理する
if (c2 > 0) {
// 右方向に差の分だけ画面をシフトさせる
for (c=0 ; c < c2 ; c++) LCD_Command(0x18) ;
} else {
// 左方向に差の分だけ画面をシフトさせる
c2 = c2 * -1 ;
for (c=0 ; c < c2 ; c++) LCD_Command(0x1C) ;
}
LCD_NowPage = no ; // 指定ページ画面の番号を保存する
ans = 0 ;
}
}
return ans ;
}
/*******************************************************************************
* LCD_PageClear( ) *
* 現在表示中のページ画面内の消去を行う処理 *
*******************************************************************************/
void LCD_PageClear(void)
{
int c , i ;
// 現在ページの先頭DDRAM位置を計算する
c = LCD_NowPage * LCD_ColumnSu ;
// 1行目を消す
LCD_SetCursor(c, 0) ;
for (i=0 ; i < LCD_ColumnSu ; i++) {
LCD_Putc(0x20) ;
}
// 2行目を消す
LCD_SetCursor(c, 1) ;
for (i=0 ; i < LCD_ColumnSu ; i++) {
LCD_Putc(0x20) ;
}
LCD_SetCursor(c, 0) ;
}
/*******************************************************************************
* LCD_PageSetCursor(col,row) *
* 現在表示中のページ画面内でのカーソル設定を行う処理 *
* 指定位置の数値データ内容チェックは行っていないので数値は正しく設定する事。*
* *
* col : 横(列)方向のカーソル位置(8x2なら0-7/16x2なら0-15) *
* row : 縦(行)方向のカーソル位置(0-1) *
*******************************************************************************/
void LCD_PageSetCursor(int col, int row)
{
LCD_SetCursor((LCD_NowPage * LCD_ColumnSu) + col, row) ;
}
/*******************************************************************************
* ans = LCD_PageNowNo() *
* 現在表示中のページ画面番号を返す処理 *
* *
* ans : ページ画面番号を返します(8x2なら0-4/16x2なら0-1) *
*******************************************************************************/
int LCD_PageNowNo(void)
{
return LCD_NowPage ;
}
/*******************************************************************************
* LCD_Contrast(contrast) *
* LCDのコントラスト調整を行う処理 *
* *
* contrast : LCDのコントラストを指定します(0-63) *
*******************************************************************************/
void LCD_Contrast(int contrast)
{
// 拡張コマンドの設定を有効にする
LCD_Command(0x39) ;
// コントラストの下位4ビット
LCD_Command(0x70 | (contrast & 0x0F)) ;
// コントラストの上位2ビット
ContSet_DT = (ContSet_DT & 0xFC) | ((contrast & 0x30) >> 4) ;
LCD_Command(ContSet_DT) ;
// 拡張コマンドを設定を無効にする
LCD_Command(FuncSet_DT) ;
}
/*******************************************************************************
* LCD_Init(icon,contrast,bon,colsu) *
* LCDの初期化を行う処理 *
* *
* icon : アイコンを使用するのかを指定します(1=使う 0=使わない) *
* contrast : LCDのコントラストを指定します(0-63) *
* bon : 昇圧回路の利用有無 1:ON(VDD=3.3V) 0:OFF(VDD=5.0V) *
* colsu : LCDの表示可能文字数を指定します(8/16) *
*******************************************************************************/
void LCD_Init_ST7032i(int icon, int contrast, int bon, int colsu)
//LCD_Init_ST7032i(0,50,1,16);
{
unsigned int d ;
LCD_ColumnSu = colsu ; // LCDの文字数をセット
__delay_ms(50); // 電源ON後40msまで待ってから初期化
FuncSet_DT = 0x38 ;
LCD_Command(FuncSet_DT);// function set : データ線は8本・表示は2行・フォントは5x8ドット
LCD_Command(0x39) ; // function set : 拡張コマンドの設定を有効にする
LCD_Command(0x14) ; // Internal OSC frequency : バイアスの選択と内部OSC周波数の調整
d = 0x70;// | (contrast & 0x0F) ; // (下位4ビット)の取り出し
LCD_Command(d) ; // Contrast set : コントラスト調整データ
d = 0x50 | ((contrast & 0x30) >> 4) ; // (上位2ビット)の取り出し
if (icon == 1) d = d | 0x08 ; // アイコンを利用する場合
if (bon == 1) d = d | 0x04 ; // 昇圧回路を利用する場合
ContSet_DT = d ;
LCD_Command(ContSet_DT) ; // Contrast set : 昇圧回路、コントラスト調整データ
LCD_Command(0x6C) ; // Follower control : フォロア回路をON、増幅率の調整を行う
__delay_ms(200); // 電力が安定するまで待つ(200ms)
LCD_Command(FuncSet_DT);// function set : 拡張コマンドを設定を無効にする
LCD_Command(0x01) ;
LCD_Command(0x0C) ; // display control : 画面表示はON・カーソル表示はOFF・カーソル点滅はOFF
// LCD_Command(0x06) ; // entry mode set : 文字を表示した次にカーソルを移動するを指示
// LCD_Clear() ; // Clear Display : 画面を消去する、初期状態に戻す
//
// LCD_Clear() ; // Clear Display : 画面を消去する、初期状態に戻す
}