Skin:
[NORMAL]
[BLUE] [DOS] [LIGHT]  / コピーするための表示 / 実行
このファイル: /home/web6047/www/cgi-bin/prj/photos of index/20200809-/softwarei2c.c
1 //もとのプログラムの作成者 mit.ueno 様
2
3 #include "pic.h"
4 // CONFIG1
5 //http://rikei60.web.fc2.com/toybox/sokkyo/16F88conf.htm
6 //#pragma config FOSC = INTOSCIO //内部クロック発振。RA6,7は通常の入出力ポート。
7 #pragma config WDTE = OFF //暴走自動停止なし。
8 //#pragma config PWRTE = ON //電源立ち上げ時遅延スタートあり
9 //#pragma config MCLRE = ON //RA5はMCLR機能で、負パルスでリセット
10 //#pragma config BOREN = ON //電圧低下(>4V)リセット許可
11 #pragma config LVP = OFF ///MCLR端子に高電圧(VPP)を与えて書き込む。RB3(PGM)は通常の入出力ポート。
12 //#pragma config CPD = OFF //EEPROM読み出し禁止
13 //#pragma config WRT = OFF //フラッシュプログラムメモリ書き込み防止なし
14 //#pragma config CCPMX = RB3 //RB3コンパレータ入力
15 //#pragma config CP = OFF //プログラム読み出し許可
16
17 // CONFIG2
18 //#pragma config FCMEN = OFF //非常用内蔵クロック(FRC)使用禁止
19 //#pragma config IESO = OFF //電源立ち上げ時非常用内蔵クロック(FRC)使用禁止
20
21 #define I2C_SCL RB4
22 #define I2C_SDA RB1
23 #define I2C_SDA_TRIS TRISB1
24
25 //小型液晶アドレス(I2Cフォーマット)
26 #define LCD_ADDR 0x7C
27
28 static void pic_init(void);
29
30 static void I2C_start(void);
31 static void I2C_send(unsigned char);
32 static unsigned char I2C_ackchk(void);
33 static void I2C_acksnd(void);
34 static void I2C_nacksnd(void);
35 static unsigned char I2C_rcv(void);
36 static unsigned char I2C_rcv_char(unsigned char EE_P0 ,unsigned char addr1 ,unsigned char addr2);
37 static void I2C_stop(void);
38
39
40 static void wait_50us(void);
41 static void wait_1ms(void);
42 static void wait_ms(unsigned int);
43
44
45 __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & IESO_OFF & LVP_OFF);
46
47
48 const unsigned char hex_tbl[16] = "0123456789ABCDEF";
49 /*
50 void setI2C( unsigned char databyte ) {
51 //PDF セクション19. I2C(Inter-Integrated Circuit)
52 //19.5 シングルマスタ環境でマスタとして通信する
53
54 //1. SDAx と SCLx で START 条件を生成する
55 I2C1CONbits.SEN = 1;
56 while( I2C1CONbits.SEN ) {};
57
58 //2. 書き込み指示を含むI2C デバイスアドレスバイトをスレーブへ送信する
59 I2C1TRN = 0x7c; //(液晶仕様:スレーブアドレスは、0x7Cです)
60
61 //3. スレーブからの肯定応答を待機/ 確認する
62 while( I2C1STATbits.TBF ) {}
63 while( I2C1STATbits.TRSTAT ) {}
64 if( I2C1STATbits.ACKSTAT ) {
65 //1 = スレーブからNACK を受信した
66 }
67
68 //4. (液晶仕様:コントロール部)をスレーブへ送信する
69
70 I2C1TRN = 0b00000000; //液晶仕様:コマンド送信時 RS=0
71
72 //5. スレーブからの肯定応答を待機/ 確認する
73 while( I2C1STATbits.TBF ) {}
74 while( I2C1STATbits.TRSTAT ) {}
75 if( I2C1STATbits.ACKSTAT ) {
76 //1 = スレーブからNACK を受信した
77 }
78
79 //6. (液晶仕様:データ部)をスレーブへ送信する
80 I2C1TRN = databyte;
81
82 //7. スレーブからの肯定応答を待機/ 確認する
83 while( I2C1STATbits.TBF ) {}
84 while( I2C1STATbits.TRSTAT ) {}
85 if( I2C1STATbits.ACKSTAT ) {
86 //1 = スレーブからNACK を受信した
87 }
88
89 //13. SDAx とSCLx でSTOP 条件を生成する
90 while( I2C1CON & 0b0000000000011111 != 0 ) {}
91 I2C1CONbits.PEN = 1;
92 while( I2C1CONbits.PEN ) {};
93 }
94 */
95 static void I2C_snd_char2( unsigned char databyte) {
96 I2C_start();
97
98 I2C_send(LCD_ADDR); // スレーブアドレス & Write
99 if (I2C_ackchk()) {
100 }
101
102 //4. (液晶仕様:コントロール部)をスレーブへ送信する
103 I2C_send( 0b00000000 ); //液晶仕様:コマンド送信時 RS=0
104 if (I2C_ackchk()) {
105 }
106
107 //6. (液晶仕様:データ部)をスレーブへ送信する
108 I2C_send(databyte);
109 if (I2C_ackchk()) {
110 }
111
112 I2C_stop();
113
114 return;
115 }
116 void lcdClr() {
117 I2C_snd_char2( 0x01 );//clear disp
118 }
119 void lcdStr( char *str ) {
120 I2C_start();
121 RA1=1;
122 I2C_send(LCD_ADDR); // スレーブアドレス & Write
123 if (I2C_ackchk()) {
124 }
125
126 while( *str != '\0' ) {
127 //control byte
128 if( *str + 1 == '\0' )
129 I2C_send( 0x40 );
130 else
131 I2C_send( 0xc0 );
132
133 //ack
134 if (I2C_ackchk()) {
135 }
136
137 //data byte
138 I2C_send( *str );
139
140 //ack
141 if (I2C_ackchk()) {
142 }
143
144
145 str++;
146 }
147 I2C_stop();
148 }
149 // ==================== メイン処理 ===========================
150 int main() {
151 unsigned char c;
152
153 pic_init(); // PICの初期化
154 int i;
155 for( i = 0; i < 10; i++ ) {
156 RB3=1;
157 wait_ms(100); // 500ミリ秒の待ち時間
158 RB3=0;
159 wait_ms(100); // 500ミリ秒の待ち時間
160 }
161 wait_ms(3000); // 500ミリ秒の待ち時間
162
163 RB3 = 1;
164
165
166 I2C_snd_char2( 0x38 );//norm func---------------
167 wait_ms(50);
168 I2C_snd_char2( 0x3d );//ext. func---------------
169 wait_ms(50);
170 I2C_snd_char2( 0x1d );//osc freq
171 wait_ms(50);
172 I2C_snd_char2( 0x52 );//power/icon/contrast
173 wait_ms(50);
174 I2C_snd_char2( 0x6b );//follower ctr***
175 wait_ms(50);
176 I2C_snd_char2( 0x70 );//contrast
177 wait_ms(50);
178 I2C_snd_char2( 0x39 );//norm func---------------
179 wait_ms(50);
180 I2C_snd_char2( 0x0f );//disp on/off
181 wait_ms(50);
182 lcdClr();
183 wait_ms(50);
184 lcdStr( "DRAM" );
185 wait_ms(50);
186
187 /*
188 //液晶初期設定
189 setI2C( 0x38 );//norm func---------------
190 setI2C( 0x3d );//ext. func---------------
191 setI2C( 0x1d );//osc freq
192 setI2C( 0x56 );//power/icon/contrast
193 setI2C( 0x6b );//follower ctr***
194 setI2C( 0x70 );//contrast
195 setI2C( 0x39 );//norm func---------------
196 setI2C( 0x0f );//disp on/off
197 lcdClr();
198
199 lcdStr( "DRAM" );
200 */
201
202 while(1) {
203 }
204 }
205
206
207 // ==================== PICの初期化 ===========================
208 static void pic_init() {
209 OSCCON = 0x70; // INTOSC 8MHz
210 ANSEL = 0x00; // AN未使用
211 TRISA = 0xF0; // RA0-3:out
212 TRISB = 0xE3; // RB2-4:out SDAは通常input(開放)
213 PORTA = 0x00;
214 PORTB = 0x12; // SCL=1,SDA=1
215
216 // SSPCON = 0x2B; // SSP enable & I2C Firmware Controlled Master mode
217 // この設定をするとうまく動作しない
218
219 return;
220 }
221
222 // ==================== I2C Start =============================
223 static void I2C_start() {
224 I2C_SDA = 1;
225 I2C_SDA_TRIS = 0; // output
226 I2C_SCL = 1; // SCL high
227 NOP();
228 NOP();
229 NOP();
230 NOP();
231 I2C_SDA = 0; // SDA low : startA
232 NOP();
233 NOP();
234 NOP();
235 NOP();
236 I2C_SCL = 0; // SCL lowB
237
238 return;
239 }
240
241 // ==================== I2C Stop ==============================
242 static void I2C_stop() {
243 I2C_SDA = 0; // SDA low
244 I2C_SDA_TRIS = 0; // output
245 I2C_SCL = 1; // SCL high
246 NOP();
247 NOP();
248 NOP();
249 NOP();
250 I2C_SDA_TRIS = 1; // input(SDA high) : stop
251
252 return;
253 }
254
255 // ==================== I2C Send ==============================
256 static void I2C_send(unsigned char send_data) {
257 unsigned char i2c_data,i;
258
259 I2C_SDA_TRIS = 0; // SDA output
260
261 i2c_data = send_data;
262 for (i=8 ; i>0 ; i--) {
263 if (i2c_data & 0x80) { // ビットセット
264 I2C_SDA = 1;
265 } else {
266 I2C_SDA = 0;
267 }
268 i2c_data = i2c_data << 1; // next bit set
269
270 I2C_SCL = 1; // 1ビット送信
271 NOP();
272 NOP();
273 NOP();
274 NOP();
275 I2C_SCL = 0;
276 }
277 I2C_SDA_TRIS = 1; // SDA input
278
279 return;
280 }
281
282 // ==================== I2C Recive ============================
283 static unsigned char I2C_rcv() {
284 unsigned char i2c_data,i;
285
286 I2C_SDA_TRIS = 1; // SDA input
287 for (i=8 ; i>0 ; i--) {
288 NOP();
289 I2C_SCL = 1; // 1ビット受信
290 i2c_data = i2c_data <<1;
291 if (PORTB & 0x02) {
292 i2c_data = i2c_data | 0x01;
293 } else {
294 i2c_data = i2c_data & 0xFE;
295 }
296 I2C_SCL = 0;
297 }
298
299 return(i2c_data);
300 }
301
302 // ==================== I2C Send char ==========================
303 static void I2C_snd_char(unsigned char ee_p0 ,unsigned char addr1 ,unsigned char addr2 ,unsigned char send_data) {
304 I2C_start();
305 I2C_send(LCD_ADDR | ee_p0); // スレーブアドレス & Write
306 if (I2C_ackchk()) {
307 // LCD_data('4');
308 }
309 I2C_send(addr1); // 書き込みアドレス1
310 if (I2C_ackchk()) {
311 // LCD_data('5');
312 }
313 I2C_send(addr2); // 書き込みアドレス2
314 if (I2C_ackchk()) {
315 // LCD_data('6');
316 }
317 I2C_send(send_data); // 書き込み
318 if (I2C_ackchk()) {
319 // LCD_data('7');
320 }
321
322 I2C_stop();
323
324 return;
325 }
326
327 // ==================== I2C Recive char ========================
328 static unsigned char I2C_rcv_char(unsigned char ee_p0 ,unsigned char addr1 ,unsigned char addr2) {
329 unsigned char c;
330
331 I2C_start();
332 I2C_send(LCD_ADDR | ee_p0); // スレーブアドレス & Write
333 if (I2C_ackchk()) {
334 // LCD_data('8');
335 }
336 I2C_send(addr1); // 書き込みアドレス1
337 if (I2C_ackchk()) {
338 // LCD_data('9');
339 }
340 I2C_send(addr2); // 書き込みアドレス2
341 if (I2C_ackchk()) {
342 // LCD_data('A');
343 }
344
345 I2C_start();
346 I2C_send(LCD_ADDR | ee_p0 | 0x01); // スレーブアドレス & Read
347 if (I2C_ackchk()) {
348 // LCD_data('B');
349 }
350 c = I2C_rcv();
351 I2C_nacksnd();
352
353 I2C_stop();
354
355 return(c);
356 }
357
358 // ==================== I2C ACK check =========================
359 static unsigned char I2C_ackchk() {
360 unsigned char i2c_data;
361
362 I2C_SCL = 1; // ACKビット受信
363 I2C_SCL = 0;
364 NOP();
365 NOP();
366 i2c_data = PORTB & 0x02;
367
368 return(i2c_data);
369 }
370
371 // ==================== I2C ACK send ==========================
372 static void I2C_acksnd() {
373 I2C_SDA = 0; // ACK
374 I2C_SDA_TRIS = 0; // SDA output
375 NOP();
376 I2C_SCL = 1; // ACK送信
377 NOP();
378 NOP();
379 NOP();
380 NOP();
381 I2C_SCL = 0;
382 I2C_SDA_TRIS = 1; // SDA input
383
384 return;
385 }
386
387 // ==================== I2C NACK send =========================
388 static void I2C_nacksnd() {
389 I2C_SDA = 1; // NACK
390 I2C_SDA_TRIS = 0; // SDA output
391 I2C_SCL = 1; // NACK送信
392 NOP();
393 I2C_SCL = 0;
394 NOP();
395 I2C_SDA_TRIS = 1; // SDA input
396
397 return;
398 }
399
400 // ==================== LCD 初期表示 ==========================
401
402 // ==================== LCD 4bit 送信 =========================
403
404 // ==================== LCDコマンドWRITE =================
405
406
407 // ==================== LCDデータWRITE =================
408
409
410 // =============== 1バイトを16進数でLCDに出力 ==========
411
412
413 // ==================== LCDの初期化 ===========================
414
415 // ==================== 50μSウェイトルーチン =================
416 static void wait_50us() {
417 unsigned char i;
418
419 for (i=32 ; i>0 ; i--) {}
420 return;
421 }
422
423 // ==================== 1mSウェイトルーチン =================
424 static void wait_1ms() {
425 unsigned char i;
426
427 for (i=179 ; i>0 ; i--) {
428 NOP();
429 NOP();
430 NOP();
431 }
432 return;
433 }
434
435 // ==================== 1mS×ms ウェイトルーチン =============
436 static void wait_ms(unsigned int ms) {
437 unsigned int c;
438 for (c=ms ; c>0 ; c--) {
439 wait_1ms();
440 }
441 return;
442 }
443 // ========================== ここまで ==============================