CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

generation of 1 kilohertz siren tone using timer 1

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
swapnil



Joined: 15 Dec 2016
Posts: 13
Location: delhi

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger

generation of 1 kilohertz siren tone using timer 1
PostPosted: Fri Jan 06, 2023 12:59 pm     Reply with quote

hi
I want to generate 600 Hz to 700 Hz siren tone using timer 1 in 12f675 mcu, please help.
I generated by delay function but tone is not exactly what i want.
_________________
heroswap1981
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Fri Jan 06, 2023 6:46 pm     Reply with quote

Post some code and do tell what is wrong with the tone.
swapnil



Joined: 15 Dec 2016
Posts: 13
Location: delhi

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger

generation of 1 kilohertz siren tone using timer 1
PostPosted: Fri Jan 06, 2023 10:38 pm     Reply with quote

PrinceNai wrote:
Post some code and do tell what is wrong with the tone.


Code:
#include <12f675.h>
#fuses INTRC_IO,NOWDT,NOMCLR,PROTECT
#use delay(internal=4000000)

#define TONE_PIN  PIN_A0
#define RELAY_PIN  PIN_A1
void timer1_isr(void)
{
   clear_interrupt(INT_TIMER1);
   set_timer1(3036);
   output_toggle(PIN_A1);
   set_timer1(4036);
   output_high(TONE_PIN);
   
}
//Global Variables:
int16 n; //counting var

void siren(void);

// Main Function
void main(void)  {
{  setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); // Internal clock and prescaler 8
   set_timer1(3036);                            // Preload value
   clear_interrupt(INT_TIMER1);                 // Clear Timer1 interrupt flag bit
   enable_interrupts(INT_TIMER1);               // Enable Timer1 interrupt
   enable_interrupts(GLOBAL);                   // Enable global interrupts
   output_toggle(PIN_A1);
   
}
output_low(TONE_PIN);


   while(TRUE)
   {
      siren(); timer1_isr();
   }
 
}
//Beep 1:                     //Short single beep
void siren(void)  { 
         
         //first beep 50% duty:
         for(n=0; n<550; n++)  {
            output_high(TONE_PIN);
            delay_us(750);
            output_low(TONE_PIN);
            delay_us(750); 
           }
         
           for(n=0; n<350; n++)  {
            output_high(TONE_PIN);
            delay_us(550);
            output_low(TONE_PIN);
            delay_us(550); 
           }       
         //second beep 10% duty:
         for(n=0; n<300; n++)  {
            output_high(TONE_PIN);
            delay_us(400);
            output_low(TONE_PIN);
            delay_us(400); 
           } 
           
           return;
   }

In this code, tone is generated by delay but i want by Timer1 function so the frequency can be output from .6 KHz to .7 KHz. Simultaneously the width amplitude should change.
_________________
heroswap1981
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sat Jan 07, 2023 7:36 am     Reply with quote

Quote:

while(TRUE)
{
siren(); timer1_isr();
}


You should never call timer1 interrupt routine. It happens by itself when timer1 overflows, that is the point of an interrupt.

How long do you want each tone to last?
swapnil



Joined: 15 Dec 2016
Posts: 13
Location: delhi

View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger

Re: generation of 1 kilohertz siren tone using timer 1
PostPosted: Sat Jan 07, 2023 8:01 am     Reply with quote

swapnil wrote:
PrinceNai wrote:
Post some code and do tell what is wrong with the tone.


Code:
#include <12f675.h>
#fuses INTRC_IO,NOWDT,NOMCLR,PROTECT
#use delay(internal=4000000)

#define TONE_PIN  PIN_A0
#define RELAY_PIN  PIN_A1
void timer1_isr(void)
{
   clear_interrupt(INT_TIMER1);
   set_timer1(3036);
   output_toggle(PIN_A1);
   set_timer1(4036);
   output_high(TONE_PIN);
   
}
//Global Variables:
int16 n; //counting var

void siren(void);

// Main Function
void main(void)  {
{  setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); // Internal clock and prescaler 8
   set_timer1(3036);                            // Preload value
   clear_interrupt(INT_TIMER1);                 // Clear Timer1 interrupt flag bit
   enable_interrupts(INT_TIMER1);               // Enable Timer1 interrupt
   enable_interrupts(GLOBAL);                   // Enable global interrupts
   output_toggle(PIN_A1);
   
}
output_low(TONE_PIN);


   while(TRUE)
   {
      siren(); timer1_isr();
   }
 
}
//Beep 1:                     //Short single beep
void siren(void)  { 
         
         //first beep 50% duty:
         for(n=0; n<550; n++)  {
            output_high(TONE_PIN);
            delay_us(750);
            output_low(TONE_PIN);
            delay_us(750); 
           }
         
           for(n=0; n<350; n++)  {
            output_high(TONE_PIN);
            delay_us(550);
            output_low(TONE_PIN);
            delay_us(550); 
           }       
         //second beep 10% duty:
         for(n=0; n<300; n++)  {
            output_high(TONE_PIN);
            delay_us(400);
            output_low(TONE_PIN);
            delay_us(400); 
           } 
           
           return;
   }

In this code, tone is generated by delay but i want by Timer1 function so the frequency can be output from .6 KHz to .7 KHz. Simultaneously the width amplitude should change.



there is only one tone ,timer1 i have used to toggle a relay which will on/off at 1 hz for flasher(lamp) to be connected.

im my code tone is generated by delay function but i want by timer 1
frequency can be output from .6 KHz to .7 KHz. Simultaneously the width amplitude should change.
_________________
heroswap1981
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Jan 07, 2023 8:36 am     Reply with quote

First comment, honestly use a different chip.
If you use for example the 12F1822 or the 1840, these both have PWM
modules. Can develop a tone with almost no software overhead at all.
Also will support different duty cycles simply.
Simple, reliable etc. etc...

Now, to do this with this chip, there will be a significant cost in terms of
software, and it will result in delay functions running slightly slow as the
chip spends some of it's time servicing the interrupt.
You do have to use an interrupt for this, since the timer does not itself
support toggling a pin. What you will have to do is run the timer at
the 'half period' interval, and toggle the pin each time this expires. So:
Code:

include <12f675.h>
#fuses INTRC_IO,NOWDT,NOMCLR,PROTECT
#use delay(internal=4000000)

#define INTERVAL (125000/2000) //count for a 2000Hz interrupt
#define RELOAD (65536-INTERVAL)
//This is the reload needed for the interrupt at 2000Hz to give a 1KHz
//tone. The timer counts up from the reload and wraps at 65536.
//The timer is fed by 4MHz/(4*8)

#define TONE_PIN  PIN_A0
#define RELAY_PIN  PIN_A1
void timer1_isr(void)
{
   set_timer1(RELOAD);
   output_toggle(TONE_PIN); 
}

void siren(void);

// Main Function
void main(void)  {
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
   // Internal clock and prescaler 8
   set_timer1(RELOAD);                            // Preload value
   clear_interrupt(INT_TIMER1);                 // Clear Timer1 interrupt flag bit
   enable_interrupts(INT_TIMER1);               // Enable Timer1 interrupt
   enable_interrupts(GLOBAL);                   // Enable global interrupts
 
   while(TRUE)
   {
      siren();
   }
 
}
//Beep 1:                     //Short single beep
void siren(void) 

    output_high(RELAY_PIN); //assume this turns the relay on
    delay_ms(1000); //one second
    output_low(RELAY_PIN); //and off for one second.
    delay_ms(1000);
}


That should give you a 50% duty cycle 1KHz tone, for one second, then
relay off for one second, and keep repeating.
As posted, the delays will be about 10% long because of the time spent
in the interrupt handling the tone.

Now if you want to change the duty cycle, you would have to change the
reload value used in alternate calls to the interrupt.

If the timer interrupt is giving you 1000Hz, you can't use this for the
flash as well. If you want timer1 to handle this flash function, then use
timer0 for the tone. Does it really have to be 1KHz?. If you could accept
976Hz, this is easy with timer0, using an /2 prescaler, since it will then
interrupt every 1/1953 second without using any reload. However this
will not then give duty cycle control.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group