/************************************************************************ * MAX7219_8x8LedMatrix2_Scroll_TEST3: * 8x8Ledモジュール2個を、カスケード接続し、スクロール実験を行う。 * 今回は、フォントテーブルのデータを元に、表示用のデータを生成し * それを循環スクロールさせてみた。 * * 参考資料:後閑氏hpの、PIC24F電光掲示板の記事 * 8x8 LEDマトリックス・モジュール:M7SEGX1R-7219B"aitendo" * * PIC18F14K50 * 8MHz 内部クロックをPLLで4倍し32MHzクロックにて動作 * Tcy= 1/(32M/4)= 125nS * * 初期作成日:2020/2/6 N.Ishii * 更新年月日: * 200210 * 異なるLEDメッセージを追加しました。(コメントアウトにて選択対応) *************************************************************************/ #include #include "Font8x8.h" #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 // #define MaxWord 15 // 表示桁数 #define MaxWord 13 // 200210 unsigned int Buff[MaxWord][8]; // 表示バッファ //char LedMsg[] = "Nobosan's Electronic WorkShop "; // LED Message char LedMsg[] = "MIDI WorkShop of Flutist "; // 200210 //-------------------------------------------------------------------------------------- //******************* プロトタイプ *********************************** void Send_x2_MAX7219(unsigned char adrs, unsigned char HiData, unsigned char LoData); void CreateDispBuff(char *str); void delay_ms(int ms); /***************** * メイン関数 ******************/ void main(void) { char i,k,m; // xc8の場合、修飾子を省略して単にcharと書くとunsignedとなるので注意(この場合は意図的なのでok) signed char l; // xc8の場合、符号付8bitは明示的に、signed charと書く必要があるので注意 int CarryL[MaxWord][8]; 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 /// LEDメッセージの各文字を、フォントバッファから読出し、表示桁数分の表示データを生成。 CreateDispBuff(LedMsg); /// MAIN LOOP while (1) { l= MaxWord-1; while (l >= 0) { switch (l) { case 14: /// 最下位桁の、左シフトとキャリー処理 for (m= 0; m<8; m++) { // 8行分(フォントの横8行)繰り返し CarryL[l][m]= Buff[l][m] & 0x8000; // 最上位ビットをCarryへ保存 Buff[l][m]= Buff[l][m] << 1; // ビットを左へシフト } --l; break; case 13: // case 13〜1は同じ処理 case 12: case 11: case 10: case 9: case 8: case 7: case 6: case 5: case 4: case 3: case 2: case 1: /// 途中の桁の、左シフトとキャリー処理 for (m= 0; m<8; m++) { // 8行分(フォントの横8行)繰り返し CarryL[l][m]= Buff[l][m] & 0x8000; // 最上位ビットをCarryへ保存 Buff[l][m]= Buff[l][m] << 1; // ビットを左へシフト if (CarryL[l+1][m] != 0) { // 下位桁のキャリーが立っていたら Buff[l][m] |= 1; // 上位桁の最下位ビットセット } else { Buff[l][m] &= 0xFFFE; // 上位桁の最下位ビットクリア } } --l; break; case 0: /// 最上位桁の、左シフト+ローテ―トとキャリー処理 for (m= 0; m<8; m++) { // 8行分(フォントの横8行)繰り返し CarryL[l][m]= Buff[l][m] & 0x8000; // 最上位ビットをCarryへ保存 Buff[l][m]= Buff[l][m] << 1; // ビットを左へシフト if (CarryL[l+1][m] != 0) { // 下位桁[1]のキャリーが立っていたら Buff[l][m] |= 1; // 上位桁[0]の最下位ビットセット } else { Buff[l][m] &= 0xFFFE;; // 上位桁[0]の最下位ビットクリア } if (CarryL[l][m] != 0) { // 最上位桁[0]のキャリーが立っていたら Buff[MaxWord-1][m] |= 1; // 最下位桁[14]の最下位ビットセット } else { Buff[MaxWord-1][m] &= 0xFFFE;; // 最下位桁[14]の最下位ビットクリア } } --l; break; } } //// 表示面にデータ転送し表示 for (i=0; i<8; i++) Send_x2_MAX7219(i+1, (unsigned char)(Buff[0][i] >> 8),(unsigned char)(Buff[0][i] & 0x00FF)); delay_ms(100); } } //----------------------------------------------------------------------------------------------------------- /****************************************************************** * 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); } /************************************************************ * LEDメッセージの各文字フォントを、フォントテーブルから読出し、 * 表示桁数分の表示バッファ・データを生成 *(2個カスケード接続専用) * *************************************************************/ void CreateDispBuff(char *str) { char l,m; unsigned int tempH, tempL; for (l=0; l 0)__delay_ms(1); }