/****************************************************************/
/* Множитель/делитель частоты                                   */
/* http://radiokot.ru/forum/viewtopic.php?f=20&t=59172          */
/*                                                              */
/* МК:          PIC12F675                                       */
/* Компилятор:  HI-TECH PICC                                    */
/*                                                              */
/* Автор:       Alex                                            */
/*              al.kl@list.ru                                   */
/*              http://ChipMk.ru                                */
/****************************************************************/
#include "pic.h"
__CONFIG ( WDTDIS & INTIO & MCLREN & UNPROTECT );
static volatile near unsigned int	TMR1		@ 0x00E;
/****************************************************************/
#define MUL         0.8        // Множитель
#define PIN_OUT     GPIO0       // Выходной ПИН
#define TRIS_OUT    TRIS0       //
/****************************************************************/
volatile unsigned long   Per_In=0;       // Преобразованный период входного сигнала
static bit               In_Fl=0;        // Флаг окончания преобразования периода
volatile unsigned long   Per_Out=0;      // Период выходного сигнала
/****************************************************************/


/****************************************************************/
void interrupt _isr(void){
static bit p_fl=0;                      // Флаг преобразования входного периода
static unsigned int     H_Per_In=0;     // Старшие байты вх. периода
static unsigned char    H_Per_Out=0;    // Старший байт вых. периода
//-------------------------------------//
    if(INTF){
        INTF=0;
            if(!p_fl){
                p_fl=1;
                TMR0=0;
                H_Per_In=0;
            }
            else{
                *((char*)&Per_In)=TMR0+5;
                TMR0=0;
                    if(T0IF)                // Если было переполнение
                        H_Per_In++;         // обрабатываем его
                *((int*)((char*)&Per_In+1))=H_Per_In;
                H_Per_In=0;
                In_Fl=1;    // Ставим флаг окончания преобразования
            }
        T0IF=0;
    }
//-------------------------------------//
    if(T0IF && T0IE){
        T0IF = 0;
        H_Per_In++;                         //  +256
            if( *((char*)&H_Per_In+1)>=16 ){    //  >=16*65536 ~1000000 МЦ
                H_Per_In=0;
                p_fl=0;     // Сброс флага преобразования
                Per_In=0;   // Период = 0
                In_Fl=1;    // Ставим флаг окончания преобразования
            }
    }
//-------------------------------------//
    if(TMR1IF && TMR1IE){
    TMR1IF=0;
        if(!H_Per_Out--){
            TMR1 -= *((int*)((char*)&Per_Out));
            H_Per_Out = *((char*)&Per_Out+2);
            PIN_OUT=!PIN_OUT;
        }
    }
//-------------------------------------//
}
/****************************************************************/
void main(){
CMCON=7;

TRIS_OUT=0;
PIN_OUT=0;

T0CS =0;
PSA=1;
PS2=0;
PS1=0;
PS0=0;
TMR0 = 0;
T0IE =1;

TMR1ON=1;
TMR1IE=0;

INTE=1;
INTEDG=0;

PEIE=1;
GIE=1;

Per_Out=0;

while(1){
unsigned long per_tmp;

    if(In_Fl){
        In_Fl=0;
        
        //--------------------
        GIE=0;
        per_tmp = Per_In;
        GIE=1;
        per_tmp/=2;
        //--------------------
        if(per_tmp){
            per_tmp = (long)((float)(per_tmp/MUL));
            GIE=0;
            Per_Out = per_tmp;
            GIE=1;
            TMR1IE=1;
        }
        else{
            TMR1IE=0;
            PIN_OUT=0;
        }
    }
}
}
/****************************************************************/
