Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top