/* <周波数ロックユニット> */ #define PRESCALE_SW PORTA.F1 #define GATETIME_SW PORTA.F3 #define LOCK_SW 0b00000100 #define UNLOCK_SW 0b00000001 #define LOCK_LED PORTB.F4 #define UPPER_LED PORTB.F6 #define LOWER_LED PORTB.F7 #define LOCK_MODE 1 #define UNLOCK_MODE 0 //********************************************************************** static short endFlag; static short gateTime; //********************************************************************** void interrupt(){ if (INTCON.INTF == 1) { INTCON.INTF = 0; // if (endFlag == 0xFF) { // 何もしない。 return; } if (endFlag == 0) { TRISA.F4 = 1; //ゲートを開ける。 endFlag++; return; } endFlag++; if (endFlag > gateTime) { TRISA.F4 = 0; // ゲートを閉める。 PORTA.F4 = 0; endFlag = 0xFF; return; } } } //********************************************************************** void Pwm_Change_DutyEx(unsigned int duty_ratio) { CCPR1L = duty_ratio >> 2; CCP1CON.F6 = duty_ratio & 0b00000001; CCP1CON.F7 = (duty_ratio & 0b00000010) >> 1; } //********************************************************************** void Usart_Write_String(char *buf) { short len, i; len = strlen(buf); for (i = 0; i < len; i++) { Usart_Write(buf[i]); } } //********************************************************************** void main() { static unsigned short rs232cSendFlag; static unsigned short mode; static unsigned long freq; // 0...4294967295 static unsigned long freqSave; // 0...4294967295 static unsigned char buf[20]; static short prescaler; static unsigned int duty; // クロックの設定(8Mhz) OSCCON = 0b01110000; // コンパレータの設定 →今回は使用しない。 CMCON = 0b00000111; // アナログの設定 →今回は使用しない。 ANSEL = 0b00000000; // ポートの設定 TRISA = 0b11111111; TRISB = 0b00000101; OPTION_REG.F7 = 0; // INTCON.PEIE = 0; INTCON.GIE = 0; // 入力割り込みの設定 INTCON.INTE = 1; INTCON.INTF = 0; OPTION_REG.INTEDG = 0; // 入力割り込み(変化)の設定 →今回は使用しない。 INTCON.RBIE = 0; INTCON.RBIF = 0; // CCPの設定 →今回は使用しない。 PIE1.CCP1IE = 0; PIR1.CCP1IF = 0; CCP1CON = 0b00001111; CCPR1L = 0; CCPR1H = 0; // TIMER0の設定 INTCON.T0IE = 0; INTCON.T0IF = 0; TMR0 = 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 = 0; PIR1.TMR1IF = 0; TMR1L = 0; TMR1H = 0; T1CON.T1CKPS0 = 0; T1CON.T1CKPS1 = 0; T1CON.TMR1ON = 0; // TIMER2の設定 →今回は使用しない。 PIE1.TMR2IE = 0; PIR1.TMR2IF = 0; T2CON.TMR2ON = 0; T2CON.T2CKPS0 = 0; T2CON.T2CKPS1 = 0; TMR2 = 0; // TRISA.F4 = 0; PORTA.F4 = 0; endFlag = 0xFF; duty = 1024 / 2; // Pwm_Init(8000); // 8Khz PR2 = 0xFF; Pwm_Change_DutyEx(duty); Pwm_Start(); // if (((LOCK_SW & PORTA) == 0) && ((UNLOCK_SW & PORTA) == 0)) rs232cSendFlag = 1; else rs232cSendFlag = 0; // Usart_Init(9600); LOCK_LED = 0; UPPER_LED = 0; LOWER_LED = 0; Delay_ms(250); LOCK_LED = 1; Delay_ms(250); UPPER_LED = 1; Delay_ms(250); LOWER_LED = 1; Delay_ms(250); LOCK_LED = 0; UPPER_LED = 0; LOWER_LED = 0; // if (rs232cSendFlag == 1) { // RS232Cに出力するか? Usart_Write_String("FreqLock R1.00 JF3SFB\r\n"); } // TRISB.F0 = 1; // 割り込み(全体)の設定 INTCON.PEIE = 1; INTCON.GIE = 1; while (1) { if (PRESCALE_SW == 1) { // プリスケーラの切り替え OPTION_REG.PSA = 1; OPTION_REG.PS0 = 0; OPTION_REG.PS1 = 0; prescaler = 1; } else { OPTION_REG.PSA = 0; OPTION_REG.PS0 = 0; OPTION_REG.PS1 = 1; prescaler = 8; } if (GATETIME_SW == 1) { // Gate Timeの切り替え gateTime = 1; } else { gateTime = 10; } // 初期化 TMR0 = 0; INTCON.T0IF = 0; freq = 0; // 開始 endFlag = 0; // 測定 while (endFlag != 0xFF) { if (INTCON.T0IF == 1) { INTCON.T0IF = 0; freq++; } } freq *= 256; freq += TMR0; // 補正 if (prescaler == 8) freq *= 8; if (gateTime == 1) freq *= 10; // 表示 if (rs232cSendFlag == 1) { // RS232Cに出力するか? LongToStr(freq, buf); Usart_Write_String(buf); Usart_Write_String("Hz\r\n"); } // if ((LOCK_SW & PORTA) == 0) { // LOCKスイッチが押されたか? mode = LOCK_MODE; freqSave = freq; } if ((UNLOCK_SW & PORTA) == 0) { // UNLOCKスイッチが押されたか? mode = UNLOCK_MODE; } // if (mode == LOCK_MODE) { // LOCKモード if ((freq > (freqSave - 100)) && (freq < (freqSave + 100))) { LOCK_LED = 1; UPPER_LED = 0; LOWER_LED = 0; } if (freq < (freqSave - 100)) { LOCK_LED = 0; UPPER_LED = 0; LOWER_LED = 1; duty++; Pwm_Change_DutyEx(duty); // 周波数が低いので電圧を高くする。 } if (freq > (freqSave + 100)) { LOCK_LED = 0; UPPER_LED = 1; LOWER_LED = 0; duty--; Pwm_Change_DutyEx(duty); // 周波数が高いので電圧を低くする。 } } else { // UNLOCKモード LOCK_LED = 0; UPPER_LED = 0; LOWER_LED = 0; duty = 1024 / 2; Pwm_Change_DutyEx(duty); // 電圧を中央にする。 } // Delay_ms(10); } } //**********************************************************************