/******************************************************************** * プロジェクト名: PIC24F_GC_TX1094A_LCD_TEST * 本実験は、UNV版自作HSオシロ基板を流用して行った。 * * セグメント液晶: aitendo_TX1094A-02 * * 参考にした書籍 * PICで始めるアナログ回路_後閑氏_7セグLCD例 * * Condition: * 原発振は内蔵8MHzFRCを使用し、PostScalerにより1/4に分周し、Fosc= 2MHzとする。 * Fcy=2MHz/2= 1MHz, Tcy=1us * * MPU:PIC24FJ64GC006 * * デバッグ年月日: 2021/1/15 N.Ishii *********************************************************************/ #include /* コンフィギュレーションの設定 */ // CONFIG4 #pragma config DSWDTPS = DSWDTPS1F // Deep Sleep Watchdog Timer Postscale Select bits (1:68719476736 (25.7 Days)) #pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock) #pragma config DSBOREN = OFF // Deep Sleep BOR Enable bit (DSBOR Disabled) #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable (DSWDT Disabled) #pragma config DSSWEN = OFF // DSEN Bit Enable (Deep Sleep operation is always disabled) #pragma config RTCBAT = OFF // RTC Battery Operation Enable (RTC operation is discontinued in VBAT) #pragma config PLLDIV = DIV2 // PLL Input Prescaler Select bits (Oscillator divided by 2 (8 MHz input)) #pragma config I2C2SEL = PRI // Alternate I2C2 Location Select bit (I2C2 is multiplexed to SDA2/RA3 and SCL2/RA2 ) #pragma config IOL1WAY = OFF // PPS IOLOCK Set Only Once Enable bit (The IOLOCK bit can be set and cleared using the unlock sequence) // CONFIG3 #pragma config WPFP = WPFP127 // Write Protection Flash Page Segment Boundary (Page 127 (0x1FC00)) #pragma config SOSCSEL = OFF // SOSC Selection bits (Digital (SCLKI) mode) #pragma config WDTWIN = PS25_0 // Window Mode Watchdog Timer Window Width Select (Watch Dog Timer Window Width is 25 percent) #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset Disabled) #pragma config WPDIS = WPDIS // Segment Write Protection Disable (Disabled) #pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select (Disabled) #pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory) // CONFIG2 #pragma config POSCMD = EC // Primary Oscillator Select (External-Clock Mode Enabled) #pragma config WDTCLK = LPRC // WDT Clock Source Select bits (WDT uses LPRC) //#pragma config OSCIOFCN = OFF // OSCO Pin Configuration (OSCO/CLKO/RC15 functions as CLKO (FOSC/2)) #pragma config FCKSM = CSDCMD // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching and Fail-Safe Clock Monitor are disabled) //#pragma config FNOSC = PRIPLL // Initial Oscillator Select (Primary Oscillator with PLL module (XTPLL,HSPLL, ECPLL)) #pragma config FNOSC = FRCDIV // Initial Oscillator Select (Fast RC Oscillator with Postscaler (FRCDIV)) #pragma config ALTADREF = AVREF_RA // External 12-Bit A/D Reference Location Select bit (AVREF+/AVREF- are mapped to RA9/RA10) #pragma config ALTCVREF = CVREF_RA // External Comparator Reference Location Select bit (CVREF+/CVREF- are mapped to RA9/RA10) #pragma config WDTCMX = WDTCLK // WDT Clock Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits) #pragma config IESO = OFF // Internal External Switchover (Disabled) // CONFIG1 #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler Select (1:32,768) #pragma config FWPSA = PR128 // WDT Prescaler Ratio Select (1:128) #pragma config WINDIS = OFF // Windowed WDT Disable (Standard Watchdog Timer) #pragma config FWDTEN = WDT_DIS // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled) #pragma config ICS = PGx2 // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC2/PGED2) #pragma config LPCFG = ON // Low power regulator control (Low voltage regulator controlled in sw by RETEN bit) #pragma config GWRP = OFF // General Segment Write Protect (Disabled) #pragma config GCP = OFF // General Segment Code Protect (Code protection is disabled) #pragma config JTAGEN = OFF // JTAG Port Enable (Disabled) /// グローバル変数、定数定義 int i; //// セグメントデータの定義 const unsigned int CENTER_7SEG[10] = { // 中央の7セグ用 0x0EE0, 0x0240, 0x0BA0, 0x0B60, 0x0740, 0x0D60, 0x0DE0, 0x0A40, 0x0FE0, 0x0F60 }; const unsigned int UNDER_7SEG[10] = { // 下の7セグ用 0x0DD0, 0x0480, 0x0750, 0x06D0, 0x0E80, 0x0AD0, 0x0BD0, 0x0490, 0x0FD0, 0x0ED0 }; /// 7セグ以外の個別セグメント #define Temperature LCDDATA1bits.S20C0 #define CENTER_C LCDDATA5bits.S20C1 #define Water_flow LCDDATA9bits.S20C2 #define Temperature_set LCDDATA25bits.S20C6 #define UNDER_C LCDDATA17bits.S21C4 #define Fault_code LCDDATA21bits.S21C5 #define Safe LCDDATA25bits.S21C6 #define High LCDDATA1bits.S22C0 #define Low LCDDATA25bits.S22C6 #define DOT_10 LCDDATA1bits.S23C0 #define DOT_1 LCDDATA25bits.S23C6 #define DOT_9 LCDDATA1bits.S24C0 #define DOT_2 LCDDATA25bits.S24C6 #define DOT_8 LCDDATA1bits.S25C0 #define DOT_3 LCDDATA25bits.S25C6 #define DOT_7 LCDDATA1bits.S26C0 #define DOT_4 LCDDATA25bits.S26C6 #define DOT_6 LCDDATA1bits.S27C0 #define BAR LCDDATA13bits.S27C3 #define DOT_5 LCDDATA25bits.S27C6 /// 関数プロトタイピング void LCD_Init(void); void SetDigit(int); void Delayms( unsigned int t); /*********** メイン関数 **************************/ int main(void){ /// クロックの設定 CLKDIVbits.RCDIV = 2; // Fosc= 8MHz/4= 2MHzクロック (1MIPS= Fcy= 1MHz) ※ 2設定で1/4 /// USBピン:RG2/D+, RG3/D-を単純入出力ピンとして使う設定(今回は未使用) // U1CNFG2bits.UTRDIS = 1; /// I/Oの初期設定(UNV版オシロ用のSW・RE・DSW類は今回未使用だがTRISとプルアップ設定は残した。) TRISB = 0xE07F; // RB7:COM6 RB12:COM5 TRISD = 0x0F01; // RD7〜 RD1:SEG26〜 SEG20 TRISE = 0x0070; // RE7:LED RE3〜 RE0:COM3〜 COM0 TRISF = 0x0F78; // RF0:SEG27 RF1:COM4 TRISG = 0x03CC; // RGポートは今回未使用 /// プルアップ設定 CNPU1bits.CN2PUE = 1; // RB0= SW3:SLOPE SW Pullup CNPU1bits.CN10PUE = 1; // RG8= SW2:HOLD SW Pullup CNPU2bits.CN17PUE = 1; // RF4= RE-A Pullup // TRIG_LEVEL CNPU2bits.CN18PUE = 1; // RF5= RE-B Pullup // CNPU5bits.CN68PUE = 1; // RF0= ATT_PRI SW Pullup CNPU5bits.CN71PUE = 1; // RF3= SW5:TRG MODE SW Pullup CNPU6bits.CN83PUE = 1; // RF7= SW6:READY SW Pullup CNPU4bits.CN49PUE = 1; // RD0= SW9:DC/AC SW Pullup CNPU1bits.CN12PUE = 1; // RB15= DSW_b3 Pullup CNPU3bits.CN32PUE = 1; // RB14= DSW_b2 Pullup CNPU2bits.CN31PUE = 1; // RB13= DSW_b1 Pullup // CNPU2bits.CN30PUE = 1; // RB12= DSW_b0 Pullup // CNPU5bits.CN72PUE = 1; // RG2= ZERO_RE-A Pullup // CNPU5bits.CN73PUE = 1; // RG3= ZERO_RE-A Pullup /// LCDドライバ初期化 LCD_Init(); /// メインループ while(1){ for(i=0; i<10; i++){ // 0から9まで順次繰り返し SetDigit(i); // 数字表示 //// 個別表示部はオンとオフを繰り返す Temperature = i%2; CENTER_C= i%2; Water_flow= i%2; Temperature_set= i%2; UNDER_C= i%2; Fault_code= i%2; Safe= i%2; High= i%2; BAR= i%2; Low= i%2; DOT_1= i%2; DOT_2= i%2; DOT_3= i%2; DOT_4= i%2; DOT_5= i%2; DOT_6= i%2; DOT_7= i%2; DOT_8= i%2; DOT_9= i%2; DOT_10= i%2; Delayms(1000); // 1秒間隔 } } } /************************************************** * LCDドライバ初期化 **************************************************/ void LCD_Init(void){ LCDCONbits.SLPEN= 1; // Enable during sleep // スリープ中の動作ビット:SLPENビット 1=停止 LCDCONbits.CS= 1; // Clock is LPRC 31.25kHz // クロック選択ビット:CSビット 内蔵の低周波=31kHzを選択 // LCDクロック源は、31.25kHzだが、これの1/32分周された977HzがLCDへの供給クロックになる。 LCDCONbits.LMUX= 6; // バイアス=1/3, コモン=7コモンに設定 //=================================================================================================================== LCDREGbits.CPEN= 0; // Disable Charge Pump(3.6Vチャージポンプ無効) LCDREGbits.BIAS= 7; // 3.6Vピーク LCDREGbits.MODE13= 0; // 1/3 Bias Output Disable(1/3バイアス無効) LCDREGbits.CKSEL= 1; // Select Clock LPRC //=================================================================================================================== LCDPSbits.WFT= 0; // Type A(波形タイプ選択:タイプA) // 波形タイプA:コモン毎に位相が反転し平均電圧が1フレーム内で0Vになる。 LCDPSbits.BIASMD= 0; // 1/3 Bias Mode(ここで2バイアスか3バイアス選択) LCDPSbits.LP= 4; // Prescaler 1/5 // 1/5になるクロック源は31.25kでなく、さらに32分周されたクロック:977Hzである。 // なので、COMスキャン用リングカウンタの入力クロックは、195Hz(5.12mS)ということになる。 //=================================================================================================================== /// どのセグメントを使うかを設定 /// "1"と設定したセグメントがlcdドライバモジュールの制御下になる。 /// LCDSE0レジスタ:SEG0〜 SEG15の指定 /// LCDSE1レジスタ:SEG16〜 SEG31の指定 LCDSE0= 0; // SEG0を全て無効にする。未使用 LCDSE1= 0x0FF0; // SEG20〜 SEG27を有効にする。 //============================================================================================================ /// LCDREFレジスタは、電力モードAとBの期間割合の設定をするレジスタ /// このモードをきめ細かく制御することで省電力化をする。 LCDREFbits.LCDIRE= 1; // Enable Contrast Control:コントラスト用内蔵リファレンス有効化 LCDREFbits.LCDCST= 0; // Contrast Max:最大コントラスト LCDREFbits.LRLAP= 0; // Off A:モードA電源制御:電源オフ LCDREFbits.LRLBP= 3; // High Power Mode:モードB電源制御:高電力 LCDREFbits.LRLAT= 0; // Allways B Power:常にモードB電源を使う。 //========================================================================================================== /// LCDDATAnレジスタでセグメントの、on/offを制御 /// "1"と設定したセグメントが暗く表示されて見えるようになり /// "0"と設定したセグメントが明るく表示され消えた状態になる。 LCDDATA1= 0; // Clear All Segment LCDDATA5= 0; LCDDATA9= 0; LCDDATA13= 0; LCDDATA17= 0; LCDDATA21= 0; LCDDATA25= 0; LCDCONbits.LCDEN= 1; // Enable LCD Module // 動作中でのレジスタ設定は失敗することがあるので、LCDENビットによる // モジュール許可は、全ての設定が完了してから行う。 } /************************************************** * 数字表示制御関数 **************************************************/ void SetDigit(int number){ while(LCDPSbits.WA == 0); // LCDレディー待ち LCDDATA5= CENTER_7SEG[number]; // 中央7セグ1桁目 COM1 LCDDATA9= CENTER_7SEG[number]; // 中央7セグ1桁目 COM2 LCDDATA17= UNDER_7SEG[number]; // 下7セグ1桁目 COM4 LCDDATA21= UNDER_7SEG[number]; // 下7セグ1桁目 COM5 } /*********************************************** * タイマ4による1msec単位の遅延関数 Fcy=1MHz ***********************************************/ void Delayms( unsigned int t){ IFS1bits.T4IF= 0; // 割り込みフラグクリア PR4 = 999; // 1msec設定 T4CON= 0x8000; // タイマ4スタート プリスケーラ 1/1 while (t--) { // 繰り返し回数 while (!IFS1bits.T4IF); // 待ち IFS1bits.T4IF= 0; // 割り込みフラグクリア } }