自分でも忘れそうなので、PIC16F1705のソース、回路図をきちんと残しておくことにした。
http://rilassaru.blog.jp/source/in9.pdf
ありものの組み合わせなだけで、特に珍しい事は何にもしてません。
- CDIからのパルスを引き込み、パルスの間隔を計測する。
- パルスの間隔からエンジン回転数を計算する。
- エンジン回転数からDAC(デジタルアナログコンバータ)出力値を決める
- DACの出力をPICマイコン内部オペアンプで構成したオペアンプに接続
- オペアンプとコレクタ接地回路を接続し、ニキシー管に流れる電流値を制御する
・コレクタ接地回路とオペアンプの接続については、こちら。
#include
#include
#include
#define _XTAL_FREQ 16000000
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config BOREN = OFF
#pragma config CLKOUTEN = OFF
#pragma config IESO = ON
#pragma config FCMEN = ON
// CONFIG2
#pragma config WRT = OFF
#pragma config PPS1WAY = ON
#pragma config ZCDDIS = ON
#pragma config PLLEN = OFF
#pragma config STVREN = ON
#pragma config BORV = LO
#pragma config LPBOR = OFF
#pragma config LVP = ON
void sys_initialize(void);
uint8_t gRPM = 0;
#define MAX_RPM (125)
#define MIN_RPM (10)
// ----------------------------------------------------------------------------
void main(void) {
static uint8_t dacout = 0;
uint8_t ii;
sys_initialize();
TMR1IE = 1;
TMR1ON = 1;
PEIE = 1;
GIE = 1;
while(1){
uint8_t dac_target = 0;
if(gRPM > MAX_RPM) gRPM = MAX_RPM;
if(gRPM < MIN_RPM) gRPM = MIN_RPM;
dac_target = gRPM * 2;
if(DAC1CON1 > dac_target) DAC1CON1--;
if(DAC1CON1 < dac_target) DAC1CON1++;
__delay_ms(1);
}
return;
}
// ----------------------------------------------------------------------------
void __interrupt() ISRCode(void)
{
static uint16_t tm1_count = 0;
// interrupt handler
if(CCP1IF)
{
tm1_count = ((CCPR1H << 8)|CCPR1L);
gRPM = (uint8_t)(37500 / (tm1_count>>3));
// Reset Timer1 and restart.
TMR1H = 0;
TMR1L = 0;
TMR1ON = 1;
__delay_ms(1);
CCP1IF = 0;
}
if(TMR1IF)
{
gRPM = 0;
TMR1IF = 0;
} else {
// Unhandled Interrupt
}
}
// ----------------------------------------------------------------------------
void sys_initialize(void){
LATA = 0b00000000;
TRISA = 0b00110111; // 0x37;
ANSELA = 0b00010011; // 0x13;
WPUA = 0b00000000;
ODCONA = 0b00000000;
SLRCONA= 0b00110111; // 0x37;
INLVLA = 0b00111111; // x3F;
LATC = 0b00000000;
TRISC = 0b00111011; // 0x3B;
ANSELC = 0b00111111; // 0x3F;
WPUC = 0b00000000;
ODCONC = 0b00000000;
SLRCONC= 0b00111111; // x3F;
INLVLC = 0b00111111; // x3F;
OPTION_REGbits.nWPUEN = 1;
IOCAFbits.IOCAF2 = 0; //interrupt on change for group IOCAF - flag
IOCANbits.IOCAN2 = 0; //interrupt on change for group IOCAN - negative
IOCAPbits.IOCAP2 = 1; //interrupt on change for group IOCAP - positive
CCP1PPS = 0x02; //RA2->CCP1:CCP1
OSCCON = 0b01111000; // SCS FOSC; SPLLEN disabled; IRCF 16MHz_HF;
OSCSTAT = 0x0c; // SOSCR disabled;
OSCTUNE = 0x00; // TUN 0;
BORCON = 0x00; // SBOREN disabled; BORFS disabled;
WDTCON = 0x16; // WDTPS 1:65536; SWDTEN OFF;
FVRCON = 0x8C; // CDAFVR 4x; FVREN enabled; TSRNG Lo_range;
// ADFVR off; TSEN disabled;
DAC1CON0 = 0b10001000; // (0x88)DAC1EN enabled; DAC1NSS VSS; DAC1PSS FVR;
// DAC1OE1 disabled; DAC1OE2 disabled;
DAC1CON1 = 0x3F; // DAC1R 63;
OPA1CON = 0b11000010; // (0xC2)OPA1SP High_GBWP_mode; OPA1EN enabled;
// OPA1PCH DAC; OPA1UG OPAIN-_pin;
CCP1CON = 0b00000100; // (0x05)CCP1M Falling edge; DC1B 0;
CCPR1L = 0x00; // CCPR1L 0;
CCPR1H = 0x00; // CCPR1H 0;
PIR1bits.CCP1IF = 0; // Clear the CCP1 interrupt flag
PIE1bits.CCP1IE = 1; // Enable the CCP1 interrupt
T1GCON = 0x00; // T1GSS T1G_pin; TMR1GE disabled; T1GTM disabled;
// T1GPOL low; T1GGO_nDONE done; T1GSPM disabled;
TMR1H = 0x00; // TMR1H 0;
TMR1L = 0x00; // TMR1L 0;
PIR1bits.TMR1IF = 0; // Clearing IF flag before enabling the interrupt.
PIE1bits.TMR1IE = 1; // Enabling TMR1 interrupt.
// Timer1 setteing
T1CONbits.TMR1CS =0; // 00 = Timer1 clock source is instruction clock (FOSC/4)
T1CONbits.T1CKPS =0b11; // Timer1 Input Clock Prescale Select bits 1:8 Prescale value
T1CONbits.T1OSCEN=0; // Dedicated Timer1 oscillator circuit disabled
T1CONbits.nT1SYNC=1; // 1 = Do not synchronize external clock input
T1CONbits.TMR1ON =0; // Timer1 On bit
}
コメント