/* =========================================================================== * 16 x 16 Life Game Program * =========================================================================== * プログラミング初期設定 PIC16F1939 40pin Package PIN互換OK v001 * TRドライブ関数 モニターLED点滅確認 v010 * 配列のDotデータをLEDマトリクスに表示する動作不良 v011 * ダイナミック点灯確認OK(シフトした変数は代入しないとダメ) * ダイナミック点灯制御完成。上部下位、上位バイト、下部下位、上位 *  の順番で表示。50マイクロSECで、ほぼダイナミックちらつきなし v012 * (x,y)点のON/OFFをチェック(未テスト) v013 * ダイナミック表示ルーチンを改変(TMR用のテスト)動作確認 v014 * 周りのドットONのカウント関数(スケール外は反対値にする)OK v015 * ドットON、OFF (未テスト) * TMR0ダイナミック表示(未テスト) * ライフゲームプロセス(未テスト) v016 * TMR0ダイナミック表示確認 v017 * ドットON/OFF確認。プロセス確認。動作Ok v018 v019 * * * * * * * * * File: LifeGame001.c * Author: VividHobby * Created on 2016/10/07, 11:33 */ //--------------------- // PIC 16F1939 基本設定 //--------------------- #include #include #include #include //----------------------------------- // ソフトバージョン表示 //----------------------------------- // unsigned char ver[] = "v012"; //最大5文字 #define _XTAL_FREQ 20000000 //PICのクロックをHzで設定(20MHz) // PIC16F1938 Configuration Bit Settings // 'C' source line config statements // CONFIG1 #pragma config FOSC = HS // Oscillator Selection (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT disabled) #pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled) #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config VCAPEN = OFF // Voltage Regulator Capacitor Enable (All VCAP pin functionality is disabled) #pragma config PLLEN = ON // PLL Enable (4x PLL disabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. //----------------- //LEDとSWの定義領域 //----------------- #define monitor_LEDC RA0//右下LED点滅(Lで) #define monitor_LEDL RB3//右下LED点滅(Lで) #define SW_1 RA4 #define SW_2 RD7// LEDドライブと共通なので使用しない //#define on 0 // TRドライブ、LEDドライブともに0でon //#define off 1 // 1でoff //------------------ //グローバル変数 //------------------ unsigned int Dot_data[16][4] = 0xFFFF; int Dot_work1 = 0, Dot_work2 = 0; int n = 0, m = 0, TR_no = 0, flg = 0; int on = 0, off = 1; int today, future; int x, y, i, j, k; int dot_no; int cnt = 0; int mtrx[8][2] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} }; float total_dot; //--------------------------------- //関数定義領域 //--------------------------------- void PIC_ini(void); void TR_drive_onL(int); void TR_drive_onH(int); void TR_drive_off(int); void interrupt Dot_disp(void); int Dot_chk(int, int, int); //指定点(x,y,plane_no)のドットのONをチェック int Dot_cnt(int, int, int); //指定点の周りの8ポイントのONのドットカウント void Dot_on(int, int, int); void Dot_off(int, int, int); //========================================================================== // メインプログラム //========================================================================== main() { __delay_ms(1000); PIC_ini(); //PIC16F1939 begin: //-------------------------- // Dot LED 配列の初期設定 // 原点は右上 //-------------------------- //結構長い寿命 Dot_data[0][0] = 0b1111111111111111; //原点は右上 Dot_data[1][0] = 0b1111111111101111; Dot_data[2][0] = 0b1111100111101111; Dot_data[3][0] = 0b1111110111000111; Dot_data[4][0] = 0b1111111111111111; Dot_data[5][0] = 0b1111111110111111; Dot_data[6][0] = 0b1110111110111111; Dot_data[7][0] = 0b1111011110011111; Dot_data[8][0] = 0b1111111111111111; Dot_data[9][0] = 0b1111111111111111; Dot_data[10][0] = 0b111111111111111; Dot_data[11][0] = 0b1111011111111111; Dot_data[12][0] = 0b1111110111111111; Dot_data[13][0] = 0b1110011000111111; Dot_data[14][0] = 0b1111111111111111; Dot_data[15][0] = 0b1111111111111111; //--------------------------------------- // PIC起動確認 //---------------------------------------- monitor_LEDC = 1; //消灯 monitor_LEDL = 1; __delay_ms(500); monitor_LEDC = 0; //点灯 monitor_LEDL = 0; __delay_ms(500); //------------------------------------- // TMR0 の初期設定追加 //------------------------------------- OPTION_REG = 0b10000001; // PreScale 1/4 = 200usec INTCON = 0b10100000; //割込み解除 for (k = 1; k <= 3; k++) { for (y = 0; y <= 15; y++) { for (x = 0; x <= 15; x++) { Dot_off(x, y, k); } } } __delay_ms(1000); //for (y = 0; y <= 15; y++) { //Dot_data[y][0] = rand(); //} //---------------------------------------- // ライフゲームメインプロセス //---------------------------------------- today = 0; //プレーンの初期設定 future = 1; while (1) { for (y = 0; y <= 15; y++) { for (x = 0; x <= 15; x++) { Dot_off(x, y, future); } } for (y = 0; y <= 15; y++) { for (x = 0; x <= 15; x++) { dot_no = Dot_cnt(x, y, today); if (Dot_chk(x, y, today) == 0) { if (dot_no == 3) Dot_on(x, y, future); else Dot_off(x, y, future); } else { if (dot_no <= 1) Dot_off(x, y, future); if (dot_no >= 4) Dot_off(x, y, future); if (dot_no == 2) Dot_on(x, y, future); if (dot_no == 3) Dot_on(x, y, future); //if (dot_no == 4) Dot_on(x, y, future); } } } today = today + 1; if (today >= 4) today = 0; future = future + 1; if (future >= 4) future = 0; __delay_ms(1); //------------------------ // 終了チェック判定 //------------------------ if (SW_1 == 0) break; } goto begin; //--------------------------------------- // PIC起動確認 //---------------------------------------- while (1) { monitor_LEDC = 1; //消灯 monitor_LEDL = 1; __delay_ms(500); monitor_LEDC = 0; //点灯 monitor_LEDL = 0; __delay_ms(500); } //while (1) { //Dot_disp(); //__delay_us(100); //} } //=========================== End of Main Program ===================== //========================================================================= // 関数エリア //========================================================================= //-------------------------------------------------- // Dot ON 指定ビットを0に //-------------------------------------------------- void Dot_on(int xc, int yc, int pn) { int temp; temp = 1; temp = temp << xc; temp = ~temp; Dot_data[yc][pn] = Dot_data[yc][pn] & temp; } //-------------------------------------------------- // Dot OFF 指定ビットを1に //-------------------------------------------------- void Dot_off(int xc, int yc, int pn) { int temp; temp = 1; temp = temp << xc; Dot_data[yc][pn] = Dot_data[yc][pn] | temp; } //------------------------------------------------- // X, Yで指定されたポイントのDOTのON・OFFを返す // ドットがONなら1。 //------------------------------------------------- int Dot_chk(int xc, int yc, int pn) { int dot_no; if (((Dot_data[yc][pn] >> xc) & 1) == 0) dot_no = 1; else dot_no = 0; return dot_no; } //------------------------------------------------- // X, Y, pnで指定されたポイントの周りののDOTのON数を返す //------------------------------------------------- int Dot_cnt(int x0, int y0, int pn) { int xc, yc, i, ttl_no, x1, y1; ttl_no = 0; for (i = 0; i <= 7; i++) { xc = mtrx[i][0]; yc = mtrx[i][1]; x1 = x0 + xc; y1 = y0 + yc; if (x1 < 0) x1 = 15; if (x1 > 15) x1 = 0; if (y1 < 0) y1 = 15; if (y1 > 15) y1 = 0; ttl_no = Dot_chk(x1, y1, pn) + ttl_no; } return ttl_no; } //---------------------------------------------------------- // 配列のDOTデータ(4プレーン)をLEDにダイナミック表示する // コールされるとLEDを消灯し、mで指定されたLEDを点灯して戻る // TMR0を設定して100usec毎に実行 //---------------------------------------------------------- void interrupt Dot_disp(void) { GIE = 0; //---- LED Off ------- PORTA = 0b11111111; // SW1 = RA4 PORTB = 0b11111111; // PORTC = 0b11111111; // PORTD = 0b11111111; // PORTE = 0b11111111; // if (flg == 0) { if (n == future) goto last; // 上段下位バイト Dot_work1 = Dot_data[m][n]; RC4 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 Dot_work1 = Dot_work1 >> 1; RD1 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 Dot_work1 = Dot_work1 >> 1; RC5 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 Dot_work1 = Dot_work1 >> 1; RC6 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 Dot_work1 = Dot_work1 >> 1; RD0 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 Dot_work1 = Dot_work1 >> 1; RD2 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 Dot_work1 = Dot_work1 >> 1; RC7 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 Dot_work1 = Dot_work1 >> 1; RD3 = Dot_work1 & 1; // dotデータをポートに移す 0->0, 1->1 // 下段下位バイト Dot_work2 = Dot_data[m + 8][n]; RB3 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD4 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RB2 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RB1 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD5 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD6 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RB0 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD7 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; last: //-- TR on ---------- TR_drive_onL(m); // mによってドライブTRをon cnt = cnt + 1; } else { if (n == future) goto last2; // 上段上位バイト Dot_work1 = Dot_data[m][n]; Dot_work1 = Dot_work1 >> 8; RC4 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; RD1 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; RC5 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; RC6 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; RD0 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; RD2 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; RC7 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; RD3 = Dot_work1 & 1; Dot_work1 = Dot_work1 >> 1; // 下段上位バイト Dot_work2 = Dot_data[m + 8][n]; Dot_work2 = Dot_work2 >> 8; //上位バイト RB3 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD4 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RB2 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RB1 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD5 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD6 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RB0 = Dot_work2 & 1; Dot_work2 = Dot_work2 >> 1; RD7 = Dot_work2 & 1; last2: //-- TR on ---------- TR_drive_onH(m); // mによってドライブTRをon cnt = cnt + 1; } TR_no = m; // TR_noにmを保存 m = m + 1; //表示するLEDの行を+1する if (m >= 8) { m = 0; if (cnt >= 16) { cnt = 0; n = n + 1; } if (n >= 4) n = 0; flg ^= 1; //flgを反転 } T0IF = 0; GIE = 1; } //--------------------------- // TRドライブ(on) //--------------------------- void TR_drive_onL(int drv) { switch (drv) { case 0: RC3 = on; break; case 1: RC2 = on; break; case 2: RC1 = on; break; case 3: RC0 = on; break; case 4: RA3 = on; break; case 5: RA2 = on; break; case 6: RA1 = on; break; case 7: RA0 = on; break; break; } } //--------------------------- // TRドライブ H (on) //--------------------------- void TR_drive_onH(int drv) { switch (drv) { case 0: RE2 = on; break; case 1: RE1 = on; break; case 2: RE0 = on; break; case 3: RA5 = on; break; case 4: RB7 = on; break; case 5: RB6 = on; break; case 6: RB5 = on; break; case 7: RB4 = on; break; break; } } /* //--------------------------- // TRドライブ(off) //--------------------------- void TR_drive_off(int drv) { switch (drv) { case 0: RC3 = off; break; case 1: RE2 = off; break; case 2: RC2 = off; break; case 3: RE1 = off; break; case 4: RC1 = off; break; case 5: RE0 = off; break; case 6: RC0 = off; break; case 7: RA5 = off; break; case 8: RA3 = off; break; case 9: RB7 = off; break; case 10: RA2 = off; break; case 11: RB6 = off; break; case 12: RA1 = off; break; case 13: RB5 = off; break; case 14: RA0 = off; break; case 15: RB4 = off; break; break; } } */ //============================ // PIC 16F1938 Initialize //============================ void PIC_ini(void) { //注意 PIC16F1939に対する設定 //----- PIC 内部発振制御 -------------------------------- OSCCON = 0b00000000; // HS //----- ポートI/Oアナログ・デジタル設定 ----------------- ANSELA = 0b00000000; // PORTAの設定(0=Digital I/O, 1=Analog in) ANSELB = 0b00000000; // PORTBの設定(0=Digital I/O, 1=Analog in) ANSELD = 0b00000000; ANSELE = 0b00000000; //----- ポートのピンアサイン変更 ------------------------ APFCON = 0b00000000; // 未設定 //----- A/D変換設定 ------------------------------------- ADCON0 = 0b00000000; // 未使用  ADCON1 = 0b00000000; // 未使用 //----- TMR0の設定 ---------------------------------------- OPTION_REG = 0b10000000; // PullUP, RB0, TMR0Soc, TMR0Ed, PreSc, PrScl(3) //----- TMR1の設定 ---------------------------------------- T1CON = 0b11000000; // TMRsoc(2)=CPS, PreScl(2), IntOsc,-,-,TMR1 on/(off) T1GCON = 0b10000001; // Gate, G+/-, TGL, SP, SPflg, GatEN, SorcTMR0ovf //----- 割込み設定 -------------------------------------- INTCON = 0b00000000; // GIE, PEIE, TM0IE, EXTIE, IOChg, TM0ovf, EXTf, IOChgf //----- 周辺機器割り込み制御(1)-------------------------- PIE1 = 0b10000000; // TMR1Gate割込み許可, PIR1 = 0b00000000; // 周辺機器割り込みFLG(TMR1Gate-flg:bit7) //----- CCCP 設定 ----------------------------------------- CCP1CON = 0b00000000; //未使用 CCP2CON = 0b00000000; CCP3CON = 0b00000000; //----- CPS 設定 --------未使用---------------------------- CPSCON0 = 0b00000000; // CPSon,-,-,-,OSC(2),OUT, CLK CPSCON1 = 0b00000000; // -,-,-,-,-, CPS-ch(0-15) //----- ポートの入出力設定 ------------------------------ TRISA = 0b00010000; // SW1 = RA4 TRISB = 0b00000000; // TRISC = 0b00000000; // TRISD = 0b00000000; // TRISE = 0b00000000; // //----- ポートの出力初期化 ------------------------------ PORTA = 0b11111111; // SW1 = RA4 PORTB = 0b11111111; // PORTC = 0b11111111; // PORTD = 0b11111111; // PORTE = 0b11111111; // }