/***************************************************************************** * main.c * * Description: * Sample code to show how to monitor Sharp GP2D12 infrared proximity * detector with the CCS compiler. * * Created by: Martin Dubuc (martin.dubuc@rogers.com) * * Creation date: February 12, 2003 * ****************************************************************************/ #include <16f877.h> #fuses HS,NOPROTECT,NOWDT,BROWNOUT,PUT,NOLVP #ORG 0x1F00,0x1FFF {} /* Reserve memory for bootloader for the 8k 16F876/7 */ #device PIC16F877 *=16 /* Allow RAM to expand beyond 256 bytes */ #device adc=10 /* Make sure that we are sampling on 10 bits. This directive is required for compiler version 2.7. */ /* Set the clock speed */ #use delay(clock=20000000) /* Directive for RS-232 interface */ #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) /* Definitions */ /* Analog channel definitions */ #define ADC_DELAY 20 /* Delay in microseconds */ #define DISTANCE_ANCH 4 /* Port A5/AN4 */ /* IR calibration data */ #define IR_DISTANCE_BASE 10 #define IR_DISTANCE_STEP 2 #define NUM_IR_CALIB_DATA 31 /* Type definitions */ typedef int uint8_t; typedef long uint16_t; /* Public interface */ void main(void); void init_pins(void); void init(void); void display_ir_distance(void); /* IR sensor interface */ uint8_t get_ir_distance(uint8_t ir_reading); void monitor_ir_distance_sensor(void); /* Variable definitions */ static const uint8_t ir_calib_data[NUM_IR_CALIB_DATA] = { 124, 107, 93, 83, 75, 67, 62, 57, 53, 49, 47, 44, 42, 39, 38, 36, 34, 33, 32, 30, 29, 28, 27, 26, 25, 25, 24, 23, 23, 22, 21 }; uint8_t distance = 0xff; /***************************************************************************** * Init hardware pins: Set up the TRIS, set up analog ports, set the * pins to their default values. ****************************************************************************/ void init_pins(void) { /* Set up the various pins in/out */ set_tris_a(0b00100000); /* Pin A5 is input. Rest is not used. */ set_tris_b(0b00000000); /* Port B is not used. */ set_tris_c(0b10000000); /* C6 is output. C7 is input. Rest is not used. */ set_tris_d(0b00000000); /* Port D is not used. */ set_tris_e(0b00000000); /* Port E is not used. */ } /* init_pins */ /***************************************************************************** * Board initialization. Initialize pins. ****************************************************************************/ void init(void) { init_pins(); } /* init */ /***************************************************************************** * This is the main control loop. ****************************************************************************/ void main(void) { char c; init(); printf("ADC Demo\r\n\r\n"); for ( ; ; ) { printf("press key to get ADC value: "); for ( ; ; ) { if (kbhit()) break; c = getc(); printf("\r\n"); monitor_ir_distance_sensor(); display_ir_distance(); } } } /* main */ void display_ir_distance(void) { printf("distance = %u cm\r\n", distance); } /* display_status */ /* IR sensor implementation */ /* * get_ir_distance * * Determine distance in cm based in the A/D value and the calibration table. * * Parameters: * ir_reading (IN) - A/D value for the IR sensor */ uint8_t get_ir_distance(uint8_t ir_reading) { int i; for (i = 0; i < NUM_IR_CALIB_DATA; i++) { if (ir_calib_data[i] < ir_reading) { return IR_DISTANCE_BASE + i * IR_DISTANCE_STEP; } } return IR_DISTANCE_BASE + (i - 1) * IR_DISTANCE_STEP; } /* get_ir_distance */ /***************************************************************************** * This function monitors the IR distance sensor. * This function updates the distance global variable. ****************************************************************************/ void monitor_ir_distance_sensor(void) { uint16_t value; /* Read ADC for left sensor */ setup_adc_ports(A_ANALOG); setup_adc(ADC_CLOCK_DIV_8); set_adc_channel(DISTANCE_ANCH); /* Read Port A5/AN4 */ delay_us(ADC_DELAY); value = Read_ADC(); setup_adc(ADC_OFF); value >>= 2; distance = get_ir_distance(value); } /* monitor_ir_distance_sensor */