View previous topic :: View next topic |
Author |
Message |
NB_CAD
Joined: 11 Sep 2014 Posts: 7 Location: Newport Beach,CA
|
Can't get IRQ driven freq above 32.5khz (Rapid USB) |
Posted: Thu Sep 11, 2014 12:33 pm |
|
|
I am trying to drive an ultrasonic transducer at around +/-40khz. It may be necessary to tune the transducer to resonance. The project is based on a Rapid USB proto stick since it matches my target goal for a product. It is a sole function of the processor when I pulse so I am flexible. I choose the IRQ method to get complementary outputs.
When I use the IRQ Timer 1 the max frequency I can get is 32.5khz (half cycle IRQ rate (65khz). If it loop on the code I can get 440 khz but don't have a good way to fine tune the frequency. Full uSeconds are not fine enough.
Are the Timer1 ticks really 83.3 ns?
Code: | #include <RapidUSB Bert.h>
#include <ios.h>
#include <math.h>
unsigned int16 sensorTicks; // IRQ for frequency
#int_timer1
void timer1_isr(void)
{
static int1 s;
set_timer1(sensorTicks); // Timer interrupt 83.3us tick?
if (s){
output_b(0b000010000);
}else{
output_b(0b001000000);
}
s=!s;
}
void main(VOID) {
HW_INIT () ;
unsigned int8 a;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Interrupts
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
cout << endl << "Start ";
sensorTicks=65535-16;
while(TRUE){
cout << endl << "Enter the IRQ value: ";
cin >> a;
sensorTicks=65535-a;
cout << endl << "IRQ: "<< a;
}
}
in the rapidUSB.h I found these frequencies
#if !defined(__e3loader)
#use delay(clock=48MHz)
#endif
#if defined(__e3loader)
#use delay(int=8MHz, clock=48MHz, USB_FULL, act=USB)
#endif
#fuses LS48MHZ |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Thu Sep 11, 2014 12:49 pm |
|
|
Use the hardware PWM.
You can just tweak the timer frequency to get a good frequency.
Problem is that it takes a lot of time to get into, and out of an interrupt. Typically about 60 instructions. Add the code in your 'handler', and you run out of time.
Alternatively, you can use the interrupt, without using the interrupt!.
If you don't enable the interrupt, and don't have a handler, you can _poll_ the interrupt bit, then clear it. This only takes a couple of instructions. Vastly faster than using an interrupt handler. |
|
|
NB_CAD
Joined: 11 Sep 2014 Posts: 7 Location: Newport Beach,CA
|
Will try polling the IRQ |
Posted: Thu Sep 11, 2014 1:29 pm |
|
|
Thanks for the suggestion to poll the IRQ Bit. I will try this. If I use the PWM I will have more hardware to get a complementary output that I can turn off when I read the echo from the ultrasonic.
I have been tweaking with instructions for timing. The smallest "C" instruction I found generated 3 machine instructions. Is there a way for me to add single instructions for finer delays? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 11, 2014 1:34 pm |
|
|
Quote: | Is there a way for me to add single instructions for finer delays? |
See the CCS manual for the delay_cycles() function.
Quote: | Are the Timer1 ticks really 83.3 ns? |
With a 48 MHz CPU speed and Timer divisor of 1, the Timer clock should
be 12 MHz, which is a 83.3 ns period. That is the clock rate, not the
interrupt rate. The term "Timer Tick" refers to the interrupt rate, not
the Timer's clock speed. A "Timer Tick" might be commonly be 1 ms,
10ms or 100 ms, or whatever the developer wants. The rate is controlled
by the timer clock frequency and the preload value for the timer.
But, test your program with an LED 1 second blinker loop. Verify that
your PIC is really running at 48 MHz. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Fri Sep 12, 2014 1:17 am |
|
|
You haven't told us your PIC?. Thing is that a lot of PIC's have ECCP modules, and on these, the hardware PWM, can generate a complementary output for you. It is always far easier to let hardware do things..... |
|
|
NB_CAD
Joined: 11 Sep 2014 Posts: 7 Location: Newport Beach,CA
|
|
Posted: Fri Sep 12, 2014 6:06 pm |
|
|
The PIC is a PIC16F1459 used in the Rapid USB Prototyping Stick. This is a cool tool to develop a USB application. It is not as capable as using an ICD but remarkably suitable for the purpose.
Thank you for the tips. Polling the interrupt is ideal. Where I the max I could run was 32khz (interrupting for half cycles.) Now I can almost reach 200khz. The important issue for me is that I can tune my frequency within 1 percent.
Instead of testing the state of the output, I just coded the high going and low going phases. So I didn't need the delay_cycles command to match the duty cycle. I look forward to using it in the future.
I am grateful for your assistance. |
|
|
|