Jump to content

32k interupts a second?

Recommended Posts

:?: I just got a launchpad, some larger flash chips and a LCD and have a question.


Can the watch crystal fire an interrupt 32k times a second?


I want to make some tones and use it to clock a phase accumalator.


For the output I plan to look up the desired output from a look up table indexed via the phase acumalator and compare it to the adc reading every time the acc updates. If its low I will set a pin high else it will be set low.


Does this look doable an anyone got any code bits to help someone still getting all the info together?

Link to post
Share on other sites

No the 32K crystal cannot fire an ISR 32K A second.......The reason being is its to slow. you have to account for cycles that it takes to enter and clear the ISR.


I believe it is possible to create the accumulator, and you should look into Timer_A functions/registers in Chapter 12 in SLA144x.pdf


But my question for you is are you trying to create a wave table? (ie digital synth or function generator)

If so you may want to look at Interval timers and PWM code examples.

Link to post
Share on other sites

I am getting confused reading the docs. I can't use the lone timer for both PWM triggering a 32khz interupt. Can the LF xtal trigger an interrupt on level change and avoid using a timer for it?


Sorry, my learning curve is steap sometimes. I pound my head on the wall on some things but when the click I usually end up with a good grasp of it all.


The end project will be to make tones used in two tone paging systems, its old school but firefighters still use them a lot and my job is fixing them. The tone generator at work gives out TONS of rfi on some frequencies.


tones will be 100.0 to 4000.0 in .1 hz steps.

Link to post
Share on other sites

Ok lets assume you have a standard G2231 chip

your requirement


2 PWM channels for Tones

and a 32KHz interrupt---


My way of approaching this would be --


use the WDT timer for your Tone generation- using something similar to my WDT PWM code

Then use the Timer A Capture compare register for your 32K interrupts a second..... remember you have 2 of these registers


If you are unhappy with the WDT interval PWM, you can use the second CC register instead

Link to post
Share on other sites
.... tones will be 100.0 to 4000.0 in .1 hz steps.


Sine or square wave output, David? A simple NCO (numerically controlled oscillator) might work but generating a 4 kHz sine wave from a 32 kHz loop would only provide eight (8) sine samples per cycle so a 4 kHz output would be a crude looking sine wave.


If you do decide to look at an NCO based frequency generator solution, there are some useful clock and sample frequencies that make it a little easier to come up with the phase offset value for the phase accumulator. For example, a 16,777,216 Hz DCO frequency, a 24 bit phase accumulator, and a 104,857.6 Hz sample/loop frequency (160 cycles) would allow specifying the phase offset as fout * 10 << 4. That is, a frequency of 254.1 Hz would have a phase offset of 2541 << 4, so much easier to compute for a continuously variable frequency generator. On the other hand, if you're working with a table of fixed output frequencies (not variable), a const array of phase offset values and almost any oscillator and loop frequency should work fine.


Forum member oPossum posted an excellent NCO example that's well worth studying; Fraunchpad Poly Synth. I added comments to one section of his code showing one way to derive phase offset values;


   *  Accumulator width = 2^24
   *  Fres = 32000/2^24 = 0.0019073486328125 Hz  (frequency resolution)
   *  Phase offset = Fout / Fres
   *  Phase offset = 6644.87457275391 / 0.0019073486328125 = 3483828.00000000196608
   static unsigned long notes[12] = {
       3483828,                // 116  G#8  6644.87457275391
       3690988,                // 117   A8  7040.00091552734
       3910465,                // 118  A#8  7458.62007141113
       4142993,                // 119   B8  7902.13203430176
       4389349,                // 120   C9  8372.01881408691
       4650353,                // 121  C#9  8869.84443664551
       4926877,                // 122   D9  9397.27210998535
       5219845,                // 123  D#9  9956.06422424316
       5530233,                // 124   E9  10548.0823516846
       5859077,                // 125   F9  11175.3025054932
       6207476,                // 126  F#9  11839.8208618164
       6576592                 // 127   G9  12543.8537597656


Regards, Mike

Link to post
Share on other sites

Using a 32768 Hz xtal for the phase accumulator clock is a very clever idea. I like it.


Here is some code that seems to work. I just briefly tested it, so there may be some bugs.


Timer A is switched between ACLK at 32768 Hz and SMCLK at ~16 MHz as needed.


This will generate two sine waves with a frequency resolution of 0.5 Hz.


This is the core code...

                                   // Phase increments are in units of 0.5 Hz
static unsigned pi1 = 440 * 2;      // Phase increment 1
static unsigned pi2 = 660 * 2;      // Phase increment 2

void main(void)
   WDTCTL = WDTPW | WDTHOLD; // Disable watchdog

   BCSCTL1 = XT2OFF | 15;  // Set DCO to aprox 16 MHz
   DCOCTL = 0x86;          //

   P1DIR = 0xF3;           // I/O assignment
   P1REN = 0x00;           // 
   P1OUT = 0x02;           //
   P1SEL = 0x50;           // Enable Timer A output, SMCLK output

   TACTL = TASSEL_1 | MC_1 | TAIE; // Timer A config: ACLK, count up, ovrflow int enabled
   TAR = 0xFF00;           // Force interrupt soon
   TACCR0 = 420;           // Setup Timer A period for under 32768 kHz
   TACCR1  = TACCR0 / 2;   // Setup Timer A compare to midpoint
   TACCTL1 = OUTMOD_7;     // Setup Timer A reset/set output mode

   _EINT();                // Enable interrupts


#pragma vector = TIMERA0_VECTOR         // Timer A Period interrupt 
__interrupt void timer_a0_isr(void)     // This interrupt will occur when the PWM period is complete
{                                       //
   TACCTL0 &= ~CCIE;                   // Disable period interrupt
   TACTL = TASSEL_1 | MC_1 | TAIE;     // Timer A config: ACLK, count up, overflow interrupt
   TAR = 0xFFFF;                       // Interrupt at next clock edge
   volatile unsigned z = TAIV;         // Clear any pending interrupts
}                                       //

#pragma vector = TIMERA1_VECTOR         // Timer A Overflow interrupt
__interrupt void timer_a1_isr(void)     // This interrupt will occur when the 32 kHz xtal clock
                                       //   (ACLK) causes Timer A to overflow from 65535 to 0
{                                       //
   static unsigned pa1 = 0;            // Phase accumulator for tone 1
   static unsigned pa2 = 0;            // Phase accumulator for tone 2
   static unsigned sample = 218;       // PWM sample
   TACCR1 = sample;                    // Output previous PWM sample
   TACTL = TASSEL_2 | MC_1 | TACLR;    // Timer A config: SMCLK, count up, clear
   TACCTL0 &= CCIFG;                   // Clear any pending interrupt
   TACCTL0 |= CCIE;                    // Enable period interrupt
                                       // Get pointer to sine table entry
   signed char const *ps1 = sine + (pa1 >> 8);
   signed char const *ps2 = sine + (pa2 >> 8);
                                       // Interpolate sine table entry and next sine table entry
   sample = 218 + \
       interpolate(ps1[0], ps1[1], pa1 & 0x00FF) + \
       interpolate(ps2[0], ps2[1], pa2 & 0x00FF);
   pa1 += pi1;                         // Update phase accumulators
   pa2 += pi2;                         //
}                                       //


Complete code attached.


Link to post
Share on other sites
  • 4 weeks later...

Staring at the code and trying to figure out exactly what "Calculate a + (((b - a) * f) / (2 ^ frac_bits))" is ment to do.


Did you use that to find a sine value between the steps of the refernce sin?


I put the project on hold for a while till I could buy a Rigl DS1052E o'scope.

Link to post
Share on other sites

That is linear interpolation. It allows the use of a smaller sine table with reasonable distortion.


In this specific case it could be eliminated with little affect on quality. If the size of the sine table was reduced, then it would be much more important.


If you are going to look at audio with a 'scope, then an analog scope is generally better than a digital. Just listening to audio can often reveal problems that are hard to see on any scope.


For audio work a distortion analyzer and spectrum analyzer (not a scope with FFT) are extremely useful, but quite expensive for anything of good quality.

Link to post
Share on other sites

Thanks again.

I thought that was what it was doing. I plan on using a large enough sine look up table I can probably skip it like you said, the chip I have has 8k of room.


The scope is going to come in handy for a lot of things not just looking at the audio but it will be better than nothing for that too. Its a nice one for about $400 too.I didn't want to be at a point where I program the chip and can't even tell if the outputs are toggling while I debug it. I don't have an frequency counter and it will work as a cheap one too to verify I picking the right value to add to the phase accumalator. I'm hoping I can also figure out the IC2 codes using it on a the recivers on a unit at work and maybe oneday have a 430 control it so I can work on the receiver section with out being connected to the decoder.

Doesn't really matter if it will or not I guess, I have wanted a scope for years. I used Tek scopes everywhere I have worked but this last place, they have the cheapest old analog scopes I have seen in a while good for 20 Mhz. If I do the software hack the Rigol I have at home is good for 100,

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...