Capturing the signal using CCP1CON

Status
Not open for further replies.

mattycha

Newbie level 5
Joined
Aug 30, 2008
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,343
Hi. I am trying to replicate a project from best-microcontroller-example.

This is an ultrasonic range dectector project. Initially, it's written in 16F88

but I am changing into 18F2455. Also, original code was written in mikroC

but I am switching to C18.



The problem I am having is that even though my US range detector is

about 11cm about from the wall, the LCD reading is 23641......

I am not sure why the LCD is displaying such a large value. I changed the

binary into decimal using a function "putdec". I am using 20MHz crystal and

I calculated to produce a period of 40kHz on RC1. RC2 is the receiving pin,

trying to capture the signal using CCP1CON=0b00000101.

Code:
#include <p18f2455.h>
#include <delays.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config LVP = OFF
#pragma config MCLRE = ON

#pragma interrupt MyHighInt
#pragma code high_vector=0x08

void MyHighInt(void);
void high_vector(void);
void enable_interrupts(void);
void disable_interrupts(void);
void ultrasonic(void);
void display(unsigned int value);
void welcome();
void clearLCD();
void writeData(unsigned char data);
void sendData(unsigned char data);
void writeString(const char rom *str);
void putdec(unsigned int n);

unsigned int T1_O = 0; //timer1 overflow updated in interrupt routine
unsigned int t_capL = 0; //timer1 low
unsigned int t_capH = 0; //timer1 high
unsigned int t_capO = 0; //timer1 overflow
unsigned int CapVal = 0; //capture 
unsigned short CapInt = 0; //captured something in interrupt routine
unsigned short CapOn = 1; //capture only 1st value

#define send PORTCbits.RC1
#define LCDData PORTB
#define rs PORTAbits.RA3
#define rw PORTAbits.RA2
#define en PORTAbits.RA5

void high_vector(void)
{
 _asm GOTO MyHighInt _endasm
}

#pragma code

void MyHighInt(void)
{
 if(PIR1bits.TMR1IF == 1)
 {
  PIR1bits.TMR1IF = 0; //clear timer1 overflow bit
  T1_O++;
 }
 
 if(PIR1bits.CCP1IF == 1)
 {
  PIR1bits.CCP1IF = 0; //clear capture flag
  
  if(CapOn == 1)
  {
   CapOn = 0;
   t_capL = CCPR1L;
   t_capH = CCPR1H;
   t_capO = T1_O;
   CapInt = 1;
  }
 }
}   

void main(void)
{
 unsigned int val, s1, s2, tH, tL, tO;
 unsigned long calc = 0;

 CCP1CON = 0b00000101; //CCP to capture every rising edge
 T1CONbits.TMR1ON = 1; //timer1 on
 ADCON0 = 0;
 ADCON1 = 0x0F;
 PORTB = 0;
 TRISB = 0;
 TRISCbits.TRISC1 = 0; //
 TRISCbits.TRISC2 = 1; //receive US signal
 // LCD
    TRISAbits.TRISA3 = 0;
    TRISAbits.TRISA2 = 0;
    TRISAbits.TRISA5 = 0; 
 rs = 0;
 rw = 0;
 en = 0;

 CapInt = 0; //reset capture indicator
 
 for(;;)
 {
  CapOn = 1; //allow one capture value
  tO = T1_O; //get the current value
  tH = TMR1H;
  tL = TMR1L;
  
  t_capL = 0; t_capH = 0; t_capO = 0; //initialize capture
  
  ultrasonic();
  enable_interrupts();
  display(val);
  disable_interrupts();
  
  if(CapInt == 0) //no echo??
  {
   enable_interrupts();
   display(val);
   disable_interrupts(); 
  }
  
  else if(CapInt == 1) //captured anything??
  {
   CapInt = 0; //reset for next time
   s1 = (t_capH - tH);
   s2 = (t_capL - tL);
   calc = ((s1<<8))+s2;
   calc *= 34;
   calc /= 10000;  //(1/20MHz)*340m/s*100cm/m*2
   val = (int)calc;
   display(val);
  }
  clearLCD();
 }
} 

     

void enable_interrupts(void)
{
   PIR1bits.TMR1IF = 0; //timer1
   PIR1bits.CCP1IF = 0; //capture
   PIE1bits.CCP1IE = 1; //interrupt enable
   INTCONbits.GIE = 1; //enable global interrupt
   INTCONbits.PEIE = 1; //enable peripheral interrupt
}



void disable_interrupts(void)
{
   INTCONbits.GIE = 0; //disable global interrupt
   INTCONbits.PEIE = 0; //disable peripheral interrupt 
}



void ultrasonic(void)
{
 send = 1;
 Delay10TCYx(6);
 Delay1TCY();
 Delay1TCY();
 Delay1TCY();
 send = 0;
 Delay10TCYx(6);
 Delay1TCY();
 Delay1TCY();
  
 send = 1;
 Delay10TCYx(6);
 Delay1TCY(); 
 Delay1TCY();
 Delay1TCY();
 send = 0;
 Delay10TCYx(6);
 Delay1TCY();
 Delay1TCY();
 
 send = 1;
 Delay10TCYx(6);
 Delay1TCY();
 Delay1TCY();
 Delay1TCY();
 send = 0;
 Delay10TCYx(6);
 Delay1TCY();
 Delay1TCY();



 send = 1;
 Delay10TCYx(6);
 Delay1TCY();
 Delay1TCY();
 Delay1TCY();
 send = 0;
 Delay10TCYx(6);
 Delay1TCY();
 Delay1TCY();
}



void display(unsigned int value) {
 welcome();
 sendData(0xC0);   // line 2, position 0
 writeString("Dist:");
 sendData(0xC5);
 putdec(value);
 Delay1KTCYx(5000); //wait for 1second
}



void welcome()
{
   Delay1KTCYx(250);          // Wait 20ms 
   sendData(0x38);     // Set LCD to 8-bit operation, 2-line display and 5 x 8 dot character font 
   Delay1KTCYx(250);          // Wait 2ms 
   sendData(0x0E);     // Turn LCD display off, cursor off and blinker off 
   Delay1KTCYx(15);          // Wait 2ms 
   sendData(0x01);     // Clear LCD display 
   Delay1KTCYx(15);          // Wait 2ms 
   sendData(0x06);     // Set LCD entry mode to increment by one and to shift the cursor to the right. No display shift. 
    
    sendData(0x80);
    writeString("Ultrasonic in cm");
}
    
void clearLCD()
{
   Delay1KTCYx(250);          // Wait 20ms 
   sendData(0x38);     // Set LCD to 8-bit operation, 2-line display and 5 x 8 dot character font 
   Delay1KTCYx(250);          // Wait 2ms 
   sendData(0x0E);     // Turn LCD display off, cursor off and blinker off 
   Delay1KTCYx(15);          // Wait 2ms 
   sendData(0x01);     // Clear LCD display 
   Delay1KTCYx(15);          // Wait 2ms 
   sendData(0x06);     // Set LCD entry mode to increment by one and to shift the cursor to the right. No display shift. 
}
 
void sendData(unsigned char data) { 
   LCDData = data; 
   rs = 0; 
   rw = 0;
   en = 1; 
   Delay1KTCYx(1); 
   en = 0; 
} 

void writeData(unsigned char data) { 
   LCDData = data; 
   rs = 1; 
   rw = 0;
   en = 1; 
   Delay1KTCYx(1); 
   en = 0; 
} 

void writeString(const char rom *str) { 
    while( *str ) { 
    writeData(*str); 
    str++;    
   } 
}

void putdec(unsigned int n)
{
    unsigned int rem  = n % 10;
    unsigned int quot = n / 10;
    if (quot > 0) 
    {
        putdec(quot);
    }
    writeData(rem + '0');
}

Could someone please explain what I am doing wrong here? How can I fix

the problem so I can display a correct range??
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…