Sign In

Hardware Runs Slow After Initializing Timer In My Code

Sujit Mishra mishras1132@gmail.com India

Hardware: PIC16F877A Running On External Crystal Of 4 MHZ. Software: MPLAB X IDE With XC8 Compiler

Sir, the problem I am facing is that whenver I initialize Timer0 and Timer1 in my program and runs the hex code in proteus or on actual hardware the program runs very slow but when i comments timer0 & 1 it runs fine. I am using XC8 free compiler, I dont know why I am facing this problem is it because of my free version or something wrong with my code. Please help.....

Images

Replies

R Avinash
2016-05-29 11:24:46
Why haven't you attached the program?
R Sujit Mishra
2016-05-29 11:52:19
Sir I tried to attached to attach the zip file but its not attaching.
R Avinash
2016-05-29 15:43:59
Copy and paste the main program in the box for program.
R Sujit Mishra
2016-05-29 16:37:56
Sir I have attached my main program
/* 
 * File:   Main.c
 * Author: Sujit
 *
 * Created on 12 March, 2016, 11:28 AM
 */

#include "Includes.h"

//__EEPROM_DATA(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);

void Bargraph_On (void);
void Bargraph_Off (void);

unsigned int ADC_value1 = 0, ADC_value2 = 0;
unsigned char count = 100;
unsigned char Dutycycle = 1;

void main(void)
{  
    
    TRISB6= 0;
    TRISB7= 0;
    TRISC = 0x08; //PORTD as output
    TRISD = 0x01; //PORTC as output
    PORTC = 0;
    PORTD = 0;
    
    LED1_OFF;
    LED2_OFF;
    Walk_Stop = 0;
    //eeprom_write(0x00,0);
    //if (eeprom_read(0x00)) LED1_ON;  
    //else LED1_OFF;
    
	InitLCD();			// Initialize LCD
    InitTimer0();		// Initialize timer0
    InitTimer1 ();
    InitADC();			// Initialize ADC
    
    // Power On Message
    lcd_gotoxy (0,4);
    WriteStringToLCD ("WELCOME");
    __delay_ms(600);
    ClearLCDScreen();
    lcd_gotoxy (0,4);
    WriteStringToLCD ("MASKED");
    lcd_gotoxy (1,0);
    WriteStringToLCD ("TECHNOLOGY ENGG.");
    __delay_ms(1000);
    
    ClearLCDScreen();
     
	while(1)
	{
        Counter ();
        
        ADC_value1 = GetADCValue(AN0);		// Read ADC value from RA0(AN0) pin
        ADC_value2 = GetADCValue(AN1);		// Read ADC value from RA1(AN1) pin
		
       // Function for setting Sensitivity with Button
		
       //displayParameter ();
       //chking_Senstivity ();
       Check_Buttons ();
		
        /*if (g_SecondFlag)
        {
            g_SecondFlag = 0;
            displayParameter ();
        }*/
        
        if ((IR1 == 1) || (IR2 == 1))
        {
            
           if ((ADC_value1 >= (count*5)) || (ADC_value2 >= (count*5)))
           {
                setPWMfreq (Dutycycle);
                LED1_ON;
                LED2_ON;
                Walk_Stop = 1;
                Bargraph_On ();
                __delay_ms(600);
                buzzer_Off();
                LED1_OFF;
                LED2_OFF;
                Walk_Stop = 0;
                Bargraph_Off ();
           }
           else 
           {
               Bargraph_On ();
               __delay_ms(1000);
               Bargraph_Off ();
           }
        }
	}
}
//=================================================================
void Bargraph_On (void)
{
    if (ADC_value1 > ADC_value2)
    {
        if (ADC_value1 <= 102)
        {
            RD2 = 1;
        }
        else if (ADC_value1 <= 204)
        {
            RD2 = 1;
            RD3 = 1; 
        }
        else if (ADC_value1 <= 306)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
        }
        else if (ADC_value1 <= 408) 
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
        }
        else if (ADC_value1 <= 510)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
        }
        else if (ADC_value1 <= 612)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
        }
        else if (ADC_value1 <= 714)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
        }
        else if (ADC_value1 <= 816)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
            RD5 = 1;
        }
        else if (ADC_value1 <= 918) 
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
            RD5 = 1;
            RD6 = 1;
        }
        else if (ADC_value1 <= 1024) 
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
            RD5 = 1;
            RD6 = 1;
            RD7 = 1;
        }
    }
    else
    {
        if (ADC_value2 <= 102)
        {
            RD2 = 1;
        }
        else if (ADC_value2 <= 204)
        {
            RD2 = 1;
            RD3 = 1; 
        }
        else if (ADC_value2 <= 306)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
        }
        else if (ADC_value2 <= 408) 
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
        }
        else if (ADC_value2 <= 510)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
        }
        else if (ADC_value2 <= 612)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
        }
        else if (ADC_value2 <= 714)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
        }
        else if (ADC_value2 <= 816)
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
            RD5 = 1;
        }
        else if (ADC_value2 <= 918) 
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
            RD5 = 1;
            RD6 = 1;
        }
        else if (ADC_value2 <= 1024) 
        {
            RD2 = 1;
            RD3 = 1;
            RC4 = 1;
            RC5 = 1;
            RC6 = 1;
            RC7 = 1;
            RD4 = 1;
            RD5 = 1;
            RD6 = 1;
            RD7 = 1;
        }
    }
}
//======================================
void Bargraph_Off (void)
{
    RD2 = 0;
    RD3 = 0;
    RC4 = 0;
    RC5 = 0;
    RC6 = 0;
    RC7 = 0;
    RD4 = 0;
    RD5 = 0;
    RD6 = 0;
    RD7 = 0;
}


R Avinash
2016-05-30 02:25:55
For what purpose TIMER0 and TIMER1 used? I see no use.

Also for PWM TIMER2 should be initialized. That is not seems to be done.

What evidence you are getting the programming is running slower?
R Sujit Mishra
2016-05-30 05:08:10
Sir this is my timer and pwm function which i have used in main loop.
/* 
 * File:   Timer0.c
 * Author: Sujit
 *
 * Created on 18 May, 2016, 1:55 PM
 */

#include <pic16f877a.h>

#include "Includes.h"

#define PWM_FREQ            416

void InitTimer0(void)
{
	// Timer0 is 8bit timer, select T0CS and PSA to be zero
	OPTION_REG &= 0xC1;     // Make Prescalar 1:2
	
	T0IE = 1;				// Enable Timer0 interrupt
	GIE = 1;				// Enable global interrupts
}

void InitTimer1 (void)
{
    TMR1H = 0;				// Cleat timer1 registers
	TMR1L = 0;				// before enabling timer1

	// Timer1 is 16bit timer
	T1CON = 0x01;			// Prescalar 1:1, Timer1 On

	TMR1IF = 0;				// Clear interrupt bit
	TMR1IE = 1;				// Enable Timer1 interrupt
	PEIE = 1; 				// Enable peripheral interrupts
	GIE = 1;				// Enable global interrupts
}

void InitPWM ()
{
    PR2 = 0b10010101;
    T2CON = 0b00000111;   //prescalar
    CCPR2L = 0b00111011;
    CCP2CON = 0b00111100;
    
}
void setPWMDuty (unsigned int duty)
{
    CCPR2L = duty >> 2;
    CCP2CON = ((duty & 3) << 4) | 0x0C;
}

void setPWMfreq (unsigned int dutycyle) // Frequency to activate buzzer
{
    unsigned int pr2val = 0;
    unsigned int maxduty = 0;
    unsigned int duty = 0;
    T2CON = 0b00000111;   //prescalar
    
    pr2val = (unsigned int) (4000000 / PWM_FREQ / 4);
    pr2val = (unsigned int) ((pr2val / 16) - 1);
    PR2 = pr2val;
    maxduty = (unsigned int) (4000000 / (PWM_FREQ * 16));
    duty = ((maxduty * dutycyle) / 100);
    setPWMDuty(duty);
}

void buzzer_Off ()
{
    setPWMfreq (0);
    Buzzer = 0;
}


R Sujit Mishra
2016-05-30 05:10:22
And this is my ISR routine.
/* 
 * File:   ISR.c
 * Author: Sujit
 *
 * Created on 18 May, 2016, 1:57 PM
 */

#include "Includes.h"

//unsigned char g_Timer = 0xEC;
unsigned char fg_13mSCount;
unsigned char g_SecondFlag;

void interrupt ISR(void)
{
    // timer 0 interrupt
	if(T0IF)  //If Timer0 Interrupt @ 200ms
	{
        TMR0 = 0xEC; 
		T0IF = 0;    // Clear the interrupt
        RC2 = ~RC2; // Toggle RC2 pin  
	}
    // timer 1 interrupt
    if(TMR1IF)  //If Timer1 Interrupt
	{	
		TMR1IF = 0;    // clear the interrupt
        RD1 =~ RD1;
        fg_13mSCount++;
	
        if (fg_13mSCount >= 76)
        {
            fg_13mSCount = 0;
            g_SecondFlag = 1;
        }
    }
    
}
R Avinash Gupta
2016-06-01 04:46:31
Comment out only one of then (i.e. TIMER0 or 1) and find out actually which one of them is the culprit.
R Sujit Mishra
2016-06-01 06:09:52
Sir its timer0 which is creating a problem when i change its delay lets say 1 ms then it works fine.The generated delay in my code is of 200us to create a frequency of 5 khz.
R Avinash Gupta
2016-06-02 06:57:08
The timer0 is reloade with a value of 0xEC (decimal 236) it will overflow when it reaches 255 we have 255-236=19 pulses only in between overflow. But timers prescaller is set to 2 so we have 19x2=38 CPU clock pulses between overflows. most of it is used to handle the execution of code in the ISR of this timer. So the MCU is getting very small amount of free time.

The solution is to use a faster MCU like AVR ATmega16 in place of it has also got 4 PWM channels that you can use to generate this 5KHz signal without any CPU overhead.
R Sujit Mishra
2016-06-02 08:09:38
Sorry for my mistake in commented portion. Sir i have used timer prescaler set to 4 so we have 19x4 = 76 CPU clock pulses between overflows. Sir if it still not a sufficient time for MCU then sir can i use any other timer in same MCU?

Post a reply to Sujit Mishra

Think you can help Sujit Mishra ? Then post your thoughts that might help Sujit Mishra. You will earn a lot of reputation in the technical community.

If your program is in multiple files, then ZIP the entire folder and attach below

Images and Screenshots

These helps other better understand your suggestion.