|
|
View previous topic :: View next topic |
Author |
Message |
newpic
Joined: 09 Aug 2005 Posts: 32
|
ccp1 using timer1 |
Posted: Mon Apr 04, 2011 1:37 pm |
|
|
I need capture help.
How can I capture a button that connect to CCP1 (RC2)?
if button pressed < 500msec === output high pin RB0
if button pressed > 500 msec === output high pin RB1
Code: | #include <p18f4620.h>
#include <delays.h>
#include <usart.h>
#include <stdio.h>
#define CapRise 0b00000101;
#define CapFall 0b00000100;
#define printf(a) printf((rom far char *)a)
unsigned int T1 = 0;
unsigned int T2 = 0;
unsigned int Width = 0;
void isr_high(void);
void isr_low (void);
void init(void);
#pragma idata
volatile unsigned char port_value = 0;
#pragma code
void main(void)
{
TMR1H = 0x00;
TMR1L = 0x00;
init();
while(1) // continuous loop
{
}
}
// interrupt setup
#pragma code high_vector=0x08
void high_vector (void)
{
_asm GOTO isr_high _endasm
}
#pragma code low_vector=0x18
void low_vector (void)
{
_asm GOTO isr_low _endasm
}
#pragma code
#pragma interrupt isr_high
void isr_high (void)
{
T1CON = 0b00000101; // 1:1 prescale, osc off, no synch, int clk, tmr1 on
T1 = CCPR1;
PIR1bits.CCP1IF = 0; // clear capture flag bit
CCP1CON = CapFall;
while(!PIR1bits.CCP1IF);
T2 = CCPR1;
PIR1bits.CCP1IF = 0; // clear capture flag bit
Width = (T2-T1);
if(Width < 500)
{
PORTBbits.RB0 = 1;
PORTBbits.RB1 = 0;
}
else
{
PORTBbits.RB0 = 0;
PORTBbits.RB1 = 1;
}
delay_ms(50);
printf("Pulse width =%d cycles\r\n",Width);
}
#pragma interruptlow isr_low
void isr_low(void)
{
// unused
}
void init(void)
{
// USART Setup
OpenUSART (USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 25); // 9600 bps @ 4MHz
// hardware setup
ADCON1 = 0b00001111; // A/D disabled
TRISC = 0x04; // RC2 CCP1 pin = input
PORTB = 0; // clear portb on POR
TRISB = 0; // all outputs
PORTA = 0;
TRISA = 0;
CCP1CON = CapRise; // capture on rising edge
// interrupt setup
PIR1bits.CCP1IF = 0; // clear capture flag bit
IPR1bits.CCP1IP = 1; // CCP1 int is high priority
PIE1bits.CCP1IE = 1; // enable CCP1 interrupt
RCONbits.IPEN = 1; // enable priority levels on interrupts
INTCON = 0b11000000; // global & peripheral ints enabled
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 04, 2011 1:45 pm |
|
|
You're using the Microchip C18 compiler. You're in the wrong forum.
This is the CCS compiler forum. You want the C18 forum, here:
http://www.microchip.com/forums/f3.aspx |
|
|
newpic
Joined: 09 Aug 2005 Posts: 32
|
timer1 |
Posted: Mon Apr 04, 2011 2:12 pm |
|
|
Ok,
I post the wrong code,
here it is
Code: |
#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#endif
long rise,fall,pulse_width;
#int_ccp2
void isr()
{
rise = CCP_1;
fall = CCP_2;
pulse_width = fall - rise; // CCP_1 is the time the pulse went high
// CCP_2 is the time the pulse went low
// pulse_width/(clock/4) is the time
// In order for this to work the ISR
// overhead must be less than the
// low time. For this program the
// overhead is 45 instructions. The
// low time must then be at least
// 9 us.
if(pulse_with > 500)
{
output_high(PIN_B0);
output_low(PIN_B1);
}
else
{
output_high(PIN_B1);
output_low(PIN_B0);
}
delay_ms(50);
}
void main()
{
printf("\n\rHigh time (sampled every second):\n\r");
setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise
setup_ccp2(CCP_CAPTURE_FE); // Configure CCP2 to capture fall
setup_timer_1(T1_INTERNAL); // Start timer 1
enable_interrupts(INT_CCP2); // Setup interrupt on falling edge
enable_interrupts(GLOBAL);
while(TRUE) {
delay_ms(1000);
printf("\r%lu us ", pulse_width/5 );
}
}
|
what do I divide pulse_width to in order to get the ms or sec instead of us?
I do not understand where do we get the /5 from? This is one of the example came with CCS compiler. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 04, 2011 2:23 pm |
|
|
Quote: | I do not understand where do we get the /5 from
|
The 20 MHz clock is divided by 4 to get the instruction clock. That's in
every PIC data sheet. Timer1 is clocked by the instruction clock.
So it's clocked at 5 MHz. It's counting in units of 1/5 of a microsecond.
If you get 5 counts, then it took 5us to do that. They want to display
the output in units of microseconds, so they divide the count by 5.
If you want to display in units of milli-seconds, then divide it by 5000
instead of 5. But you'll need to cast 'pulse_width' to a float, to get the
correct result from the math. And change the printf to "%7.3f" or
something similar. |
|
|
|
|
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
|