CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

CCP / 24 bit timer / 1hz to 150 hz range
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Salenko



Joined: 08 Sep 2008
Posts: 84

View user's profile Send private message

PostPosted: Fri Jun 12, 2009 3:32 am     Reply with quote

Dear PCM Programmer,

you solved my problem Smile , thank you.

now I'm getting 1 Hz into my Terminal. this is a progress but the display remains imprecise, in fact, the frequency of the received signal is around 1.42hz, while I'm getting 1 Hz ,then I made the flowing changes (in bold):

Quote:
float frequency;

frequency = (float) ((2500000L + (current_ccp_delta >> 1)) / current_ccp_delta);

printf("------%f Hz\n\r", frequency);



I got 1.00 Hz , is there anything else to change to get the correct decimal. Wink

Salenko.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jun 12, 2009 1:00 pm     Reply with quote

You are doing integer math which has no decimal fraction result, and
then casting the integer as float. It will always have .00 on end.

You need to force it to do floating point math inside the equation.
The equation consists of a division of two terms. The top term
is an addition, within parentheses. Solution: Cast either the top
term or the bottom term to a float. This forces the division to be
done in floating point. It's easiest just to stick it in front of the
bottom term:
Quote:

frequency = ((2500000L + (current_ccp_delta >> 1)) / (float)current_ccp_delta);


Also, be aware that some versions of the CCS compiler (not sure which
ones) need Width and Precision numbers to be specified in the "%f"
field, in order for printf to work properly. The first number must be
higher than the 2nd number. Example: "%7.2f"
Salenko



Joined: 08 Sep 2008
Posts: 84

View user's profile Send private message

PostPosted: Fri Jun 12, 2009 1:48 pm     Reply with quote

Dear PCM,

for the nth time, thank you.

you are doing a great job in this forum.
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Wed Sep 30, 2009 8:05 am     Reply with quote

Dear PCM,

I just tried your code and it doesnt worked for me. Im using pic 18f2580 with external oscillator 20MHz.

In rs232 not even print "Non signal". What is wrong with this?

Code:
#include <18F2580.H>
#fuses NOWDT, PUT, BROWNOUT, NOLVP // 20 MHz xtal
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#priority CCP1, TIMER1


#define BytePtr(var, offset) (char *)((char*)&var + offset)

#byte PIR1 = 0xF9E
#bit  TMR1IF = PIR1.0

int8  gc_timer1_extension = 0;
int8  gc_capture_flag = FALSE;
int32 g32_ccp_delta;

//------------------------------------------------------
#int_timer1
void timer1_isr(void)
{
gc_timer1_extension++;
}

//------------------------------------------------------

#int_ccp1
void ccp1_isr(void)
{
char timer_ext_copy;
int32 current_ccp;
static int32 old_ccp = 0;

gc_capture_flag = TRUE;       

current_ccp = (int32)CCP_1;   

// Get local copy of the timer ext.
timer_ext_copy = gc_timer1_extension;


if(TMR1IF)
  {
   if(*BytePtr(current_ccp, 1) < 2)  // Was CCP captured after Timer1 wrapped?
      timer_ext_copy++;  // If so, inc the copy of the timer ext.

   // Since we know a timer interrupt is pending, let's just
   // handle it here and now.  That saves a little load off
   // the processor.
   gc_timer1_extension++;  // Increment the real timer extension
   TMR1IF = 0;     // Then clear the Timer1 interrupt
  }

// Insert the timer extension into the proper place in the 32-bit
// CCP value.
// ie.,  Insert it into location "EE" as follows: 0x00EEnnnn
// (nnnn = the CCP).
*BytePtr(current_ccp, 2) = timer_ext_copy;

g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);

// Save the current ccp value for next time.
old_ccp = current_ccp;

}

//=======================
void main()
{
int16 frequency;
int32 current_ccp_delta;

set_timer1(0);           
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   

setup_ccp1(CCP_CAPTURE_RE);   

// Enable interrupts.
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);

clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);

enable_interrupts(GLOBAL);


while(1)
  {
   disable_interrupts(GLOBAL);
   current_ccp_delta = g32_ccp_delta;;
   enable_interrupts(GLOBAL);

   if(gc_capture_flag == TRUE)
     {
      frequency = (int16)((5000000L + (current_ccp_delta >> 1)) / current_ccp_delta);

      printf("%lu Hz\n\r", frequency);
//      printf("%lu Hz, delta = %lx \n\r", frequency, current_ccp_delta);

      gc_capture_flag = FALSE;
    }
  else
    {
     printf("No signal\n\r");
    }

  delay_ms(500);
 }

}
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Wed Sep 30, 2009 8:32 am     Reply with quote

I just change the fuses to
Code:
#fuses HS
and its working now
but only at 1Hz im getting on terminal:

1 Hz
no signal
1 hz
no signal
no signal
1Hz

and so on...

why ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 30, 2009 11:37 am     Reply with quote

The problem is probably because:

1. The voltage levels of your input signal are too low. They need
to be at least 0v to 4v levels. (For a PIC running at 5v).

2. Your input frequency may not be in the correct range to work
with the Timer1 prescaler and the frequency divisor in the posted code.

3. Your input signal may not be a normal, continuous squarewave.


What is the frequency of your input signal ?
What are the voltage levels of your input signal ?
Is it a normal continuous squarewave ?
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Wed Sep 30, 2009 2:07 pm     Reply with quote

PCM programmer wrote:
The problem is probably because:

1. The voltage levels of your input signal are too low. They need
to be at least 0v to 4v levels. (For a PIC running at 5v).

2. Your input frequency may not be in the correct range to work
with the Timer1 prescaler and the frequency divisor in the posted code.

3. Your input signal may not be a normal, continuous squarewave.


What is the frequency of your input signal ?
What are the voltage levels of your input signal ?
Is it a normal continuous squarewave ?


the input signal is a normal continuous squarewave with 1Hz, 0v-5v.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 30, 2009 4:02 pm     Reply with quote

For low frequency operation, change these things:

1. Change the declaration of the 'frequency' variable to a float:
Code:

void main()
{
float frequency;


2. Change the while(1) loop to this:

Code:
while(1)
  {

   if(gc_capture_flag == TRUE)
     {
      disable_interrupts(GLOBAL);
      current_ccp_delta = g32_ccp_delta;;
      enable_interrupts(GLOBAL);

      frequency =  (5000000L / (float)current_ccp_delta);
      printf("%4.2f\n\r", frequency);

      gc_capture_flag = FALSE;
     }
 
  }

I did those changes, and put in signal from my B&K Function Generator
that was the lowest possible frequency (0.4 Hz). Then I turned the
frequency adjust knob slowly so it went up to 2 Hz. Here is the output:
Quote:

0.41
0.41
0.41
0.40
0.41
0.47
0.62
0.75
0.89
0.96
0.99
1.02
1.06
1.14
1.24
1.36
1.46
1.60
1.62
1.76
1.93
2.02
2.08
2.09
2.08
2.09
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Fri Oct 16, 2009 8:23 am     Reply with quote

I recently switch from external 20MHz xtal to the internal osc 4Mhz...and now i dont know why, the program just stop.

Im debugging via rs232 and around 100Hz+ to 300Hz input, it stops sending data to rs232.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 16, 2009 2:51 pm     Reply with quote

If you lower the oscillator from 20 MHz down to 4 MHz, then you need
to also change the numerator in the frequency equation from 5 million
down to 1 million, as shown below in bold:
Quote:
frequency = (1000000L / (float)current_ccp_delta);


I don't know why it would stop doing output. You probably changed
something else. The input levels might be incorrect, or the cable
connection is bad.
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Tue Dec 15, 2009 10:58 am     Reply with quote

I return to 20Mhz Xtal because that problem.

In tests, while i change the frequency sometimes the output pull to a different value.

Example:
I increase the frequency from 10Hz to 100Hz, while the output is increasing sometimes im getting weird values. Like getting 10Hz output when the frequency is reaching 80Hz.

Another thing, what is the best way to use watchdog without corrupt the output.
Because i add WTD2048 Fuse to my program and Setup_WDT(WDT_ON) to main code, but when the PIC reset per example with a 20Hz input, the next output immediately after the reset is weird.

thks
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Fri Dec 18, 2009 9:06 am     Reply with quote

anyone ? Sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Dec 18, 2009 10:42 am     Reply with quote

Quote:

I increase the frequency from 10Hz to 100Hz, while the output is
increasing sometimes im getting weird values. Like getting 10Hz
output when the frequency is reaching 80Hz.

You could use a Median Filter to fix the problem. If you get an
occasional bad output from the tachometer code, this filter will remove it:
http://www.ccsinfo.com/forum/viewtopic.php?t=3462
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Wed Jan 06, 2010 9:10 am     Reply with quote

PCM programmer wrote:
Quote:

I increase the frequency from 10Hz to 100Hz, while the output is
increasing sometimes im getting weird values. Like getting 10Hz
output when the frequency is reaching 80Hz.

You could use a Median Filter to fix the problem. If you get an
occasional bad output from the tachometer code, this filter will remove it:
http://www.ccsinfo.com/forum/viewtopic.php?t=3462


Thanks, it is much better now Razz
Macas



Joined: 09 Jun 2009
Posts: 13

View user's profile Send private message

PostPosted: Fri Jan 22, 2010 7:54 am     Reply with quote

New question eheh!

I'm getting problems on WDT and the output.

Example:

Output: 32
Output: 32
Output: 32
Output: 32
Output: 32
Output: 32
WDT
Output: weird value
Output: 32
Output: 32
Output: 32

and so on...

How can I avoid that weird value next to WDT?

Thanks in advance
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4, 5, 6  Next
Page 4 of 6

 
Jump to:  
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