/************************************************************************ * MAX7219_8x8LedMatrix2_Scroll_TEST: * 8x8Ledモジュール2個を、カスケード接続し、スクロール実験を行う。 * * 参考資料:トラ技 2007年8月号 山口晶大氏の記事 * 8x8 LEDマトリックス・モジュール:M7SEGX1R-7219B"aitendo" * * PIC18F14K50 * 8MHz 内部クロックをPLLで4倍し32MHzクロックにて動作 * Tcy= 1/(32M/4)= 125nS * * 初期作成日:2020/1/7 N.Ishii * 更新年月日:2020/1/9 *************************************************************************/ #include #pragma config FOSC = IRC, PLLEN = ON, FCMEN = OFF #pragma config IESO = OFF, USBDIV = OFF, CPUDIV = NOCLKDIV #pragma config PWRTEN = OFF, BOREN = OFF, WDTEN = OFF #pragma config HFOFST = OFF, MCLRE = ON #pragma config STVREN = ON, BBSIZ = OFF, LVP = OFF #pragma config XINST = OFF #pragma config CP0 = OFF, CP1 = OFF, CPB = OFF #pragma config WRT0 = OFF, WRT1 = OFF, WRTB = OFF, WRTC = OFF #pragma config EBTR0 = OFF, EBTR1 = OFF, EBTRB = OFF #define _XTAL_FREQ 32000000 /// MAX7219 SPIピン定義 #define LOAD_PIN_Hi LATCbits.LATC7 = 1 #define LOAD_PIN_Lo LATCbits.LATC7 = 0 #define CLK_PIN_Hi LATCbits.LATC0 = 1 #define CLK_PIN_Lo LATCbits.LATC0 = 0 #define DATA_PIN_Hi LATCbits.LATC6 = 1 #define DATA_PIN_Lo LATCbits.LATC6 = 0 #define LED LATCbits.LATC2 // デバッグLED unsigned long ScrollBuff[8]= {0x00001C18, 0x00002224, 0x00004042, 0x00004042, 0x0000404A, 0x00002224, 0x00001C1A, 0x00000000};// " CQ" unsigned int DispBuff[8]; //-------------------------------------------------------------------------------------- //******************* プロトタイプ *********************************** void Send_x2_MAX7219(unsigned char adrs, unsigned char HiData, unsigned char LoData); void delay_ms(int ms); /***************** * メイン関数 ******************/ void main(void) { char i, j, loop; char carry_flag= 0;; OSCCON = 0b01100000; // 内部クロック8Mhz x PLL4 UCONbits.USBEN = 0; // USBは使用しない /// アナログ入力と併用の、RB4,5に該当する /// ANSELxビットを'0'にリセット、デジタルピンとして使用する ANSELHbits.ANS10 = 0; // RB4 digital input ANSELHbits.ANS11 = 0; // RB5 digital input TRISA= 1; // RA is Input(今回は未使用) TRISB= 0b11110000; // RB4-7 is Input TRISC= 0; // RC is Output:RC0=CLK, RC6=DATA, RC7=LOAD(CS)) /// 内部プルアップ設定 INTCON2bits.RABPU = 0; // プルアップ許可(これが無いとプルアップされない) WPUB = 0b11110000; // RB4-7 is Pull-Up LED= 0; // デバッグLED 消灯 /// SPIピンの初期化 LOAD_PIN_Hi; CLK_PIN_Lo; /// MAX7219初期化:上位桁・下位桁共に同じパラメータを書込む。 Send_x2_MAX7219(0x0F, 0, 0); // display test reg - normal operation for (i=1; i <= 8; ++i) Send_x2_MAX7219(i, 0, 0); // clear data reg Send_x2_MAX7219(0x09, 0, 0); // decode moode reg - no decode Send_x2_MAX7219(0x0A, 0x0F, 0x0F); // intensity reg - maximum brightness Send_x2_MAX7219(0x0B, 0x07, 0x07); // scan limit reg - 8digit Send_x2_MAX7219(0x0C, 0x01, 0x01); // shutdown reg - normal operation -> Scan Start /// MAIN LOOP while(1) { /// 最初の16回は、スクロールバッファを左シフトしながら、 /// その結果を表示バッファにコピーし表示 for (loop=0; loop < 16; loop++) { for (i=0; i < 8; i++) { ScrollBuff[i] <<= 1; DispBuff[i]= (unsigned int)(ScrollBuff[i] >> 16); } for (i=0; i<8; i++) Send_x2_MAX7219(i+1, (unsigned char)(DispBuff[i] >> 8),(unsigned char)(DispBuff[i] & 0x00FF)); delay_ms(1000); } /// 以降16回は行毎に、キャリーをチェックしキャリーが立っていたらローテート用のデータに変換しながら循環表示 for (loop=0; loop < 16; loop++) { for (i=0; i<8; i++) { if ((ScrollBuff[i] & 0x80000000) == 0x80000000) carry_flag= 1;// シフト前に、msbをチェックし、'1'だったらキャリーを立てておく。 ScrollBuff[i] <<= 1; if (carry_flag == 1) { ScrollBuff[i] |= 0x00000001; // シフト前のmsbが、'1'の場合:シフト後のlsbを強制的に、'1'にする(ローテート) carry_flag= 0; } DispBuff[i]= (unsigned int)(ScrollBuff[i] >> 16); } for (i=0; i<8; i++) Send_x2_MAX7219(i+1, (unsigned char)(DispBuff[i] >> 8),(unsigned char)(DispBuff[i] & 0x00FF)); delay_ms(1000); } /// 初期状態のブランク表示に戻っている。 } /// 最初に戻って繰り返す } //----------------------------------------------------------------------------------------------------------- /****************************************************************** * MAX7219へのデータ送信(2個カスケード接続専用関数) * * <引数> * adrs:レジスタ・アドレス(共通) * HiData:上位桁ledの表示データ * LoData:下位桁ledの表示データ *******************************************************************/ void Send_x2_MAX7219(unsigned char adrs, unsigned char HiData, unsigned char LoData) { char i, j; unsigned char data; unsigned char adrs_temp; adrs_temp= adrs; LOAD_PIN_Lo; for (j=0; j<2; ++j) { if (j == 0) data= HiData; else { data= LoData; adrs= adrs_temp; } // write address for (i=0; i<8; ++i) { __delay_us(1); CLK_PIN_Lo; __delay_us(1); if (0x80 <= adrs) { // send address bit DATA_PIN_Hi; } else { DATA_PIN_Lo; } adrs=adrs << 1; // shift address bits __delay_us(1); CLK_PIN_Hi; } // write data for (i=0; i<8; ++i) { __delay_us(1); CLK_PIN_Lo; __delay_us(1); if (0x80 <= data) { // send data bit DATA_PIN_Hi; } else { DATA_PIN_Lo; } data=data << 1; // shift data bits __delay_us(1); CLK_PIN_Hi; } } __delay_us(1); LOAD_PIN_Hi; __delay_us(1); CLK_PIN_Hi; __delay_us(1); } /***************************************************** * mS 単位の遅延 ******************************************************/ void delay_ms(int ms){ while(ms-- > 0)__delay_ms(1); }