10 years, 4 months ago.

How to generate a 30.0 KHz interrupt?

I would like to generate a precisely 30 KHz interrupt. It should be possible; for a 96 MHz clock a value in the match register of 3200 (or perhaps 3199) the frequency of the interrupts would be exactly 30 KHz. I tried using the Ticker function but the best I could do with it was 30.0303 KHz. Is it possible to modify a copy of the Ticker code so as to gain direct access to the match register?

I found some code for Timer0 that I attempted to use but it generates lots of errors when compiled. If the answer to the above is no I'll post another question regarding that.

I'm curious what application is using the 30 kHz interrupt?

posted by David G 03 Jan 2014

I'm attempting to build an SSB software defined radio, hardware front end, software backend. I'll be sampling the output of the quadurature demodulator (I & Q channels) at 30 KHz.

posted by Gary Richardson 04 Jan 2014

2 Answers

10 years, 4 months ago.

Well, I could live with something other exactly 30 KHz but the chip (LPC1768) will support that so I would like to find out how to do it. I found some Timer0 code here https://mbed.org/users/hugozijlmans/code/BLDC/file/f034e862af1f/Timer0.c that I thought might show me how it could be done. Below is my adaptation of that code. The problem is that the register names are not recognized. I tried writing them in the form: LPC_SC->T0IR, LPC_SC->T0IR_MR0, etc., but that didn't help. I know from other code I've used that reference to PCLKSEL0 should be written as LPC_SC->PCLKSEL0 so I assumed that the other registers would also. Perhaps I don't have the correct include files.

  1. include "core_cm3.h"
  2. include "cmsis_nvic.h"
  3. include "TARGET_LPC1768/LPC17xx.h"
  4. include "mbed.h"
  5. include "timer0.h" /*Adapted from: https://mbed.org/users/hugozijlmans/code/BLDC/file/f034e862af1f/Timer0.c*/ DigitalOut dOut(p5);

void Timer0_IRQHandler(void) { if ((T0IR & T0IR_MR0) == T0IR_MR0) Match register 0 interrupt { T0IR |= T0IR_MR0; clear the interrupt dOut = !dOut; } NVIC_ClearPendingIRQ(TIMER0_IRQn); }

void Timer0_init(int mr0Value) { NVIC_SetPriority(TIMER0_IRQn, 10); Set Timer0 interrupt priority PCONP &= (PCTIM0); Power the Timer0 T0TCR = 2; Reset the counter PCLKSEL0 &= (PCLK_TIMER0_1 | PCLK_TIMER0_0); PCLKSEL0 |= PCLK_TIMER0_0; Timer0 perhiperal clock select (01 = CCLK) T0MR0 = mr0Value; Set the timer0 match register T0PR = 0; Increment Timer0 with every PCLK T0CTCR = 0; Timer0 is incremented when the prescale register =< 0 T0MCR = 0x3; Reset timer0 after reaching T0MR0 and interrupt NVIC_SetVector(TIMER0_IRQn, (uint32_t)&Timer0_IRQHandler); NVIC_EnableIRQ(TIMER0_IRQn); Enable Timer0 interrupt T0TCR = 1; Enable the counter }

Accepted Answer

First of all, use code tags, now your code is unreadable.

Then the 'SC' is from system control (I think), clock select register is in the system control group, each timer has an own group. Here is the file which defines those things: http://mbed.org/users/mbed_official/code/mbed-src/file/49e45cb70de1/targets/cmsis/TARGET_NXP/TARGET_LPC176X/LPC17xx.h.

In the specific case of the example you used, he used different names for some reason I don't get. They are defined in: https://mbed.org/users/hugozijlmans/code/BLDC/file/f034e862af1f/LPC1768.h. So you need for example:

LPC_TIM0->MR0
posted by Erik - 03 Jan 2014

Thanks for your help. I have it working now. I would post my code but I don't see how to prevent it from becoming garbled as before.

posted by Gary Richardson 04 Jan 2014
10 years, 4 months ago.

Took me a bit to think about this one, but it makes sense. The mbed people had to set a default tick period, which all mbed devices use. This makes sure all of them have the same resolution and maximum ticker period. The 'issue', is that it is set at 1MHz, and that cannot make an exact 30kHz tone.

So I don't know exactly what your requirements are and why it needs to be that precise in the first place, but if you really want that you indeed will need to directly access the hardware. I assume you have an LPC1768 (kinda important information), and then indeed you can use one of the other Timers to do that for you. So you can make a question why your code isn't compiling ;)