I am facing a problem while implementing a timer based interrupt in mikroC for PIC.
I want to toggle a port pin for 8 times if there is a keypress at PORTC.F0 and there should be a delay of say 100ms between the toggles.
Normally this would be very easy using a delay function
for (i=0;i<=8;i++)
{
PORTB.F0=~PORTB.F0;
Delay_ms(100);
}
But during the period, any other keypresses are missed by the system. So I thought of implementing the solution using interrupts.
#define SW PORTC.F0
char ttime,i;
volatile flag;
void Inittimer()
{
T1CON = 0x01;
TMR1IF_bit = 0;
TMR1H = 0x06;
TMR1L = 0x00;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
void Interrupt()
{
if (TMR1IF_bit)
{
TMR1IF_bit = 0;
TMR1H = 0x06;
TMR1L = 0x00;
ttime--;
if (ttime==0)
{
flag=1;
}
}
}
void main()
{
Inittimer1();
TRISB = 0;
TRISC.F0 = 1;
PORTB = 0x00;
while(1)
{
if (SW==0)
{
ttime=3;
}
if (flag==1)
{
for (i=0;i<=8;i++)
{
PORTB=~PORTB;
flag=0;
}
}
}
}
Nothing is working. Can somebody please help me to correct the code?
When you initialize your timer:
void Inittimer()
{
T1CON = 0x01;
TMR1IF_bit = 0;
TMR1H = 0x06; // No prescaler? I doubt your clock speed is 40-some KHz!
TMR1L = 0x00;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
Why don't you control the LED directly from the ISR ?
if (ttime)
PORTB.F0 = (--ttime & 1); // ttime is not decremented when led is not blinking.
else
PORTB.F0 = 0; // ensures the LED is off.
To start blinking 8 times:
if (SW==0)
{
PORTB.F0 = 1;
ttime = 16;
}
Note that with a 100ms clock interrupt, the first 'blink' of the LED may last up to 200ms... This is why many like to work with a faster timer interrupt (this has usually other uses as well), controlling the led would require adding a soft post-scaler
if (blinking)
{
if (--blinkTimer == 0)
{
blinkTimer = BLINK_DELAY; // whatever number it takes for 100ms.
PORTB.F0 = (--blinking & 1);
}
}
else
{
PORTB.F0 = 0
}
To start blinking:
if (SW==0)
{
blinking = (2 * BLINKS) - 1;
blinkTimer = BLINK_DELAY;
PORTB.F0 = 1;
}
This should get you a more even first blink.