DavidEQ 4 Posted July 12, 2011 Share Posted July 12, 2011 :?: 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? oPossum 1 Quote Link to post Share on other sites
DavidEQ 4 Posted July 12, 2011 Author Share Posted July 12, 2011 oops "every time the acc updates" should have been "every time the adc updates" Quote Link to post Share on other sites
jsolarski 94 Posted July 12, 2011 Share Posted July 12, 2011 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. Quote Link to post Share on other sites
DavidEQ 4 Posted July 12, 2011 Author Share Posted July 12, 2011 I was hoping to have the main clock running at 16Mhz . I thought that would give me enough CPU cycles to do a couple isrs @ 32lhz. More later, breaks over. Quote Link to post Share on other sites
SugarAddict 227 Posted July 12, 2011 Share Posted July 12, 2011 I was hoping to have the main clock running at 16Mhz . I thought that would give me enough CPU cycles to do a couple isrs @ 32lhz. More later, breaks over. 16000000/32768=488.28125 If you can keep the ISR below that then you should be ok. If you OC your chip you can get upwards of another 100 ticks. jsolarski 1 Quote Link to post Share on other sites
DavidEQ 4 Posted July 14, 2011 Author Share Posted July 14, 2011 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. Quote Link to post Share on other sites
jsolarski 94 Posted July 14, 2011 Share Posted July 14, 2011 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 Quote Link to post Share on other sites
oPossum 1,083 Posted July 14, 2011 Share Posted July 14, 2011 I can't use the lone timer for both PWM triggering a 32khz interupt. Why not? Quote Link to post Share on other sites
Mac 67 Posted July 14, 2011 Share Posted July 14, 2011 .... 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 DavidEQ 1 Quote Link to post Share on other sites
DavidEQ 4 Posted July 14, 2011 Author Share Posted July 14, 2011 I can't use the lone timer for both PWM triggering a 32khz interupt. Why not? Well one be running off the DCO and the other the watch crystal.... Quote Link to post Share on other sites
oPossum 1,083 Posted July 15, 2011 Share Posted July 15, 2011 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 for(;; } #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. two_tone_32k_xtal.zip jsolarski 1 Quote Link to post Share on other sites
DavidEQ 4 Posted July 15, 2011 Author Share Posted July 15, 2011 Thanks for the code I will check it out tonight at home. For some reason I had it stuck in my head one time could only use one way. Quote Link to post Share on other sites
DavidEQ 4 Posted August 6, 2011 Author Share Posted August 6, 2011 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. Quote Link to post Share on other sites
oPossum 1,083 Posted August 6, 2011 Share Posted August 6, 2011 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. DavidEQ 1 Quote Link to post Share on other sites
DavidEQ 4 Posted August 7, 2011 Author Share Posted August 7, 2011 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, Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.