|
|
View previous topic :: View next topic |
Author |
Message |
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
PIC24fj64GB002 - HTF3223 Module |
Posted: Thu Jul 25, 2013 9:00 am |
|
|
Hello everyone,
I have made the same topic with PIC18F4550. I had the same problem but we have found a solution, so I tried to do this with this PIC.
I changed a little bit the program again, but my program doesn't work. I made these changes according to the header file of C Compiler, but it gives to the hyperterminal only one number (65274). My sensor is working normally, the PIC is working normally too, so I think that I'm making a mistake in my program.
The header file is a little bit confused, so forgive me if the mistake is stupid.
Here is the previous post: http://www.ccsinfo.com/forum/viewtopic.php?p=177831
And here is the code that I have changed (not the notes):
Code: |
#include <24FJ64GB002.h>
#FUSES NOWDT, FRC, PR_PLL, HS, CKSNOFSM, ICSP1, NOJTAG, NODEBUG
#use delay(clock=8000000,crystal=12000000)
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1,bits=8)
#PIN_SELECT oc1=PIN_B4
//This says your crystal is 12Mhz, so divide this to feed the USB prescaler,
//program the PLL output division to give 32Mhz to the CPU (you can
//change this is you
//want to run slower, 16, 8 or 4MHz), and generate the 48Mhz for the USB
// This global variable holds the time interval
// between two consecutive rising edges of the
// input signal.
int16 isr_oc_delta;
#int_oc1
void oc1_isr(void)
{
int16 current_oc;
static int16 old_oc = 0;
// Read the 16-bit hardware CCP1 register
current_oc = CAPTURE_TRIG_SYNC_OC1; // From the PIC's .h file EDW
// Calculate the time interval between the
// previous rising edge of the input waveform
// and the current rising edge. Put the result
// in a global variable, which can be read by
// code in main().
isr_oc_delta = current_oc - old_oc;
// Save the current ccp value for the next pass.
old_oc = current_oc;
}
//=======================
void main()
{
int16 current_oc_delta;
int16 frequency;
printf("Start \n\r");
/*
// This section of code below (3 lines) is for testing only.
// Do not use it with a real HT3223 chip.
// The CCP2 will be used in PWM mode to output a test
// signal that can be connected to the CCP1 pin.
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 79, 1); // 9.375 KHz PWM freq @ 48MHz osc
set_pwm2_duty(40); // 50% duty cycle on pin C1 (CCP2)
*/
// Setup Timer1 and CCP1 for Capture mode so that
// we can measure the input signal's frequency.
// The input signal comes from the CCP2 pin, which
// is connected to the CCP1 pin with a wire.
set_timer1(0);
setup_timer1(TMR_INTERNAL | TMR_DIV_BY_1);
setup_capture(PIN_B4, CAPTURE_FE);
// Clear the CCP1 interrupt flag before we enable
// CCP1 interrupts, so that we don't get an unwanted
// immediate interrupt (which might happen).
clear_interrupt(INT_OC1);
enable_interrupts(INT_OC1);
enable_interrupts(INTR_GLOBAL);
while(TRUE)
{
// Get a local copy of the latest ccp delta from the isr.
// We have to disable interrupts when we read a global
// isr variable that is larger than a single byte.
disable_interrupts(INTR_GLOBAL);
current_oc_delta = isr_oc_delta;
enable_interrupts(INTR_GLOBAL);
frequency = (int16)((12000000L + (current_oc_delta >> 1)) / current_oc_delta);
// Display the calculated frequency.
printf("%lu \n\r", frequency);
delay_ms(500);
}
}
|
That program is only to capture the frequency. The next step is easy and don't worry about that. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 25, 2013 10:56 am |
|
|
Quote: | setup_capture(PIN_B4, CAPTURE_FE); |
The PCD manual doesn't show that a pin number is the first parameter.
It says this:
Quote: |
setup_capture( )
Syntax:
setup_capture(x, mode) Parameters: x is 1-8 and defines which input capture module is being configured mode is defined by the constants in the devices .h file
Examples:
setup_timer3(TMR_INTERNAL | TMR_DIV_BY_8);
setup_capture(2, CAPTURE_FE | CAPTURE_TIMER3); |
|
|
|
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
|
Posted: Thu Jul 25, 2013 1:45 pm |
|
|
Excuse me if I don't make it clear . I will make it as much as I can.
I want to create a program that measures a frequency with OC1 module and then, i want the hyperterminal to give the measured frequency. Or I want to measure the frequency but I cannot. When I compile this program, then the hyperterminal gives only 65274 Herz (with or without the sensor) and that is false.
The frequency that the sensor gives is from ~8100 Hz to ~10000. That means that the programs doesn't work properly. So, I will try to change the program according to the PCD manual, but i think that i have already that tested. I will test this again and i will inform you tomorrow about the results.
Code: |
setup_capture(PIN_B4, CAPTURE_FE);
|
I found this in an example with an other PIC, so i tried that also.
Thanks anyway |
|
|
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
|
Posted: Fri Jul 26, 2013 7:55 am |
|
|
So, I've changed this line:
Code: |
setup_capture(PIN_B4, CAPTURE_FE);
|
with this line:
Code: |
setup_capture(11, CAPTURE_FE|capture_timer1);
|
and the result is exactly the same. I have 65062 Hz in my hyperterminal :P but my sensor has ~8700 Hz. The frequency in hyperterminal doesn't change when I disconnect the sensor.
I gave '11' - the number of the PIN that i use for capture function, because when I give '1' my compiler gives me an error:
"Invalid parameters to build in function :: Invalid Pin". |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Fri Jul 26, 2013 9:15 am |
|
|
Ok...I don't use that PIC but according to PCM programmers post..
..from the PCD help files...
Syntax:
setup_capture(x, mode) Parameters: x is 1-8 and defines which input capture module is being configured mode is defined by the constants in the devices .h file
..
...so WHY did you try 11 for 'x' ??
You should really open up the device.h file, read which # equates to which module.
The other approach is to try every number from 1 to 8 ( 1 you know doesn't work)....so within 7 tries it should work.Just be sure to write down which ones you've tried!!
hth
jay |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1349
|
|
Posted: Fri Jul 26, 2013 9:20 am |
|
|
That's because you haven't specified a pin for input capture using pin_select. When you put the 1 as the first parameter in setup_capture(), it tells the compiler you are using input capture 1. When the compiler then goes to setup the capture module, it sees that it is a peripheral pin select device but there are no peripheral pins selected. This means it cannot generate code for the input capture module, and thus an error!
ALL peripheral pin select modules NEED a #pin_select line if you plan on using the built in functions for their hardware. |
|
|
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
|
Posted: Sun Jul 28, 2013 4:46 pm |
|
|
Hello guys. I read carefully what you have written to me. I've read the PCD Manual and I understood many things.
Temtronic excuse me, it was a terrible mistake that '11' in setup_capture() line, you're right and jeremiah, i think you've helped me a lot with these information
Firstly, I have to use Input Capture Module (IC1) and not Output Capture Module (OC1). Is that right?
If I'm right, then I have to use timer2 or timer3 according to PCD Manual (page 296). So, I've made changes to my program but it is still not working properly.
Here is my program:
Code: |
#include <24FJ64GB002.h>
#FUSES NOWDT, FRC, PR_PLL, HS, CKSNOFSM, ICSP1, NOJTAG, NODEBUG
#use delay(clock=8000000,crystal=12000000)
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1,bits=8)
#PIN_SELECT ic1=PIN_B4
//This says your crystal is 12Mhz, so divide this to feed the USB prescaler,
//program the PLL output division to give 32Mhz to the CPU (you can
//change this is you
//want to run slower, 16, 8 or 4MHz), and generate the 48Mhz for the USB
// This global variable holds the time interval
// between two consecutive rising edges of the
// input signal.
int16 isr_ic_delta;
#int_ic1
void ic1_isr(void)
{
int16 current_ic;
static int16 old_ic = 0;
// Read the 16-bit hardware CCP1 register
current_ic = CAPTURE_TRIG_SYNC_IC1; // From the PIC's .h file EDW
// Calculate the time interval between the
// previous rising edge of the input waveform
// and the current rising edge. Put the result
// in a global variable, which can be read by
// code in main().
isr_ic_delta = current_ic - old_ic;
// Save the current ccp value for the next pass.
old_ic = current_ic;
}
//=======================
void main()
{
int16 current_ic_delta;
int16 frequency;
printf("Start \n\r");
/*
// This section of code below (3 lines) is for testing only.
// Do not use it with a real HT3223 chip.
// The CCP2 will be used in PWM mode to output a test
// signal that can be connected to the CCP1 pin.
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 79, 1); // 9.375 KHz PWM freq @ 48MHz osc
set_pwm2_duty(40); // 50% duty cycle on pin C1 (CCP2)
*/
// Setup Timer1 and CCP1 for Capture mode so that
// we can measure the input signal's frequency.
// The input signal comes from the CCP2 pin, which
// is connected to the CCP1 pin with a wire.
set_timer3(0);
setup_timer3(TMR_INTERNAL | TMR_DIV_BY_8);
setup_capture(1, CAPTURE_FE| CAPTURE_TIMER3);
// Clear the CCP1 interrupt flag before we enable
// CCP1 interrupts, so that we don't get an unwanted
// immediate interrupt (which might happen).
clear_interrupt(INT_IC1);
enable_interrupts(INT_IC1);
enable_interrupts(INTR_GLOBAL);
while(TRUE)
{
// Get a local copy of the latest ccp delta from the isr.
// We have to disable interrupts when we read a global
// isr variable that is larger than a single byte.
disable_interrupts(INTR_GLOBAL);
current_ic_delta = isr_ic_delta;
enable_interrupts(INTR_GLOBAL);
frequency = (int16)((12000000L + (current_ic_delta >> 1)) / current_ic_delta);
// Display the calculated frequency.
printf("%lu \n\r", frequency);
delay_ms(500);
}
}
|
And that is the result in my Hyperterminal:
Code: |
Start
65062
65062
65062
65062
65062
...
|
When I change this line:
Code: |
frequency = (int16)((12000000L + (current_ic_delta >> 1)) / current_ic_delta);
|
to this line:
Code: |
frequency = get_capture(1, TRUE);
|
i can compile my program but in my Hyperterminal, i get an error (at the Line Status, an error LED turns on) and simpy doesn't work. I don't get anything. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 28, 2013 5:28 pm |
|
|
Quote: | current_ic = CAPTURE_TRIG_SYNC_IC1; // From the PIC's .h file EDW |
I don't have the PCD compiler, so I can't check it, but I'm suspicious
of the indentifier in bold. Post the declaration statement for it.
In fact, I think your code above is probably completely wrong.
Based on the PCD manual, I believe that you should really be using
the get_capture() function to get the captured Timer value.
It probably should be like this, but I can't test it since I don't have that compiler:
Code: | current_ic = get_capture(1, FALSE); |
|
|
|
asiklariskostas
Joined: 07 Jul 2013 Posts: 16 Location: Greece
|
|
Posted: Mon Jul 29, 2013 8:08 am |
|
|
I changed this line as you've told me, and i tried also:
Code: |
get_gapture = (1, TRUE);
|
according to PCD Manual, but i had the same results. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 29, 2013 9:21 am |
|
|
I can't really help any more. I tried to help you port the program to PCD
because I wrote the original program. But my standard methods which
include testing it in hardware and studying the .LST file and comparing it
to the data sheet... I can't do that because I don't have the compiler.
So I'm going to quit this thread. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|