View previous topic :: View next topic |
Author |
Message |
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
tachometer with pic16f887 |
Posted: Mon Mar 02, 2009 7:52 am |
|
|
please help me with this code, trying to make a tachometer with pic16f887. only show me all the time 330.
Set CCP1 capture but in vain ....
where is wrong?
I put in main.c
ccp1_isr ();
turometru ();
where I wrong?
Code: |
#include "main.h"
#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 turometru()
{
int16 frecventa;
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);
frecventa = (frequency * 60)/2;
lcd_gotoxy(5,1);
printf(lcd_putc,"%lu\n", frecventa);
printf("%lu\n\r", frecventa);
// printf(lcd_putc,"%lu Hz, delta = %lx \n\r", frequency, current_ccp_delta);
gc_capture_flag = FALSE;
}
else
{
lcd_gotoxy(5,1);
printf(lcd_putc,"0 \n");
printf("0 \r");
}
delay_ms(100);
//}
}
|
Last edited by soulraven on Mon Mar 02, 2009 3:02 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 02, 2009 11:51 am |
|
|
I think you have some previous threads on this topic.
Describe the input signal:
1. What is the frequency (or the frequency range) of the signal ?
2. What is the amplitude of the signal ?
3. What are the high and low voltage levels of the signal ?
4. What type of signal is it ? Is a squarewave ? Rectangular waveform ?
Sinusoidal waveform ?
5. What is the duty cycle of the signal ?
6. What device is supplying the signal ? Where does the signal come from ? |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 02, 2009 12:07 pm |
|
|
My advice is, get a signal generator. Set it for 300 Hz, with a 0 to 5v
squarewave output, 50% duty cycle. Make your PIC and your code
work with that signal. Then try it with your automobile signal. |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
|
Posted: Mon Mar 02, 2009 12:10 pm |
|
|
to get up there, not even in my sim not working, I show number 330 on display ...
what can be? no longer captures well, I took the code from pic16f877a and I put on pic16f887 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 02, 2009 12:13 pm |
|
|
Was the code working with a 16F877A ? |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
|
Posted: Mon Mar 02, 2009 12:14 pm |
|
|
yes, the code above worked with 877a
887 but no longer works as it should, the display shows 330 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 02, 2009 12:22 pm |
|
|
What is your compiler version ? |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
|
Posted: Mon Mar 02, 2009 12:36 pm |
|
|
4.013 ccs c compiler |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 02, 2009 12:39 pm |
|
|
That's a very early version, and almost certainly has problems with
the setup of the peripherals (ADC, comparator, CCP, etc.).
Post the main() code with does the setup of the peripherals. |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
|
Posted: Mon Mar 02, 2009 12:43 pm |
|
|
main.c
Code: |
#include "main.h"
#include "voltmetru.c"
#include "meniu.c"
//#include "ds1820.c"
//#include "termometru.c"
#include "turometru.c"
void main()
{
lcd_init();
//porturi();
while(1)
{
//front_display2();
//temperatura();
//ccp1_isr();
ccp1_isr();
turometru();
//voltmetru();
//rezervor();
//alternator();
//temperatura();
}
} |
main.h
Code: |
#ifndef h_main
#define h_main
#include <16f887.h>
#device *=16
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8)
#include "flex_lcd.c"
extern void porturi()
{
setup_adc_ports(sAN0 | sAN1 | sAN2);
setup_adc(ADC_CLOCK_DIV_32);
}
#endif
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 02, 2009 12:55 pm |
|
|
The main() start-up code and the setup_ccp1() functions are messed up
in that version. If I have time and the inclination I will look at it later. |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
|
Posted: Wed Mar 04, 2009 6:27 am |
|
|
Any news? I have changed the compiler to 4.084 but no change......
Is possible to short the code...? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 04, 2009 11:13 am |
|
|
Quote: | #device *=16
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8) |
A 20 MHz crystal will not oscillate with the XT fuse. You must use
the HS fuse.
Also, don't use the LVP fuse. It can cause your PIC to lock-up if the PGM
pin goes to a high level. Use NOLVP. Do this in all your programs. |
|
|
soulraven
Joined: 08 Feb 2009 Posts: 72 Location: campulung muscel
|
. |
Posted: Wed Mar 04, 2009 11:37 am |
|
|
I managed to start the program, the problem was the electrical diagram.
I just some questions and questions:
1. below 50Hz is very unstable in display
2. If you use several command the ADC to measure temperature from the outside, with my influence tachometru?
3. conversion formula below is correct
frequency = (int16) ((5000000L + (current_ccp_delta>> 1)) / current_ccp_delta);
frequency = (frequency * 60) / 2; |
|
|
|