/* <周波数カウンター> */ //********************************************************************** #define LOCK_SW PORTB.F1 #define UNLOCK_SW PORTB.F2 //********************************************************************** void interrupt() { if (PIR1.TMR1IF == 1) { PIR1.TMR1IF = 0; // TRISA.F4 = 0; // ゲートを閉める。 PORTA.F4 = 0; T1CON.TMR1ON = 0; // TIMER1を停止する。 } } //********************************************************************** void Pwm_Change_DutyEx(unsigned int duty_ratio) { CCPR1L = duty_ratio >> 2; CCP1CON.F6 = duty_ratio & 0b00000001; CCP1CON.F7 = (duty_ratio & 0b00000010) >> 1; } //********************************************************************** unsigned long FreqMeasurement100msec() { unsigned long freq; // TRISA.F4 = 0; //ゲートを閉める。 PORTA.F4 = 0; // TIMER0の設定 INTCON.T0IF = 0; TMR0 = 0; // TIMER1の設定 TMR1L = 0xB0; TMR1H = 0x3C; // freq = 0; // 割り込みを許可する。 INTCON.PEIE = 1; INTCON.GIE = 1; // 開始 T1CON.TMR1ON = 1; // Delay_Cyc(2); asm nop; asm nop; asm nop; asm nop; asm nop; asm nop; asm nop; // TRISA.F4 = 1; //ゲートを開ける。 // 測定 while (T1CON.TMR1ON != 0) { if (INTCON.T0IF == 1) { INTCON.T0IF = 0; freq++; } } if (INTCON.T0IF == 1) { INTCON.T0IF = 0; freq++; } freq *= 256; freq += TMR0; return (freq); } //********************************************************************** void main() { static unsigned long freq, lockFreq; // 0...4294967295 static unsigned char buf[12]; static unsigned short cnt; static unsigned int duty; static unsigned short lockMode; // アナログの設定 // OSCCON = 0b01110000; // クッロクを8Mhzに設定する。 ANSEL = 0b00000000; // →今回は使用しない。 // ポートの設定 TRISA = 0b11110001; TRISB = 0b00000111; OPTION_REG.F7 = 0; // PORTBをプルアップ設定する。 // TIMER0の設定 INTCON.T0IE = 0; INTCON.T0IF = 0; OPTION_REG.T0CS = 1; OPTION_REG.T0SE = 0; OPTION_REG.PSA = 1; OPTION_REG.PS0 = 0; OPTION_REG.PS1 = 0; OPTION_REG.PS2 = 0; // TIMER1の設定 PIE1.TMR1IE = 1; PIR1.TMR1IF = 0; T1CON.T1CKPS0 = 1; T1CON.T1CKPS1 = 1; T1CON.TMR1ON = 0; // Lcd_Custom_Config(&PORTB,7,6,5,4,&PORTA,2,3,1); Lcd_Custom_Cmd(LCD_CURSOR_OFF); Lcd_Custom_Out(1, 1, "FreqLockV3"); Delay_ms(1000); Lcd_Custom_Cmd(LCD_CLEAR); // Pwm_Init(100000); // 100Khz PR2 = 0xFF; duty = 1024 / 2; Pwm_Change_DutyEx(duty); Pwm_Start(); lockMode = 0; // while (1) { freq = 0; for (cnt = 0; cnt < 1; cnt++) { freq += FreqMeasurement100msec(); } freq *= 10; LongToStr(freq, buf); Lcd_Custom_Out(1, 1, &buf[3]); Lcd_Custom_Out(1, 9, "Hz "); // if (LOCK_SW == 0) { lockMode = 1; lockFreq = freq; Lcd_Custom_Out(2, 1, &buf[3]); Lcd_Custom_Out(2, 9, "Hz "); } // if (UNLOCK_SW == 0) { lockMode = 0; Lcd_Custom_Out(1, 12, " "); Lcd_Custom_Out(2, 1, " "); duty = 1024 / 2; Pwm_Change_DutyEx(duty); // バリキャップの電圧を中央にする。 } // if (lockMode == 1) { if ((freq > (lockFreq - 100)) && (freq < (lockFreq + 100))) { Lcd_Custom_Out(2, 12, "LOCK "); } if ((freq < (lockFreq - 100))) { Lcd_Custom_Out(2, 12, "LOWER"); duty++; Pwm_Change_DutyEx(duty); // 周波数が低いのでバリキャップの電圧を高くする。 } if ((freq > (lockFreq + 100))) { Lcd_Custom_Out(2, 12, "UPPER"); duty--; Pwm_Change_DutyEx(duty); // 周波数が高いのでバリキャップの電圧を低くする。 } LongToStr(duty, buf); Lcd_Custom_Out(1, 12, &buf[7]); } } } //**********************************************************************