@Jim; the code would be rather useful here, wouldn't it... 8)
[FOLLOW-UP EDIT - 6 JAN 2013] Updated the code to approximate our 10Khz signal with 0...100% duty cycle.
Note: the frequency generation algorithm (uint32_t rc = VARIANT_MCK/3000/frequency; ) does not provide an accurate frequency. We've tested between 5Khz and 10Khz, for 5Khz we get approx. 5.1Khz, and for 10Khz we get 9.26Khz - as close as we can get it to 10Khz. In between the 5Khz and 10Khz, results vary wildly... please check your own numbers before relying too much on this routine.
volatile char On;
volatile char Total;
volatile char Max;
int PWM_Percent;
int PWM_Freq;
//TC1 ch 0
void TC3_Handler()
{
// reset interrupt
TC_GetStatus(TC1, 0);
// process percentage-based PWM waveforms
// If count is at leading edge, raise pulse
if (Total == 0) {
digitalWrite(13,1);
}
// If count is at trailing edge, drop pulse
else if (Total == On) {
digitalWrite(13,0);
}
Total += 1;
// If count is at 100%, reset to zero and start all over again
if (Total > Max) {
Total = 0;
}
}
// End TC3_Handler()
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK3);
uint32_t rc = VARIANT_MCK/3000/frequency;
TC_SetRA(tc, channel, rc/2);
TC_SetRC(tc, channel, rc);
TC_Start(tc, channel);
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
NVIC_EnableIRQ(irq);
}
void setup(){
// Use the LED for now
pinMode(13,OUTPUT);
// Set the total to zero
Total = 0;
// Set pulse width to 50%
PWM_Percent = 50;
// Set interrupt frequency
PWM_Freq = 10000; //
// -------------------------------
// calculate cycles
On = PWM_Percent; //
// set maximum percentage at full 100%
Max = 100; //
// -------------------------------
// Start the timer
startTimer(TC1, 0, TC3_IRQn, PWM_Freq); //TC1 channel 0, the IRQ for that channel and the desired frequency
}
void loop(){
}