Skin:
[NORMAL]
[BLUE] [DOS] [LIGHT]  / コピーするための表示 / 実行
このファイル: /home/web6047/www/cgi-bin/prj/20190815-book_asm_picprj/20200812-P93.X/newmain - snapshot 20200812.c
1 //もとのプログラムの作成者 mit.ueno 様
2
3 #include "pic.h"
4 #include "stdio.h"
5
6 // CONFIG1
7 //http://rikei60.web.fc2.com/toybox/sokkyo/16F88conf.htm
8 //#pragma config FOSC = INTOSCIO //内部クロック発振。RA6,7は通常の入出力ポート。
9 #pragma config WDTE = OFF //暴走自動停止なし。
10 //#pragma config PWRTE = ON //電源立ち上げ時遅延スタートあり
11 //#pragma config MCLRE = ON //RA5はMCLR機能で、負パルスでリセット
12 //#pragma config BOREN = ON //電圧低下(>4V)リセット許可
13 #pragma config LVP = OFF ///MCLR端子に高電圧(VPP)を与えて書き込む。RB3(PGM)は通常の入出力ポート。
14 //#pragma config CPD = OFF //EEPROM読み出し禁止
15 //#pragma config WRT = OFF //フラッシュプログラムメモリ書き込み防止なし
16 //#pragma config CCPMX = RB3 //RB3コンパレータ入力
17 //#pragma config CP = OFF //プログラム読み出し許可
18
19 // CONFIG2
20 //#pragma config FCMEN = OFF //非常用内蔵クロック(FRC)使用禁止
21 //#pragma config IESO = OFF //電源立ち上げ時非常用内蔵クロック(FRC)使用禁止
22 //__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & IESO_OFF & LVP_OFF);
23
24 #define I2C_SCL RB4
25 #define I2C_SDA RB1
26 #define I2C_SDA_TRIS TRISB1
27
28 //小型液晶アドレス(I2Cフォーマット)
29 #define LCD_ADDR 0x7C
30
31
32 static void I2C_start(void);
33 static void I2C_send(unsigned char);
34 static unsigned char I2C_ackchk(void);
35 static void I2C_acksnd(void);
36 static void I2C_nacksnd(void);
37 static unsigned char I2C_rcv(void);
38 static unsigned char I2C_rcv_char(unsigned char EE_P0 ,unsigned char addr1 ,unsigned char addr2);
39 static void I2C_stop();
40
41 static void wait_50us(void);
42 static void wait_1ms(void);
43 static void wait_ms(unsigned int);
44
45
46 //---from:
47 //lcdClr()
48 //main()
49 static void I2C_snd_char2( unsigned char databyte) {
50 I2C_start();
51
52 I2C_send(LCD_ADDR); // スレーブアドレス & Write
53 if (I2C_ackchk()) {
54 }
55
56 //4. (液晶仕様:コントロール部)をスレーブへ送信する
57 I2C_send( 0b00000000 ); //液晶仕様:コマンド送信時 RS=0
58 if (I2C_ackchk()) {
59 }
60
61 //6. (液晶仕様:データ部)をスレーブへ送信する
62 I2C_send(databyte);
63 if (I2C_ackchk()) {
64 }
65
66 I2C_stop();
67
68 wait_ms(5); //これは必要。消すと1文字目が表示されない
69 return;
70 }//I2C_snd_char2()
71
72
73 //---from:
74 //main()
75 void lcdClr() {
76 I2C_snd_char2( 0x01 );//clear disp
77 }
78
79
80 //---from:
81 //main()
82 void lcdStr( char *str ) {
83 I2C_start();
84 I2C_send(LCD_ADDR); // スレーブアドレス & Write
85 if (I2C_ackchk()) {
86 }
87
88 while( *str != '\0' ) {
89 //control byte
90 if( *( str + 1 ) == '\0' ) {
91 I2C_send( 0b01000000 );
92 } else {
93 I2C_send( 0b11000000 );
94 }
95 //ack
96 if (I2C_ackchk()) {
97 }
98
99 //data byte
100 I2C_send( *str );
101
102 //ack
103 if (I2C_ackchk()) {
104 }
105
106
107 str++;
108 }
109 I2C_stop();
110 }//lcdStr()
111
112 //---from:
113 //main()
114 void init( void ) {
115 OSCCON = 0x70; // INTOSC 8MHz
116 ANSEL = 0x00; // AN未使用
117 TRISA = 0xF0; // RA0-3:out
118 TRISB = 0xE3; // RB2-4:out SDAは通常input(開放)
119 PORTA = 0x00;
120 PORTB = 0x12; // SCL=1,SDA=1
121
122 // SSPCON = 0x2B; // SSP enable & I2C Firmware Controlled Master mode
123 // この設定をするとうまく動作しない
124
125 wait_ms( 500 );
126
127 //液晶初期設定
128 I2C_snd_char2( 0x38 );//norm func---------------
129 I2C_snd_char2( 0x3d );//ext. func---------------
130 I2C_snd_char2( 0x1d );//osc freq
131 I2C_snd_char2( 0x52 );//power/icon/contrast
132 I2C_snd_char2( 0x6b );//follower ctr***
133 I2C_snd_char2( 0x70 );//contrast
134 I2C_snd_char2( 0x39 );//norm func---------------
135 I2C_snd_char2( 0x0f );//disp on/off
136 lcdClr();
137 }//init()
138
139 /* 参考になったURL
140 http://mitt.la.coocan.jp/pic/xc8/xc8_88_01_1.html もとになったファイル。I2C制御
141 http://mitt.la.coocan.jp/pic/pic42.html PICの命令とアセンブラ命令
142 https://maku77.github.io/memo/pic/asm/bank.html バンクについての説明
143 http://zattouka.net/GarageHouse/micon/MPLAB/Delay/Delay.htm CとインラインASMの変数の受け渡し例
144 https://www.buildinsider.net/small/netduino/05 I2C送信フォーマット図示など
145 */
146
147 //============================================↓↓↓アセンブラ学習用
148
149 volatile persistent signed char GR0;
150 volatile persistent signed char GR1;
151 volatile persistent signed char GR2;
152 volatile persistent signed char GR3;
153 volatile persistent signed char X;
154 volatile persistent signed char Y;
155 volatile persistent unsigned char CONST0;
156 volatile persistent unsigned char CONST1;
157 volatile persistent char GR4;
158
159 int main() {
160 init();
161
162 lcdStr( "Asm P93" );
163 I2C_snd_char2( 0xc0 );//2行目の先頭へ
164
165 //■CASL2の場合
166 /*
167 ;課題 2つの整数x,yがメモリに保存されているとき、x * y をGR2に求める。
168 ; ただし、yは負でない整数とする。
169 SAMPLE START ;1
170 LD GR0,X ;2
171 LD GR1,Y ;3
172 LD GR2,CONST0 ;4
173 LD GR3,CONST0 ;5
174 LOOP CPA GR3,GR1 ;6
175 JZE LABEL1 ;7
176 ADDA GR2,GR0 ;8
177 ADDA GR3,CONST1 ;9
178 JUMP LOOP ;10
179 LABEL1 RET ;11
180 X DC 4 ;12
181 Y DC 3 ;13
182 CONST0 DC 0 ;14
183 CONST1 DC 1 ;15
184 END ;16
185 */
186
187 //■PICの場合
188 X = 4; //12 ※Xが負数でも動作する。
189 Y = 3; //13
190 CONST0 = 0; //14
191 CONST1 = 1; //15
192 #asm
193 ;課題 2つの整数x,yがメモリに保存されているとき、x * y をGR2に求める。
194 ; ただし、yは負でない整数とする。
195 movf _X, 0 ;2
196 movwf _GR0 ;2
197 movf _Y, 0 ;3
198 movwf _GR1 ;3
199 movf _CONST0, 0 ;4
200 movwf _GR2 ;4
201 movwf _GR3 ;5
202 LOOP: movf _GR1, 0 ;6,7 GR1==GR3判断
203 subwf _GR3, 0 ;6,7 GR1==GR3判断 計算結果代入してしまうがCPAと同等
204 btfsc STATUS, 2 ;6,7 GR1==GR3判断 下の行と合わせてJZEと同等
205 goto LABEL1 ;6,7 GR1==GR3です。
206 movf _GR0, 0 ;8
207 addwf _GR2, 1 ;8
208 movf _CONST1, 0 ;9
209 addwf _GR3, 1 ;9
210 goto LOOP ;10
211 LABEL1: ;11
212 #endasm
213
214 //結果表示
215 char buf[15];
216 sprintf( buf, "%d", GR2 ); //'0'
217 lcdStr( buf );
218
219 //============================================↑↑↑アセンブラ学習用
220
221
222 while(1) {
223 }
224 }//main()
225
226
227 //---from:
228 //I2C_snd_char2()
229 //lcdStr()
230 static void I2C_start() {
231 //START condition作成
232 I2C_SDA = 1;
233 I2C_SDA_TRIS = 0; // output
234 I2C_SCL = 1; // SCL high
235 NOP();
236 NOP();
237 NOP();
238 NOP();
239 I2C_SDA = 0; // SDA low : startA
240 NOP();
241 NOP();
242 NOP();
243 NOP();
244 I2C_SCL = 0; // SCL lowB
245
246 return;
247 }
248
249
250 //---from:
251 //I2C_snd_char2()
252 //lcdStr()
253 static void I2C_stop() {
254 //STOP condition作成
255 I2C_SDA = 0; // SDA low
256 I2C_SDA_TRIS = 0; // output
257 I2C_SCL = 1; // SCL high
258 NOP();
259 NOP();
260 NOP();
261 NOP();
262 I2C_SDA = 1; // SDA low
263 // I2C_SDA_TRIS = 1; // input(SDA high) : stop
264 return;
265 }
266
267
268 //---from:
269 //I2C_snd_char2()
270 //lcdStr()
271 static void I2C_send(unsigned char send_data) {
272 unsigned char i2c_data,i;
273
274 I2C_SDA_TRIS = 0; // SDA output
275
276 i2c_data = send_data;
277 for (i=8 ; i>0 ; i--) {
278 //ビット"1","0"送信
279 if (i2c_data & 0x80) { // ビットセット
280 I2C_SDA = 1;
281 } else {
282 I2C_SDA = 0;
283 }
284 i2c_data = i2c_data << 1; // next bit set
285
286 I2C_SCL = 1; // 1ビット送信
287 NOP();
288 NOP();
289 NOP();
290 NOP();
291 I2C_SCL = 0;
292 }
293 I2C_SDA_TRIS = 1; // SDA input
294
295 return;
296 }
297
298
299 //---from:
300 //I2C_snd_char2()
301 //lcdStr()
302 static unsigned char I2C_ackchk() {
303 //相手デバイスからの肯定応答
304 unsigned char i2c_data;
305
306 I2C_SCL = 1; // ACKビット受信
307 NOP();
308 NOP();
309 I2C_SCL = 0;
310 NOP();
311 NOP();
312 i2c_data = PORTB & 0x02;
313
314 return(i2c_data);
315 }
316
317
318 //---from:
319 //I2C_snd_char2()
320 //main()
321 static void wait_ms(unsigned int ms) {
322 unsigned int c;
323 for (c=ms ; c>0 ; c--) {
324 wait_1ms();
325 }
326 return;
327 }
328
329
330 //***未使用***
331
332 // ==================== I2C Recive ============================
333 static unsigned char I2C_rcv() {
334 unsigned char i2c_data,i;
335
336 I2C_SDA_TRIS = 1; // SDA input
337 for (i=8 ; i>0 ; i--) {
338 NOP();
339 I2C_SCL = 1; // 1ビット受信
340 i2c_data = i2c_data <<1;
341 if (PORTB & 0x02) {
342 i2c_data = i2c_data | 0x01;
343 } else {
344 i2c_data = i2c_data & 0xFE;
345 }
346 I2C_SCL = 0;
347 }
348
349 return(i2c_data);
350 }
351
352
353 // ==================== I2C Recive char ========================
354 static unsigned char I2C_rcv_char(unsigned char ee_p0 ,unsigned char addr1 ,unsigned char addr2) {
355 unsigned char c;
356
357 I2C_start();
358 I2C_send(LCD_ADDR | ee_p0); // スレーブアドレス & Write
359 if (I2C_ackchk()) {
360 // LCD_data('8');
361 }
362 I2C_send(addr1); // 書き込みアドレス1
363 if (I2C_ackchk()) {
364 // LCD_data('9');
365 }
366 I2C_send(addr2); // 書き込みアドレス2
367 if (I2C_ackchk()) {
368 // LCD_data('A');
369 }
370
371 I2C_start();
372 I2C_send(LCD_ADDR | ee_p0 | 0x01); // スレーブアドレス & Read
373 if (I2C_ackchk()) {
374 // LCD_data('B');
375 }
376 c = I2C_rcv();
377 I2C_nacksnd();
378
379 I2C_stop();
380
381 return(c);
382 }
383
384
385 // ==================== I2C ACK send ==========================
386 static void I2C_acksnd() {
387 I2C_SDA = 0; // ACK
388 I2C_SDA_TRIS = 0; // SDA output
389 NOP();
390 I2C_SCL = 1; // ACK送信
391 NOP();
392 NOP();
393 NOP();
394 NOP();
395 I2C_SCL = 0;
396 I2C_SDA_TRIS = 1; // SDA input
397
398 return;
399 }
400
401 // ==================== I2C NACK send =========================
402 static void I2C_nacksnd() {
403 I2C_SDA = 1; // NACK
404 I2C_SDA_TRIS = 0; // SDA output
405 I2C_SCL = 1; // NACK送信
406 NOP();
407 I2C_SCL = 0;
408 NOP();
409 I2C_SDA_TRIS = 1; // SDA input
410
411 return;
412 }
413
414 // ==================== LCD 初期表示 ==========================
415
416 // ==================== LCD 4bit 送信 =========================
417
418 // ==================== LCDコマンドWRITE =================
419
420
421 // ==================== LCDデータWRITE =================
422
423
424 // =============== 1バイトを16進数でLCDに出力 ==========
425
426
427 // ==================== LCDの初期化 ===========================
428
429 // ==================== 50μSウェイトルーチン =================
430 static void wait_50us() {
431 unsigned char i;
432
433 for (i=32 ; i>0 ; i--) {}
434 return;
435 }
436
437 // ==================== 1mSウェイトルーチン =================
438 static void wait_1ms() {
439 unsigned char i;
440
441 for (i=179 ; i>0 ; i--) {
442 NOP();
443 NOP();
444 NOP();
445 }
446 return;
447 }
448
449 // ========================== ここまで ==============================