Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC Sonar C souce code modification

Status
Not open for further replies.

tariq7868

New Member
Hello ,
I am making PIC sonar range finder of which wircuit was available at A PIC sonar (ultrasonic) range finding project. ,now i want to modify its c code such as that instead of displaying the distance in cm on 7Segment,it gives me value of distance in binary at portA, but as at the web it says that it can measure upto 3m=300cm but as 8bit can represent only 0-255 ,,, so please help me out with it ,
The c souce code :
<Sorry, Attachment option seems to be not working>

//////////////////////////////////////////////////////////////////////
//
// File: 16F88_Ultrasonic_ranger.c
//
// Author: J F Main.
//
// Description:
//
// Range finding by generation and reception of
// ultrasonic audio at 40kHz.
//
// Compiler : mikroC, mikroElektronika C compiler
// for Microchip PIC microcontrollers
// Version: 5.0.0.3
//
// Note Testing:
//
// Tested on 16F88
//
// Requirements:
//
// 40kHz Ultrasonic amplifier (transistor amp).
//
// 40kHz ultrasonic transducer - for different transducers
// e.g. for a 32kHz transducer change the software appropriately.
//
// Target : 16F88
//
// Notes :
//
// For the CCP module (16F88):
// Which pin is used is controlled by bit 12 of the configuration
// word (either RB0 or RB3). Use the compiler settings to set the
// configuration word i.e. you can not set this from within the
// source code
//
// This software uses RB0 as input to the CCP module.
//
// RB0 : ultrasonic in (via amplifier, peak hold, level detect).
// RB3 : ultrasonic out (40kHz pulses)
//
// Version:
// 1.02 22/Feb/06 - moved segment drives to free TX pin for debug
// SEG1 was on RB2 now on RB5
// SEG2 was on RB5 now on RB2
// 1.01 15/Feb/06 - Changed to compiler 5.0.0.3
// More efficient so had to re-code gen_ultra for correct frequency.
// 1.00 14/Feb/06 - Initial release.
//
// Copyright : Copyright © John Main 2006
// The best Microcontroller projects and resources.
// Free for non commercial use as long as this entire copyright notice
// is included in source code and any other documentation.
//
//////////////////////////////////////////////////////////////////////
#include "bit.h"

//////////////////////////////////////////////////////////////////////
// macros

//////////////////////////////////////////////////////////////////////
// globals for interrupt.
//
unsigned int T1_O = 0; // timer1 overflow updated in interrupt routine.
unsigned short gCapInt = 0; // captured something in interrupt routine.
unsigned short gfCapOn = 1; // control capture only capture 1st value.

unsigned int t_capL = 0; // timer 1 low.
unsigned int t_capH = 0; // timer 1 high.
unsigned int t_capO = 0; // timer 1 overflow.

unsigned int gCapVal = 0; // captured this.

//////////////////////////////////////////////////////////////////////
void init(void) {

OSCCON = 0x60; // b6..4 = 110 = 4MHz

// set CCP to capture mode every rising edge.
CCP1CON = 0x05;

ANSEL = 0; // all ADC pins to digital I/O

// Timer 1 on
T1CON = (1<<TMR1ON);
}

//////////////////////////////////////////////////////////////////////
void init_ports(void) {

PORTA = 0;
TRISA = 0; // 0=o/p - sets analogue pins to digital output.

PORTB = 0;
TRISB = 0x01; // 0=o/p Receive on RB0.
}

//////////////////////////////////////////////////////////////////////
void enable_interrupts(void) {

// Timer 1
PIR1 &= ~(1<<TMR1IF); // Zero T1 overflow register value.

// Capture
PIR1 &= ~(1<<CCP1IF); // Zero Capture flag

// Interrupt enable.
PIE1 = (1<<CCP1IE);

// Global interrupt enable.
INTCON = (1<<GIE) | (1<<PEIE); // enable global & peripheral
}

//////////////////////////////////////////////////////////////////////
void disable_interrupts(void) {
INTCON &= ~(1<<GIE); // disable global & peripheral
}

//////////////////////////////////////////////////////////////////////
// RA% can only be input on 16F88
// ret table is for straight through
// PORT 0 1 2 3 4 5 6 7 to a b c d e f g dp
// So map to new outputs:
// 0 a, 1 b, 2 c, 3 d, 4 e, 6 f, 7 g - loosing dp
// i.e. keep 1st 5 and move bits 5,6 to 6,7

int2seg(unsigned short digit) {
unsigned short r;
unsigned short ret[10] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66,
0x6D, 0x7D, 0x07, 0x7F, 0x6F };

if (digit<0 || digit>9) {
r = 0x7f;
} else {
r =( ret[digit] & 0x1f ) | \
( (ret[digit] & 0x60)<< 1);
}

return r;
}
//////////////////////////////////////////////////////////////////////
void seg_display_int(unsigned int val) {
char op[7];

IntToStr(val,op);
// 6 digits op by above.
// e.g. for num 1234
// pos 5 4 3 2 1 0
// num x x 1 2 3 4 \0
// index from left ! 0 1 2 3 4 5

// Display the lower 4 digits.
PORTA=int2seg(op[2]-'0');
setBit(PORTB,5);
delay_ms(4);
resBit(PORTB,5);

PORTA=int2seg(op[3]-'0');
setBit(PORTB,2);
delay_ms(4);
resBit(PORTB,2);

PORTA=int2seg(op[4]-'0');
setBit(PORTB,6);
delay_ms(4);
resBit(PORTB,6);

PORTA=int2seg(op[5]-'0');
setBit(PORTB,7);
delay_ms(4);
resBit(PORTB,7);

PORTB &= ~0xe4; // turn off all resBit should do this
PORTB=0;

PORTA=0x00;
}

//////////////////////////////////////////////////////////////////////
// generate 4 pulses of ultrasonic @ 32kHz (8 periods of 32kHz).
// Use the simulator to set correct period.
// single ended drive
void gen_ultra(void) {

setBit(PORTB,3);
delay_us(12);
resBit(PORTB,3);
delay_us(11);

setBit(PORTB,3);
delay_us(12);
resBit(PORTB,3);
delay_us(11);

setBit(PORTB,3);
delay_us(12);
resBit(PORTB,3);
delay_us(11);

setBit(PORTB,3);
delay_us(12);
resBit(PORTB,3);
delay_us(11);
}

//////////////////////////////////////////////////////////////////////
void main() {
unsigned int i,val,s1,s2,tH,tL,tO;
char op[12];
unsigned long calc=0;

init_ports();
init();

gCapInt=0; // Reset capture indicator.

while(1) {

gfCapOn = 1; // allow one capture value

tO = T1_O; // Get the current timer value.
tH = TMR1H;
tL = TMR1L;

t_capL = 0; t_capH = 0; t_capO = 0; // initialise capture

gen_ultra();

enable_interrupts();
seg_display_int(val);
disable_interrupts(); // had 20 ish ms of time so stop

if (! gCapInt) { // no echo from soft output ? try loud

enable_interrupts();
seg_display_int(val);
seg_display_int(val);
disable_interrupts(); // had 20 ish ms of time so stop
}

// Did we get any echo from soft or loud ?
if (gCapInt) { // captured anything ?
gCapInt=0; // reset for next time

// 4MHz clock so timer 1 returns us
// gCapVal * 1,000,000 = seconds.
// speed of sound in air at 20degC = 340m/s
// (gCapVal*1000000*340)/(2*100) = distance in cm

s1=(t_capH-tH);
s2=(t_capL-tL);

calc = ((s1)<<8)+s2;
calc *= 34;
calc /= 2000; // output in cm
val = (int)calc;
}
} // while(1)
}

////////////////////////////////////////////////////////////////////////
void interrupt(void) {

// Free run Timer 1 get the overflow to extend counter here.
if (PIR1 & (1<<TMR1IF) ) { // T1 overflowed ?
PIR1 &= ~(1<<TMR1IF); // clear timer1 overflow bit.
T1_O++;
}

// Capture
if (PIR1 & (1<<CCP1IF)) {
PIR1 &= ~(1<<CCP1IF); // Zero Capture flag.

if (gfCapOn) { // allow only 1 capture

gfCapOn = 0;

t_capL = CCPR1L;
t_capH = CCPR1H;
t_capO = T1_O;

gCapInt = 1; // signal that a capture occured.
}
}

// Interrupts are only enabled at a specific point from program.
// They are not re-enabled here

// Note GIE set by RETFIE instruction
}
 
Status
Not open for further replies.

Latest threads

Back
Top