/* Taos05.c This program receives four bytes and sends an array of 102 values back. These values are displayed using the C++ Builder program viewer04.cpp. This program runs on a PIC16F83 processor with a 20MHz clock. It can be compiled with the CCS C compiler which can be found at www.ccsinfo.com */ #include <16F873.h> #device adc=8 #use delay(clock=20000000) #fuses NOWDT,HS, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG #use rs232(baud=115200,xmit=PIN_C6,rcv=PIN_C7) #use fast_io(A) #use fast_io(B) #use fast_io(C) #define LED1 PIN_C0 #define LED2 PIN_C1 #define CAMMISO PIN_C2 #define CAMMOSI PIN_C3 #define CAMSCK PIN_C4 #byte portA = 5 #byte portB = 6 #byte portC = 7 #byte RCSTA = 0x18 // function prototypes void showOff(); void showGreen(); void showRed(); // these function prototypes deal with the linear image sensor void setOffsets(int8 theOffset); void setGains(int8 theGain); //void setGainsAndOffsets(int8 gain, int8 offset); void capture(int8 integrationTime); void sendXclocks(int8 numberOfClockCycles); int8 readByteTaos(); void initializeTaos(); void sendByteTaos(int8 theData); // global variables // the pixel array is split into two beacuse it makes it easier to deal with in the RAM int8 theArray1[51]; // holds the first half of the pixel values int8 theArray2[51]; // holds the second half of the pixel values void main() { int8 gain; int8 offset; int8 exposureTime; int8 temp8; int8 temp8b; setup_adc_ports(NO_ANALOGS); setup_adc(ADC_OFF); setup_spi(FALSE); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); set_tris_a(0b00000000); set_tris_b(0b00000000); set_tris_c(0b11000100); // C3 is MISO C6&7 are serial port output_low(CAMSCK); showGreen(); delay_ms(200); showRed(); delay_ms(200); showOff(); delay_ms(200); initializeTaos(); // clear the buffer error bits and reset the serial port // this chunk of code is necessary because if the serial port receives // two bytes while the PIC is starting up then the serial port won't be able // to receive RCSTA &= 0b11101111; // disable the serial port RCSTA &= 0b11111001; // clear the error bits RCSTA |= 0b00010000; // enable the serial port while(true) {// receive a character from the serial port and display the lowest bit // on the LED as orange or green if(getc() == 255) { gain = getc(); offset = getc(); exposureTime = getc(); setGains(gain); setOffsets(offset); //setGainsAndOffsets(gain, offset); // read the image sensor capture(exposureTime); // send the array for(temp8 = 0; temp8 < 51; temp8++) { putc(theArray1[temp8] ); } for(temp8 = 0; temp8 < 51; temp8++) { putc(theArray2[temp8]); } showGreen(); delay_ms(20); showOff(); } }// end of whie true } //----------------------------------------------------------------------------- void showOff() { output_low(LED1); output_low(LED2); } //----------------------------------------------------------------------------- void showGreen() { output_high(LED1); output_low(LED2); } //----------------------------------------------------------------------------- void showRed() { output_low(LED1); output_high(LED2); } //----------------------------------------------------------------------------- void initializeTaos() {// gets the Taos linear image sensor ready to take pictures after powering up // this follows the paper on their site. They are calling this 'Reset' int8 I; output_low(CAMSCK); output_low(CAMMOSI); sendXclocks(30); output_high(CAMMOSI); sendXclocks(10); sendByteTaos(0x1B); sendXclocks(5); sendByteTaos(0x5F); sendByteTaos(0x00); } //----------------------------------------------------------------------------- void setOffsets(int8 theOffset) {// sets the offsets for the linear image sensor. There are three of them // so it does this three times sendByteTaos(0x40); // register writes are 0x40 + address sendByteTaos(theOffset) sendByteTaos(0x42); sendByteTaos(theOffset); sendByteTaos(0x44); sendByteTaos(theOffset); } //----------------------------------------------------------------------------- void setGains(int8 theGain) { sendByteTaos(0x41); sendByteTaos(theGain); sendByteTaos(0x43); sendByteTaos(theGain); sendByteTaos(0x45); sendByteTaos(theGain); } //----------------------------------------------------------------------------- void capture(int8 integrationTime) { // captures an image from the Taos linear image sensor // this follows the paper that is on their website int8 count; sendByteTaos(0x08); // start integration sendXclocks(22); delay_us(integrationTime); // wait for the necessary exposure time to happen sendByteTaos(0x10); sendXclocks(5); sendByteTaos(0x02); // start pixel readout while(input(CAMMISO)) // keep pulsing the clock until a start bit is seen { output_high(CAMSCK); output_low(CAMSCK); } for(count = 0; count < 51; count++) { theArray1[count] = readByteTaos(); // the pixels are stored into two arrays } // because of RAM limitations of this PIC for(count = 0; count < 51; count++) { theArray2[count] = readByteTaos(); } } //----------------------------------------------------------------------------- void sendXclocks(int8 numberOfClockCycles) {// sends the requested number of clock cycles to the Taos linear image sensor int count; for(count = 0; count < numberOfClockCycles; count++) { // ********************** Max clock rate is 10Mhz so if using a 40Mhz // PIC, a delay might need to be inserted because the clock will be 10Mhz // which is the maximum clock rate output_high(CAMSCK); output_low(CAMSCK); } } //----------------------------------------------------------------------------- int8 readByteTaos() {// reads a single pixel and returns its value // this follows the paper on their website. int8 theData; int8 count; output_high(CAMSCK); output_low(CAMSCK); // pulse the clock line theData = 0; for(count = 0; count < 8; count++) { theData >>= 1; if(input(CAMMISO)) theData += 128; output_high(CAMSCK); output_low(CAMSCK); // pulse the clock line } output_high(CAMSCK); output_low(CAMSCK); // pulse the clock line return theData; } //----------------------------------------------------------------------------- void sendByteTaos(int8 theData) {// sends a SPI-like command to the Taos linear image sensor // This follows the paper on their website. int8 count; output_low(CAMMOSI); output_high(CAMSCK); output_low(CAMSCK); for(count = 0; count < 8; count++) { if(bit_test(theData,0)) output_high(CAMMOSI); else output_low(CAMMOSI); output_high(CAMSCK); output_low(CAMSCK); theData >>= 1; } output_high(CAMMOSI); output_high(CAMSCK); output_low(CAMSCK); }