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

Frequency reading using PIC
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

Frequency reading using PIC
PostPosted: Thu Jun 18, 2009 11:13 am     Reply with quote

Dear clever people

After browsing your wonderful forum, I found many topics that related to what I was looking for, but unfortunately didn’t work nicely for me, and I’m really looking forward for your help as I am very new to PIC programming Embarassed .

I am trying to make a frequency measuring application that can find a useful frequency range for me and I have found the following code in your forum which I have modified the last part of it for the ranges that I am looking for.

The problem is that when I flash the PIC and run it for the first time it detects the right frequency range and the LED flashes the right way but when I change the frequency nothing happens i.e. the LED flashing sequence doesn’t change.

In more details, that if I set my function generator to generate 70 Hz frequency and then I flash and run the PIC I get the right LED flashing that corresponds to 70 Hz, but now if I change the frequency to 28 Hz I don’t get the right output, the LED keeps flashing just like the 70Hz case.

It looks to me that’s either the frequency variable doesn’t get updated while the program is running or the program stuck in one of the loops and it doesn’t go out of it.

Please I am really stuck and need your help and advice in this matter.

Thanks in advance for your help.

Pin 8 is connected to square-wave generator (0-5v amp)
Pin 10 is connected to LED
PIC used 16F819
Code:
#include <16F819.H>
#fuses NOWDT, NOPROTECT, NOLVP,INTRC_IO, NOPUT, NOMCLR,NOBROWNOUT, NOCPD, NOWRT, NODEBUG
#use delay(clock=4000000)


// This global variable holds the time interval
// between two consecutive rising edges of the
// input signal.
   
int16 isr_ccp_delta;



// When a rising edge occurs on the input signal,
// the CCP1 will 'capture' the value of Timer1
// at that moment.  Shortly after that, a CCP1
// interrupt is generated and the following isr
// is called.   In the isr, we read the 'captured'
// value of Timer1.  We then subtract from it the
// Timer1 value that we 'captured' in the previous
// interrupt.  The result is the time interval
// between two rising edges of the input signal.
// This time interval is then converted to a frequency
// value by code in main(). 

#int_ccp1
void ccp1_isr(void)
{
int16 current_ccp;
static int16 old_ccp = 0;


current_ccp = CCP_1;  // From 16F819.H file

// 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_ccp_delta = current_ccp - old_ccp;

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


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

setup_oscillator(OSC_4MHZ);      //use internal 4MHz clock

// Setup Timer1 and CCP1 for Capture mode so that
// we can measure the input signal's frequency.
// The input signal comes from an external function 
// generator, which is connected to the CCP1 pin 8 with a wire.


set_timer1(0);           
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); 
setup_ccp1(CCP_CAPTURE_RE);   

// 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_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);


while(1)
  {

   // 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(GLOBAL);
   current_ccp_delta = isr_ccp_delta;
   enable_interrupts(GLOBAL);
   

   // To calculate the frequency of the input signal,
   // we take the number of clocks that occurred
   // between two consecutive edges of the input signal,
   // and divide that value into the number of Timer1
   // clocks per second.   Since we're using a 4 MHz
   // internal clock, the Timer1 clock is 1 MHz (Timer1 runs
   // at the instruction cycle rate, which is 1/4 of the
   // internal clock frequency).  For example, suppose the
   // the input waveform has a frequency of 244 Hz.
   // 244 Hz has a period of about 4098 usec.
   // Timer1 is clocked at 1 MHz, so between two
   // consecutive rising edges of the input signal,
   // it will count up by 4098 clocks.  To find the
   // frequency, we divide 4098 into the number of
   // clocks that occur in 1 second, which is 1000000.
   // This gives 1000000 / 4098 = 244 Hz.

   frequency = (int16)(125000L / current_ccp_delta);
   // Display the calculated frequency.
   
     if (frequency <= 30)   
      do {
         output_high(PIN_B4);
         delay_ms(5000);
         output_low(PIN_B4);
         delay_ms(5000);
         }
         while (TRUE);

   else if (frequency >= 31 && frequency <= 59)   
      do {
         output_high(PIN_B4);
         delay_ms(700);
         output_low(PIN_B4);
         delay_ms(1500);
         output_high(PIN_B4);
         delay_ms(300);
         output_low(PIN_B4);
         delay_ms(600);
         }
         while (TRUE);
     
   else
         do {
         output_high(PIN_B4);
         delay_ms(500);
         output_low(PIN_B4);
         delay_ms(500);
         }
         while (TRUE);
       
   
   }   //end while(1)

}  // end main
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 11:25 am     Reply with quote

Display the frequency numbers in a terminal window on your PC.
Then you can see where the problem is.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 11:40 am     Reply with quote

Dear PCM programmer

Thanks a lot for your quick reply but I have no idea about what are you talking about can you please explain a bit more as I am coming from Mechanical engineering background and I'm not get used to programming talk.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 11:42 am     Reply with quote

Did you build the PIC board yourself, or did you buy the board ?
If you bought it, post the manufacturer, model number, and a link
to the website for the board.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 11:53 am     Reply with quote

Dear PCM programmer

Thanks again for your quick reply

Yes I have built the PIC board by myself and I programmed it using MPLAB ICD2 programmer made by microchip
ECACE



Joined: 24 Jul 2006
Posts: 94

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 12:24 pm     Reply with quote

After a quick glance, it looks like your ISR is clearing the old value every time you go into it, at the start of your ISR.

Then at the end of your ISR, you save the current value as the old value.

But when you go back into your ISR, right away you blow away the old value you had saved the last time you were there.

Maybe I'm off on that, but that is what it is looking like to me.

Code:

#int_ccp1
void ccp1_isr(void)
{
int16 current_ccp;
static int16 old_ccp = 0;       ********* Right here you are blowing away any old value
                                ********* that you had saved the last time through.
                                ********* Is that really what you want to do?


current_ccp = CCP_1;
isr_ccp_delta = current_ccp - old_ccp;

old_ccp = current_ccp;          ********* Here you are saving your old_ccp value,
                                ********* But the next time you come into the ISR you blow it away
}

_________________
A HW Engineer 'trying' to do SW !!! Run!!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 12:33 pm     Reply with quote

No it's not clearing it every time. It's only cleared upon program start-up.


nizar445:
Please an RS-232 capability to your board. Add a Max232-type chip
and a DB-9 connector. Get a serial port cable. Then you will be
about to display debugging information on your PC. It will be much
easier to fix problems in your code.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 2:02 pm     Reply with quote

Dear ECACE

I have tried to replace "static int16 old_ccp = 0;" with "int16 old_ccp" but no luck

Thanks a lot for your help
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 2:11 pm     Reply with quote

Dear PCM programmer

Thanks again for your response,
Can you please explain a bit more to me about how is this chip will help me to find the code problem?

Also I found this product which is called “MAX232 RS232 to TTL Converter Board for MIC PIC Atmel” is that the one you meant. Please have a look at it in the following link:

http://www.virtualvillage.co.uk/max232-rs232-to-ttl-converter-board-for-mic-pic-atmel/sku003602-008
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 2:13 pm     Reply with quote

That adapter board would work. You can connect the Tx, Rx, and GND
pins to your PIC board. You also need a DB-9 serial cable to connect
the board to your PC.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 2:24 pm     Reply with quote

Dear PCM programmer

Thanks again, I will buy this board now.

Can you please tell me to which pins on the PIC I should connect these pins (Tx, Rx, and GND) and how is the PIC will communicate with this board, please note that my programming knowledge is very poor Embarassed
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 2:35 pm     Reply with quote

There is no schematic of the board on that web page, so I don't know
for certain how to connect it to your PIC.

Based on the photo, I can say:

Connect the Vcc pin to +5v on your board.
Connect the GND pin to GND on your board.


The TXD and RXD pins would go to the Rx and Tx pins on your PIC
board, but I'm not certain if they go TXD to Rx, or TXD to Tx,
because there is no schematic. I can't help any more on this.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 2:47 pm     Reply with quote

Dear PCM programmer

Thanks again and I'm so sorry for bothering you with my problem. But the PIC hasn’t got Rx and Tx pins please have a look at the following PIC pins diagram:

http://www.caveo.com.ar/images/16f819.gif

By the way; is there any other method that I can use to find the code error?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 18, 2009 3:13 pm     Reply with quote

Then you need to use a software UART. This can easily be done with
the #use rs232() statement in CCS. Just specify two spare i/o pins for
'rcv' and 'xmit'.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Sat Jun 20, 2009 5:04 pm     Reply with quote

Dear PCM programmer

Thanks in advance for your help, I have got the MAX232 serial adapter now and it has 4 pins (GND, V+, TX, RX)

My question is, to which pins in the PIC, I need to connect the TX and RX pins? Can I connect them to Pin11 (RB5) and Pin12 (RB6)?

http://www.caveo.com.ar/images/16f819.gif

Also did you mean that I need to add the following code to the original programme in order to see my output? (By the way, this code has been used in previous thread in this forum and I have no idea about what its doing exactly, all what I know it allows me to use some sort of serial data!)

Code:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)


Finally could you please tell me how I can display the frequency numbers in a terminal window on my PC??

Thanks again for your help and I am looking forward for your reply.
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 1, 2, 3  Next
Page 1 of 3

 
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