PWM in PIC16F616 using timer0 and timer1

In this tutorial we will see how to generate PWM using two timers in PIC16F616

        
    #include <xc.h>

    // CONFIG
    #pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
    #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
    #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
    #pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
    #pragma config IOSCFS = 8MHZ    // Internal Oscillator Frequency Select bit (8 MHz)
    #pragma config BOREN = OFF      // Brown-out Reset Selection bits (BOR Disabled)
    
    #define Tout RA0
    
    unsigned long int PWM_freq = 8000UL; // min freq achievable is 4khz
    unsigned int duty_cycle = 816,result;
    unsigned char T0_count,T1H_count,T1L_count;
    
    _Bool check1,check2;
    
    //unsigned int off_count_calculator();
    
    void __interrupt () ISR(void)
    {
        //PORTAbits.RA4 = 1;
        if(TMR0IF)
        {
            T0IE = 0;
            TMR0IF = 0;
            
            //PORTAbits.RA4 = 1;
            Tout = 1U;
            //Tout = check1;
            //check1 = !check1;
            TMR0 = T0_count;
            TMR1L = T1L_count;
            TMR1H = T1H_count;
            T0IE = 1;
            TMR1IE = 1;
        }
        
        if(TMR1IF)
        {
            TMR1IE = 0;
            TMR1IF = 0;
            Tout = 0U;
            //Tout = check1;
            //check1 = !check1;
    //        TMR1IE = 0;
    //        TMR1IF = 0;
    //        TMR1L = 0xCC;
    //        TMR1H = 0xFF;
    //        //PIE1bits.TMR1IE = 1;
    //        //RA4 = 1;
    //        if(check2)
    //        {
    //            //RA4 = 1;
    //            RC4 = 1;
    //            check2 = 0;
    //        }
    //        else
    //        {
    //            //RA4 = 0;
    //            RC4 = 0;
    //            check2 = 1;
    //        }
    //        TMR1IE = 1;
        }
        if(ADIF)
        {
            ADIE = 0; // disable adc interrupt
            ADIF = 0; // clear adc interrupt flag
            if(!GO) // if conversion is complete
            {
                result = ADRESH;
                result = (result<<8) + ADRESL;
                //GO = 1;
            }
            ADIE = 1; // enable adc interrupt
        }
    }
    
    void timer0_init()
    {
        T0IE = 0;
        TMR0IF = 0;
        OPTION_REG = 0xD0;
        TMR0 = T0_count;
        TRISA = 0xFE;
        TRISC = 0xEF;
        T0IE = 1;
    }
    
    void timer1_init()
    {
        TMR1IE = 0;
        TMR1IF = 0;
        T1ACS = 0;
        T1GSS = 0U;
        TMR1L = T1L_count;
        TMR1H = T1H_count;
        T1CON = 0x8D; // T1ON    TRISA = 0xEF;
        TRISC = 0xEF;
        TMR1IE = 1;
    }
    
    void ADC2_init()
    {
        ADIE = 0U;
        ADIF = 0U;
        ADFM = 1U; // right justified and vdd for analog voltage reference
        ADCON0 &= 0x1B; // select channel2 for adc conversion
        ADIE = 1;
    }
    
    void count_calculator()
    {
        unsigned long int T_total;
        unsigned int off_count;
        unsigned char T0_offset = 12,T1_offset = 32;
        T_total = 1000000/(PWM_freq);
        T0_count = 0xFF - T_total + T0_offset;
        //T0_count = 0xB7; // for 12khz frequency count is B7
        //off_count = off_count_calculator();
        off_count = 0xFFFF - (2*T_total*duty_cycle)/1000 + T1_offset;
        T1H_count = off_count>>8;
        T1L_count = (off_count&0xFF);
        //T1H_count = 0xFF;
        //T1L_count = 0xF3;
    }
    
    //unsigned int off_count_calculator()
    //{
    //    unsigned int result;
    //    unsigned char T1_offset = 30;
    //    unsigned char T1_duration = 21; // duration in us
    //    
    //    //T1_duration = (duty_cycle/(PWM_freq));
    //    result = 0xFFFF - (int)(2*T1_duration) + T1_offset;
    //    return result;
    //}
    
    void main()
    {
        unsigned char count1 = 0,count2 = 4;
        GIE = 1;
        PEIE = 1;
        timer0_init();
        timer1_init();
        ADC2_init();
        count_calculator();
        //TRISA = 0xEF;
        //RA4 = 1;
        //TRISC = 0xEF;
        //RC4 = 1;
        while(1)
        {
    //        if(RA1)
    //        {
    //            count2 = 18;
    //        }
    //        else
    //        {
    //            count2 = 4;
    //        }
    //        if(count1<count2)
    //        {
    //            RC4 = 1;
    //        }
    //        //NOP();
    //        else
    //        { 
    //            RC4 = 0;
    //        }
    //        //count1 = (count1 + 1)%10;
    //        if(count1 == 19)
    //        {
    //            count1 = 0;
    //        }
    //        else
    //        {
    //            count1++;
    //        }
            
    //        if(count1 >= 100)
    //        {
    //            RC4 = 1;
    //            count2 = 0;
    //           
    //        }
    //        if(count2 >= 50)
    //        {
    //            RC4 = 0;
    //            count1 = 0;
    //        }
    //        count1++;
    //         count2++;
            //if
        }
    }