Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Variable timer interrupts with 16F88

Status
Not open for further replies.

Homerzinho

New Member
Hi guys, my PIC is connected to a buzzer, and I want to make my code in way that when I press a button the frequency of the buzzer changes.

To change that frequency, I *MUST* use interrupts.

I use cc5x compiler.

I was thinking of something like:

Code:
void interrupt isr() {

    static volatile bit saved_dtr;
    saved_dtr = dtr;
                   ;                                        // save the current status of dtr
                ;                                           // disable reception of serial chars
    dtr = B_HIGH;
   
 if(TMR1IF) {
            ++tmr_aux;
            TMR1IF = false;
       PORTB.1=~PORTB.1;
        }
        
        dtr = saved_dtr;
                       ;                                  // restore the status of dtr
    }
}

I´m at school now and I can´t test the code.

I need some directions on how to make interrupts with variable timers, and some documentation on TIMERS in the cc5x compiler.

Thanks in advance, I really need to understand that.

----

My finished code looks like this now

Code:
void interrupt isr(void)
{
  if ( T0IF) /* TMR0 overflow interrupt */
  {
            CLK3=~CLK3; //The buzzer port
            TMR0 = 0; // For reseting Timmer 0 value
            T0IF = 0; /* reset Timmer 0 flag INTCON<2>*/
  }
}

(...)
main()
(...)
T0CON = 0b.1100.0100;
TMR0 = 0; /* 256 @ 64 = 1.64ms/2 delay */
INTCON = 0xF0; // Enable interupt
(...)
/*the function I call if the button is pressed (Every time the button is pressed, the frequency should increase to a maximum then return to the first value)*/

void muda_p(void)

{
switch(T0CON)
{
case 0b.1100.0111: T0CON=0b.1100.0100; break;
case 0b.1100.0110: T0CON=0b.1100.0111; break;
case 0b.1100.0101: T0CON=0b.1100.0110; break;
case 0b.1100.0100: T0CON=0b.1100.0101; break;
}



}
 
Last edited:

Homerzinho

New Member
Now, I´m trying to do that:

Code:
void interrupt isr(void)
{
  if ( T0IF) /* TMR0 overflow interrupt */
  {
            CLK3=~CLK3;
            TMR0 = 0; // For reseting Timmer 0 value
            T0IF = 0; /* reset Timmer 0 flag INTCON<2>*/
  }
}

(...)

T0CON = 0xC5;
TMR0 = 0; /* 256 @ 64 = 1.64ms/2 delay */
INTCON = 0xF0; // Enable interupt

(...)

Will that work in cc5x? I can compile right now because I´m at linux.

My plan is to change T0CON everytime the button is pressed.

Will that work?
 

Pommie

Well-Known Member
Most Helpful Member
You would be better doing something like,
Code:
void interrupt isr(void)
{
    if ( T0IF) /* TMR0 overflow interrupt */
    {
        CLK3=~CLK3;
        TMR0 = PreSet;   // For reseting Timmer 0 value
        T0IF = 0;        /* reset Timmer 0 flag INTCON<2>*/
    }
}
Then changing the value of Preset will alter the frequency. However, Timer0 is very inflexible, timer2 is much more useful for this and you can just change the value of PR2.

BTW, there is no register called T0CON.

Mike.
 

Homerzinho

New Member
I used that code

Code:
interrupt int_server( void)
{
    int_save_registers    // W, STATUS (and PCLATH)

    if (T0IF)  {
        /* TMR0 overflow interrupt */
        TMR0 = -45;
        if (CLK3 == 1)
            CLK3 = 0;
        else
           CLK3 = 1;
        T0IF = 0;  /* reset flag */
    }

  

    int_restore_registers // W, STATUS (and PCLATH)
}

And when I change the freq i use
Code:
switch(TMR0)
{
case -200: TMR0=-100; break;
case -100: TMR0=-50; break;
case -50: TMR0=-25; break;
case -25: TMR0=-200; break;
}

But now the buzzer is oscillating in a high frequency and the rest of the code pratically do not execute.

I will try to rise up these values.

If that doesn´t work, what can I do to make the frequency of interruption change in real time?
 

Pommie

Well-Known Member
Most Helpful Member
You need to set the prescaler to something sensible - see the OPTION register for details. You then need to put a value in a variable as I posted earlier.

Mike.
 

Homerzinho

New Member
Oh, I see.

I used OPTION =2 now, and Iḿ using TMR2
OPTION = 2;
TMR2 = 0;
TMR2IE = 1;
GIE = 1;


and changing PR2 as follows

Code:
void muda_p(void)

{
switch(PR2)
{
case 200: PR2=100; break;
case 100: PR2=50; break;
case 50:  PR2=25; break;
case 25:  PR2=200; break;
}




}

Do you think it will work?

Man, thank you very very much for helping me out.

With PR2 = 200, it should buzz at ~5kHz
 
Last edited:

Pommie

Well-Known Member
Most Helpful Member
You need to setup T2CON. If you set it to 0x05 it will make PR2=200 give a frequency of 1250Hz which should be a nicer sound. You also need to set PEIE or your interrupts won't work.

Mike.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top