bigdogguru
Administrator
- Joined
- Mar 12, 2010
- Messages
- 9,821
- Helped
- 2,350
- Reputation
- 4,694
- Reaction score
- 2,272
- Trophy points
- 1,413
- Location
- Southwest, USA
- Activity points
- 62,394
Hi Romel,
You can use the #define MCLRE_OFF in the configuration bit sequence, to disable the MCLR and allow you to use the pin as a digital input, MCLR is internally tied to VDD.
However, notice it is only allowed to function as a digital input, not an output.
Note:
Timer1 must be running in timer mode or synchronized counter mode for the CCP
module to use the capture feature. In asynchronous counter mode, the capture
operation may not work.
bit 2 T1SYNC: Timer1 External Clock Input Synchronization Control bit
bigdogguru said:Did those links help explain the various CCP modes and T1SYNC?
If not let me know and I find some better examples.
I have to be in town tomorrow at 6:30AM, five hours from now, so I think I'll call it a night. I'll see what your up to in four hours or so, before I head into Albuquerque.
BigDog
When a capture is made, the interrupt request flag bit CCP1IF of PIR1 register is set. The interrupt flag must be cleared in software. If another capture occurs before the value in register CCPR1 is read, the old captured value will be lost.
In capture mode, CCPR1 captures the 16bit value of the TMR1 register when and even occurs on pin RB3/CCP1.
This bit is ignored. Timer1 uses the internal clock when TMR1CS = 0.
what is the unit of TMR1 during the event? is it in milliseconds or Microseconds?
......
okay I think it's in Ms.
I was wrong.What is the actual operating frequency (clock) of your timer?
#include<htc.h>
#include"ccpmodule.h"
void init_capture()
{
TRISAbits.TRISA3 = 1; //configure as input pin
CCP1CON |= 0b0100; //Capture mode, every falling edge
TMR1IE = 1; //Enables the TMR1 overflow interrupt
T1CON |= 1; //enable timer 1
CCP1IE = 1; //Enables the CCP1 interrupt
PEIE = 1; //Enables all unmasked peripheral interrupts
GIE = 1; //Enables all unmasked interrupts(Global)
}
void interrupt capture_time()
{
if(CCP1IF) //CCp module Interrupt.. meaning event detected
{
period = CCPR1; // transfer captured time to variable period
CCP1IF = 0; // clear flag
}
if ( TMR1IF ) //timer1 over flow
{
RA7 = !RA7; //toggle port just to check if timer 1 overflows
TMR1 = 0; //clear content of TMR1
TMR1IF = 0; //clear timer1 flag
}
}
What I will do next is Store the period of first capture and the period of second capture so that is = to 1 revolution or 1 period of a pulse
to compute:
pulse2(period) - pulse1(period) = total time period
F = 1/(total time period)
RPM = 60 * f .
does it make sense?
I believe you want to calculate the period of revolution based on the time of pulse2 minus the time of pulse1 equals duration or period of revolution.
Pulse2Time - Pulse1Time = Period of Revolution = T
Frequency of Revolution = 1/T = rev/sec = f
RPM = 60sec/minute * rev/sec = 60 * f
I'll check your code next.
BigDog
Capture is 16-bit, max. resolution is 12.5 ns
this can be done in one step instead of the method described in post #69, you can choose any of the two
pulse2(period) - pulse1(period) = total time period
#include<htc.h>
#include"ccpmodule.h"
void init_capture()
{
TRISAbits.TRISA3 = 1; //configure as input pin
CCP1CON |= 0b0100; //Capture mode, every falling edge
T1CON |= 1; //enable timer 1
CCP1IE = 1; //Enables the CCP1 interrupt
TMR1IE = 1; //Enables the TMR1 overflow interrupt
PEIE = 1; //Enables all unmasked peripheral interrupts
GIE = 1; //Enables all unmasked interrupts
}
void interrupt capture_time()
{
if(CCP1IF) //event detected
{
CCP1IF = 0; // clear flag
count++; //count event
if(count == 1) //log first event
time1 = CCPR1; //save time of event1
if(count == 2) //log second event
{
time2 = CCPR1; //save time of event2
count = 0; //clear counter
}
/* this will lower the resolution of timer if the pulse is slow */
/* change pre-scaller to 8 when timer overflows before pulse 2 */
if(count == 1 && TMR1IF == 1)
adjust_scaler = 1; //activate auto-prescaller
}
if(TMR1IF) //clear timer flag
{
TMR1IF = 0; //clear flag
TMR1 = 0; //clear timer value
}
}
void adjust()
{
GIE = 0; //disable interrupts
time1 = 0;
time2 = 0;
TMR1IF = 0;
adjust_scaler = 0;
CCP1IF = 0;
count = 0;
T1CON |= 0x30; //change scaller to 1:8
GIE = 1; //enable interrupts
}
#include<htc.h>
#include"lcd.h"
#include"ccpmodule.h"
__CONFIG(FOSC_INTOSCIO & PWRTE_ON & WDTE_OFF & MCLRE_ON & CPD_OFF & BOREN_OFF & CP_OFF & LVP_OFF);
void main()
{
unsigned long rpm;
char freq;
init_capture(); //initialize ccp module for capture mode
delayms(10);
lcd_init(); //initalizw LCD
delayms(10);
while(1)
{
lcd_cmd(0xc0);
lcd_str("testing");
lcd_cmd(0x80);
if(adjust_scaler == 1) //lower timer resolution
adjust();
/*code here
for displaying something in LCD */
time1 = 0;
time2 = 0;
if(adjust_scaler == 0)//change scaller to 1:1
{
T1CKPS1 = 0;
T1CKPS0 = 0;
}
}
}
#include<htc.h>
#include"lcd.h"
#include"capture.h"
#include"long2string.h"
__CONFIG(WDTE_OFF & PWRTE_ON & MCLRE_ON & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & FOSC_INTRCIO);
void main()
{
char RPM[12]; /*buffer for display */
ANSEL = 0x01; /*set RA0 as analog input */
ANSELH = 0; /* Set PORT ANS10 as Digital I/O */
init_capture();
lcd_init();
while(1)
{
lcd_cmd(0x80);
lcd_str("RPM:");
lcd_cmd(0x84);
if(display == 1)
{
display = 0;
long_to_string(countrev,RPM,10);
lcd_str(RPM);
countrev = 0;
}
}
}
#include"long2string.h"
/*
*********************************************************************************************************
* long_to_string()
*
* Description : Convert a "long" to a null-terminated string
* (base = decimal)
* Arguments : input = number to be converted
* str = pointer to string (i.e. display buffer)
* numdigits = number of digits to display
* Returns : none
*********************************************************************************************************
*/
void long_to_string (unsigned long input, char *str, char numdigits)
{
char digit;
char blank = TRUE;
long_to_string_lz(input, str, numdigits);
for (digit=0; digit < numdigits-1; digit++) {
if (str[digit] == '0') {
if (blank == TRUE) str[digit] = ' ';
}
else {
blank = FALSE;
}
}
}
/*
*********************************************************************************************************
* long_to_string_lz()
*
* Description : Convert a "long" to a null-terminated string, with leading zeros
* (base = decimal)
* Arguments : input = number to be converted
* str = pointer to string (i.e. display buffer)
* numdigits = number of digits to display
* Returns : none
*********************************************************************************************************
*/
void long_to_string_lz (unsigned long input, char *str, char numdigits)
{
char digit;
for (digit=numdigits; digit > 0; digit--) {
str[digit-1] = (input % 10) + '0';
input = input / 10;
}
str[numdigits] = 0; // null-terminate the string
}
#include<htc.h>
#include"lcd.h"
void delayus(unsigned char delay){
while(delay--);
}
void delayms(unsigned char delay){
while(delay--)
delayus(149);
}
void lcd_reset()
{
LCD = 0xFF;
delayms(40);
LCD = 0x03+LCD_EN;
LCD = 0x03;
delayms(40);
LCD = 0x03+LCD_EN;
LCD = 0x03;
delayms(5);
LCD = 0x03+LCD_EN;
LCD = 0x03;
delayms(5);
LCD = 0x02+LCD_EN;
LCD = 0x02;
delayms(5);
}
void lcd_init ()
{
TRISC = 0x20;
//CMCON |= 111; //make RA3:RA0 as digital and disable comparator
lcd_reset();
lcd_cmd(LCD_SETFUNCTION); // 4-bit mode - 1 line - 5x7 font.
lcd_cmd(LCD_SETVISIBLE+0x04); // Display no cursor - no blink.
lcd_cmd(LCD_SETMODE+0x02); // Automatic Increment - No Display shift.
lcd_cmd(LCD_SETDDADDR); // Address DDRAM with 0 offset 80h.
}
void lcd_cmd (char cmd)
{
LCD = ((cmd >> 4) & 0x0F)|LCD_EN;
LCD = ((cmd >> 4) & 0x0F);
LCD = (cmd & 0x0F)|LCD_EN;
LCD = (cmd & 0x0F);
delayus(250);
delayus(250);
}
void lcd_data (unsigned char dat)
{
LCD = (((dat >> 4) & 0x0F)|LCD_EN|LCD_RS);
LCD = (((dat >> 4) & 0x0F)|LCD_RS);
LCD = ((dat & 0x0F)|LCD_EN|LCD_RS);
LCD = ((dat & 0x0F)|LCD_RS);
delayus(250);
delayus(250);
}
void lcd_str (unsigned char *str)
{
while(*str)
lcd_data(*str++);
}
#include<htc.h>
#include"capture.h"
void init_capture()
{
TRISCbits.TRISC5 = 1; //configure as input pin
CCP1CON |= 0b0100; //Capture mode, every falling edge
TMR1ON = 1; //enable timer 1
TMR1IE = 1; //Enables the TMR1 overflow interrupt
CCP1IE = 1; //Enables the CCP1 interrupt
PEIE = 1; //Enables all unmasked peripheral interrupts
GIE = 1; //Enables all unmasked interrupts
}
void interrupt capture()
{
static char count = 0;
if(CCP1IF)
{
CCP1IF = 0;
countrev++;
}
else if(TMR1IF)
{
TMR1IF = 0;
count++;
if(count == 15) //1second timer
{
count = 0;
countrev = countrev*60; /* total RPM */
display = 1; /* activate display */
}
}
}
__CONFIG(WDTE_OFF & PWRTE_ON & MCLRE_ON & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & FOSC_INTRCIO);
hello guys. It's now working as it should be..
Im using 4Mhz internal crystal of PIC16f690 and I use this formula for timer 1
Instead of combining CCP module and timer1 module I decided to make timer1 as independent counter to count up to 1sec then calculate the RPM.
I will post my code here for future use of other members.. I thinks it correct lol...
Follow up question.
Im not sure with my configuration bits.
PHP:__CONFIG(WDTE_OFF & PWRTE_ON & MCLRE_ON & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & FOSC_INTRCIO);
is that correct? what I want to do is use the internal oscillator and make RA4 and RA5 as digital I/O..
May like to try out a Tx/Det. pair using IR LEDs ..Place a silver reflective dot on the commutator and checkout the pulse frequency recd.
This needs be fed to an F to V converter for getting instantaneous data on the slip of the rotors.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?