void __attribute__((vector(_ADC_VECTOR), interrupt(ipl4), nomips16)) ADC_ISR(void) { if (INTGetFlag(INT_AD1)){ //when conversion is complete write ADC word to the variable so it can be displayed analogIn1 = ReadADC10(0); analogIn2 = ReadADC10(1); analogRead = TRUE; INTClearFlag(INT_AD1); } }
/** * @Function ADCIntHandler * @param None * @return None * @brief Interrupt Handler for A/D. Reads all used pins into buffer. * @note This function is not to be called by the user * @author Max Dunne, 2013.08.25 */ void __ISR(_ADC_VECTOR, ipl1) ADCIntHandler(void) { unsigned char CurPin = 0; INTClearFlag(INT_AD1); for (CurPin = 0; CurPin <= PinCount; CurPin++) { ADValues[CurPin] = ReadADC10(CurPin); //read in new set of values } //calculate new filtered battery voltage Filt_BatVoltage = (Filt_BatVoltage * KEEP_FILT + AD_ReadADPin(BAT_VOLTAGE_MONITOR) * ADD_FILT) >> SHIFT_FILT; SampleCount++; if (SampleCount > PointsPerBatSamples) {//if sample time has passed PrevFilt_BatVoltage = CurFilt_BatVoltage; CurFilt_BatVoltage = Filt_BatVoltage; SampleCount = 0; //check for battery undervoltage check if ((CurFilt_BatVoltage <= BAT_VOLTAGE_LOCKOUT) && (PrevFilt_BatVoltage <= BAT_VOLTAGE_LOCKOUT) && (AD_ReadADPin(BAT_VOLTAGE_MONITOR) > BAT_VOLTAGE_NO_BAT)) { BOARD_End(); while (1) { printf("Battery is undervoltage with reading %d, Stack is inoperable until charging\r\n", AD_ReadADPin(BAT_VOLTAGE_MONITOR)); while (!IsTransmitEmpty()); } } } //if pins are changed add pins if (PinsToAdd | PinsToRemove) { AD_SetPins(); } ADNewData = TRUE; }
int main(int argc, char** argv) { //DDPCONbits.JTAGEN = 0; // Disable JTAG mPORTGSetPinsDigitalIn(0x00FF); mPORTBSetPinsAnalogIn(0x00FF); //Enable all analog SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); CloseADC10(); SetChanADC10(INITCH); OpenADC10(CONFIG1, CONFIG2, CONFIG3, CFGPORT, CFGSCAN); ConfigIntADC10(CFGINT); EnableADC10(); //Initialize the DB_UTILS IO channel DBINIT(); // Display the introduction DBPRINTF("Welcome to the Analog Input Test.\n"); DBPRINTF("The build date and time is (" __DATE__ "," __TIME__ ")\n"); while (1){ //Get damper value from PIC analog input int i = 0; for(i;i<1;i++){ int analog = ReadADC10(i); DBPRINTF("Hammer %d = %d", i, analog); DBPRINTF("\n"); } int digital = mPORTGReadBits(BIT_0); DBPRINTF("digital: %X \n \n", digital ); } return 0; }
/**************************************************************************** Function ADCIntHandler Parameters None Returns None Description Interrupt Handler for A/D. Reads all used pins into buffer. Notes None. Author Max Dunne, 2011.12.10 ****************************************************************************/ void __ISR(_ADC_VECTOR, ipl1) ADCIntHandler(void) { mAD1ClearIntFlag(); unsigned char CurPin = 0; for (CurPin = 0; CurPin <= PinCount; CurPin++) { ADValues[CurPin] = ReadADC10(CurPin); } }
int main(void){ mPORTASetPinsDigitalIn(0xFFFF); mPORTBSetPinsAnalogIn(0xFFFF); //Enable all analog SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); CloseADC10(); SetChanADC10(INITCH); OpenADC10(CONFIG1, CONFIG2, CONFIG3, CFGPORT, CFGSCAN); ConfigIntADC10(CFGINT); EnableADC10(); //Initialize the DB_UTILS IO channel DBINIT(); // Display the introduction DBPRINTF("Welcome to the Analog Input Test.\n"); DBPRINTF("The build date and time is (" __DATE__ "," __TIME__ ")\n"); while (1){ //Get damper value from PIC analog input int i = 0; for(i;i<16;i++){ int damper = ReadADC10(i); DBPRINTF("Damper %d = %d", i, damper); DBPRINTF("\n"); } //DBPRINTF("%d \n", LATA ); } return 0; }
double GP2D12_ReadDistance(){ rawData = ReadADC10(8 * ((~ReadActiveBufferADC10() & 0x01))); // ADC1BUF0; double volts = (3.3/1024.0)*rawData; distance = (25.0/(volts-0.13)) - 0.42; if(distance <= 1e-5) distance = 1000.0; return distance; }
CPU_INT16U ADC_GetVal (void) { CPU_INT08U buffer; buffer = 8 * (~ReadActiveBufferADC10() & 0x1); /* Select non active buffer */ return (ReadADC10(buffer)); /* Return ADC reading */ }
/* * Read ADC10 and convert the counts to volts. */ float read_battery_voltage() { uint8_t offset = 0; uint32_t battery = 0; // ADC10 is set up for dual buffers, we need to read from the inactive // buffer, invert the active buffer to read from the right place. offset = 8 * (~ReadActiveBufferADC10() & 0x01); battery = ReadADC10(offset); return (float)battery / BATTERY_SCALE; }
// LDR/Temp handled externally unsigned short *AdcSampleNow(void) { // KL - Fixed ADC read bug // ConvertADC10(); // starts conversion // while(!AD1CON1bits.DONE); // wait until conversion complete if (AD1CON1bits.ADON == 0) return (unsigned short*)&adcResult; // Otherwise this code will hang forever IFS0bits.AD1IF = 0; // Clear interrupt flag AD1CON1bits.ASAM = 1; // Begin auto sampling while (!IFS0bits.AD1IF);// Wait for the allotted number of conversions set by ADC_INTR_?_CONV in config2 AD1CON1bits.ASAM = 0; // Stop auto sampling while(!AD1CON1bits.DONE);// Wait for partially complete samples adcResult.ldr = ReadADC10(ADC_INDEX_LDR); // LDR adcResult.ir1 = ReadADC10(ADC_INDEX_IR1); // IR detector adcResult.batt = ReadADC10(ADC_INDEX_BATT); // Battery adcResult.ir2 = ReadADC10(ADC_INDEX_IR2); // IR detector return adcResult.values; }
//ISR del T5 //void _ISR _T5Interrupt(void){ void __attribute__((__interrupt__, auto_psv)) _T5Interrupt(void){ //printf("ISR T5\n"); unsigned long i; int sens1, sens2; //convert ADC_SCAN_AN11 ConvertADC10(); for(i=0;i<0x0000000F;i++){} //convert ADC_SCAN_AN13 ConvertADC10(); for(i=0;i<0x0000000F;i++){} sens2=ReadADC10(0); sens1=ReadADC10(1); #if (_FISICA_VERBOSE_ISR_T5>=2) printf("sens1 = %d\n", sens1); printf("sens2 = %d\n", sens2); #endif sens_buff[sens_buff_ind]=sens1; sens_buff_ind++; sens_buff[sens_buff_ind]=sens2; sens_buff_ind++; #if (_FISICA_VERBOSE_ISR_T5>=2) printf("sens_buff_ind=%d\n", sens_buff_ind); #endif if(sens_buff_ind>=(FIS_SENS_BUFF_LEN)){ #if (_FISICA_VERBOSE_ISR_T5>=2) con_printf("ISR T5: sens_buff_ind == FIS_SENS_BUFF_LENGTH\r\n"); #endif fis_stop_expFis(); //fis_save_sens_buff(); } T5_Clear_Intr_Status_Bit; }
void __ISR(_ADC_VECTOR, ipl3) ADCInterruptHandler(void) { // Clear the ADC's interrupt flag. IFS1CLR = ADC_INT_FLAG; elua_adc_dev_state *d = adc_get_dev_state( 0 ); elua_adc_ch_state *s; if ( AD1CON1bits.DONE ) { d->seq_ctr = 0; while( d->seq_ctr < d->seq_len ) { s = d->ch_state[ d->seq_ctr ]; d->sample_buf[ d->seq_ctr ] = ( u16 )ReadADC10(0); s->value_fresh = 1; // Fill in smoothing buffer until warmed up if ( s->logsmoothlen > 0 && s->smooth_ready == 0) adc_smooth_data( s->id ); #if defined( BUF_ENABLE_ADC ) else if ( s->reqsamples > 1 ) { buf_write( BUF_ID_ADC, s->id, ( t_buf_data* )s->value_ptr ); s->value_fresh = 0; } #endif // If we have the number of requested samples, stop sampling if ( adc_samples_available( s->id ) >= s->reqsamples && s->freerunning == 0 ) platform_adc_stop( s->id ); d->seq_ctr++; } d->seq_ctr = 0; } if( d->running == 1 ) adc_update_dev_sequence( 0 ); if ( d->clocked == 0 && d->running == 1 ) { // start conversion AD1CON1SET = _AD1CON1_ASAM_MASK; AD1CON1SET = _AD1CON1_SAMP_MASK; } if(!d->running) { CloseADC10(); } }
// LDR/Temp handled externally unsigned short *AdcSampleNow(void) { if (AD1CON1bits.ADON == 0) return (unsigned short*)&adcResult; // Otherwise this code will hang forever IFS0bits.AD1IF = 0; // Clear interrupt flag AD1CON1bits.ASAM = 1; // Begin auto sampling while (!IFS0bits.AD1IF);// Wait for the allotted number of conversions set by ADC_INTR_?_CONV in config2 AD1CON1bits.ASAM = 0; // Stop auto sampling while(!AD1CON1bits.DONE);// Wait for partially complete samples adcResult.batt = ReadADC10(ADC_INDEX_BATT); return adcResult.values; }
UINT16 read_adc(UINT8 channel) { if (channel == A1) AD1CHS = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN4; else if (channel == A0) AD1CHS = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN2; else return 0; int i; for (i = 0; i < 10; i++); // small delay (may not be needed but w/e) AcquireADC10(); for (i = 0; i < 100; i++); // Wait for sampling to complete ConvertADC10(); while(!BusyADC10()); //AcquireADC10(); return ReadADC10(0); }
void __ISR(_ADC_VECTOR, IPL7AUTO) ADCHandle(void){ mAD1ClearIntFlag(); int i=0; for(i; i<16; i++){ adcread = ReadADC10(i); switch(keyState[i]){ case GET_ON: // Previous force value moved into bin 0 // Bin 1 gets new value from ADC forceData[i][0] = forceData[i][1]; forceData[i][1] = adcread; // Previous slope bit moved into bin 0 // New slope bit determined from backward differentiator // if y[n] - y[n-1] is positive --> slope in bin 1 is '1' // else, negative slope gets '0' slopeData[i][0] = slopeData[i][1]; if(forceData[i][1]>forceData[i][0]){ slopeData[i][1]=1; }else{ slopeData[i][1]=0; } // Slope in bin 1 will be less than bin 0 if the slope changes from // Positive to negative, meaning a peak has been found // If so, send out noteOn signal // Else keep searching for noteOn conditions if (slopeData[i][1]<slopeData[i][0] && forceData[i][0] > threshold){ noteOn(i, forceData[i][0]); keyState[i] = GET_OFF; }else{ keyState[i] = GET_ON; } break; case GET_OFF: //TODO: Change this to digital input from comparator if(1){ noteOff(i); keyState[i] = GET_ON; } break; } } }
int AcquireMaxData(int ch) { int max = 0; //boolean int maxvalue = 0; //max input value int adcread = 0; while(max = 0) { adcread = ReadADC10(ch); if (adcread > maxvalue) { maxvalue = adcread; }else { max = 1; } } return maxvalue; }
void __ISR(_ADC_VECTOR, ipl3) interruptGP2D12(void){ mAD1ClearIntFlag(); rawData = ReadADC10(8 * ((~ReadActiveBufferADC10() & 0x01))); // ADC1BUF0; double volts = (3.3/1024.0)*rawData; distance = (25.0/(volts-0.13)) - 0.42; if(distance <= 1e-5) distance = 1000.0; while(IFS1bits.AD1IF){ int i = ADC1BUF0; mAD1ClearIntFlag(); } INTEnable(INT_AD1, INT_DISABLED); }
void GetBatt(void) { PMD1bits.ADC1MD = 0; // See device errata CloseADC10(); // Configure ADC for RCOSC OpenADC10( /*config1*/ (ADC_MODULE_OFF | ADC_IDLE_STOP | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_OFF), /*config2*/ (ADC_VREF_AVDD_AVSS | ADC_SCAN_ON | ADC_INTR_3_CONV| ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF), /*config3*/ (ADC_CONV_CLK_INTERNAL_RC | /* INTERNAL RC */ ADC_SAMPLE_TIME_20 | ADC_CONV_CLK_20Tcy), /*configport_L*/ (ADC_SELECT_L), /*configport_H*/ (ADC_SELECT_H), /*configscan_L*/ (~ADC_SELECT_L), /*configscan_H*/ (~ADC_SELECT_H) ); EnableADC1; IFS0bits.AD1IF = 0; // Clear interrupt flag AD1CON1bits.ASAM = 1; // Begin auto sampling while (!IFS0bits.AD1IF);// Wait for the allotted number of conversions set by ADC_INTR_?_CONV in config2 AD1CON1bits.ASAM = 0; // Stop auto sampling while(!AD1CON1bits.DONE);// Wait for partially complete samples adcResult.batt = ReadADC10(ADC_INDEX_BATT); // Battery // adcResult.ldr = ReadADC10(ADC_INDEX_LDR); // LDR // adcResult.temp = ReadADC10(ADC_INDEX_TEMP); // Temp AD1CON1bits.ADON = 0; PMD1bits.ADC1MD = 1; // See device errata }
int getAverageValue() { int currentAverage = 0; int channel4 = 0; while (1) { delayMs(100); channel4 = ReadADC10(0); currentAverage = runningAverage(channel4); if (indexAverage == 15 && currentAverage != -1) { //printf("%.2f|%d=%d|\r\n", currentAverage * 3.18, currentAverage, channel4); printf("%.2f ", currentAverage * 3.18); return currentAverage; } } }
// LDR/Temp handled externally unsigned short *AdcSampleNow(void) { if (AD1CON1bits.ADON == 0) return (unsigned short*)&adcResult; // Otherwise this code will hang forever IFS0bits.AD1IF = 0; // Clear interrupt flag AD1CON1bits.ASAM = 1; // Begin auto sampling while (!IFS0bits.AD1IF);// Wait for the allotted number of conversions set by ADC_INTR_?_CONV in config2 AD1CON1bits.ASAM = 0; // Stop auto sampling while(!AD1CON1bits.DONE);// Wait for partially complete samples adcResult.pir = ReadADC10(ADC_INDEX_PIR); // PIR adcResult.temp = ReadADC10(ADC_INDEX_TEMP); // Temp adcResult.light = ReadADC10(ADC_INDEX_LIGHT); // Light adcResult.batt = ReadADC10(ADC_INDEX_BATT); // Battery adcResult.mic_ave = ReadADC10(ADC_INDEX_MIC_AVE); // Microphone - integrator adcResult.mic_peak = ReadADC10(ADC_INDEX_MIC_PEAK); // Microphone - peak detector adcResult.mic_raw = ReadADC10(ADC_INDEX_MIC_RAW); // Microphone - raw values return adcResult.values; }
// === ADC Thread ============================================= static PT_THREAD (protothread_adc(struct pt *pt)) { PT_BEGIN(pt); myPaddle = (paddle*) malloc(sizeof(paddle)); myPaddle->xc = 4; static int adc_10; while(1) { PT_YIELD_TIME_msec(2); // read the ADC from pin 24 (AN11) adc_10 = ReadADC10(0); // read the result of channel 9 conversion from the idle buffer AcquireADC10(); // not needed if ADC_AUTO_SAMPLING_ON below //READADC10 value is between 0-1020 tft_fillRect(myPaddle->xc, myPaddle->yc, 2, PADDLE_LEN, ILI9340_BLACK); if(adc_10 < 3) adc_10 = 0; else if (adc_10 > 920) adc_10 = 920; myPaddle->vyc = (adc_10 >> 2) - myPaddle->yc; myPaddle->yc = (adc_10 >> 2); tft_fillRect(myPaddle->xc, myPaddle->yc, 2, PADDLE_LEN, ILI9340_WHITE); } // END WHILE(1) PT_END(pt); } // ADC thread
CPU_INT16U ADC_GetVal (CPU_INT08U channel_to_convert) { CPU_INT08U buffer; CPU_INT32U config; switch (channel_to_convert) { case 0: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN0; break; case 1: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN1; break; case 2: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN2; break; case 3: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN3; break; case 4: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN4; break; case 5: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN5; break; case 6: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN6; break; case 7: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN7; break; case 8: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN8; break; case 9: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN9; break; case 10: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN10; break; case 11: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN11; break; case 12: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN12; break; case 13: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN13; break; case 14: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN14; break; case 15: config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN15; break; config = ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN0; } SetChanADC10(config); //pour le changement de voie en entrée de l'adc, il faudra prévoir un temps pour que la tension se //stabilise entre la comutation et l'échantillonnage. Le top se serait de changer de voie à la fin de la conversion précédente. //Ce qui laisse du temps avant la conversion suivante. CBE OSTimeDlyHMSM(0, 0, 0, 5); ConvertADC10(); while (!BusyADC10()); // timeout ?? !! buffer = 8 * (~ReadActiveBufferADC10() & 0x1); /* Select non active buffer */ return (ReadADC10(buffer)); /* Return ADC reading */ }
int main(void) { unsigned int temp; // Configure the device for maximum performance but do not change the PBDIV // Given the options, this function will change the flash wait states, RAM // wait state and enable prefetch cache but will not change the PBDIV. // The PBDIV value is already set via the pragma FPBDIV option above.. SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); /*PORT CONFIGURATION for UART*/ // Blinky LED for Uart activity //mPORTAClearBits(BIT_7); //mPORTASetPinsDigitalOut(BIT_7); // PINS used for the buttons PORTSetPinsDigitalIn(IOPORT_B, BIT_2 | BIT_3 | BIT_4); #define CONFIG (CN_ON | CN_IDLE_CON) #define INTERRUPT (CHANGE_INT_ON | CHANGE_INT_PRI_2) mCNOpen(CONFIG, CN4_ENABLE | CN5_ENABLE | CN6_ENABLE, CN4_PULLUP_ENABLE | CN5_PULLUP_ENABLE | CN6_PULLUP_ENABLE); temp = mPORTBRead(); //Analog input CloseADC10(); #define PARAM1 ADC_MODULE_ON | ADC_FORMAT_INTG32 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON #define PARAM2 ADC_VREF_AVDD_AVSS | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_2 | ADC_BUF_16 | ADC_ALT_INPUT_OFF #define PARAM3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_5 #define PARAM4 ENABLE_AN0_ANA | ENABLE_AN1_ANA #define PARAM5 SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN4 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15 SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN0); OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); EnableADC10(); //PORT D for motors mPORTDClearBits(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12 | BIT_13 | BIT_14 | BIT_15); // Turn off PORTD on startup. mPORTDSetPinsDigitalOut(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12 | BIT_13 | BIT_14 | BIT_15); // Make PORTD output. // Explorer-16 uses UART2 to connect to the PC. // This initialization assumes 36MHz Fpb clock. If it changes, // you will have to modify baud rate initializer. UARTConfigure(UART2, UART_ENABLE_PINS_TX_RX_ONLY); UARTSetFifoMode(UART2, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY); UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1); UARTSetDataRate(UART2, GetPeripheralClock(), DESIRED_BAUDRATE); UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)); // Configure UART2 RX Interrupt INTEnable(INT_SOURCE_UART_RX(UART2), INT_ENABLED); INTSetVectorPriority(INT_VECTOR_UART(UART2), INT_PRIORITY_LEVEL_2); INTSetVectorSubPriority(INT_VECTOR_UART(UART2), INT_SUB_PRIORITY_LEVEL_0); // Congifure Change/Notice Interrupt Flag ConfigIntCN(INTERRUPT); // configure for multi-vectored mode INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR); // enable interrupts INTEnableInterrupts(); WriteString("*** UART Interrupt-driven Example ***\r\n"); unsigned int channel1, channel2; unsigned int motor1Time, motor2Time; // Let interrupt handler do the work while (1) { while ( ! mAD1GetIntFlag() ); channel1 = ReadADC10(0); channel2 = ReadADC10(1); motor1Time = (channel1*(60000)/(1023) + 80000); motor2Time = (channel2*(60000)/(1023) + 80000); //maximo valor de motorTime = 140000 //use motor time for stepping delay if (MotorsON) { if (M1forward) { adelante(1, motor1Time, 1); } else { atras(1, motor1Time, 1); } if (M2forward) { adelante(1, motor2Time, 3); } else { atras(1, motor2Time, 3); } } mAD1ClearIntFlag(); } return 0; }
int getANX (char channel){ _initADC(); int result = ReadADC10(channel - 1); return result; }
/* Timer ISR callback function for CVD measurements. Requires external pull-up resistors to Vdd for all buttons. For use on devices that don't support TimerCallbackFunc1 or have a CTMU (TimerCallbackFunc4). */ void TimerCallbackFunc2(void) { UINT16 Vpos, Vneg, Vmeas, Vupdate; UINT16 iChan, iChanBit; UINT16 iRefChan, iRefBit; iRefChan = REF_CHANNEL; iRefBit = 1<<iRefChan; iChan = ScanChannels[button_set_number]; iChanBit = 1<<iChan; //***************************************************************************** // Measure Vneg //***************************************************************************** #if defined( TICKLE_LED1 ) LATFSET = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("di"); // disable interrupts AD1CON1bits.SAMP = 1; //Start Chold charging Process ChargeDelay(); LATBCLR = iRefBit; //Ref pin now low ChargeDelay(); AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH cap discharges and sensor cap charges TRISBSET = iChanBit; //Tri-state sensor port LATBCLR = iChanBit; //Sensor port low #if defined(CHARGE_DISCHARGE_CYCLE_1) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_1) #if defined(CHARGE_DISCHARGE_CYCLE_2) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_2) #if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_3) #if defined(CHARGE_DISCHARGE_CYCLE_4) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin ChargeDelay(); //Wait as ADC SAH discharges #endif//defined(CHARGE_DISCHARGE_CYCLE_4) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH charges AD1CON1bits.SAMP = 0; //Start A/D conversion #if defined( TICKLE_LED1 ) LATFCLR = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("ei"); //re-enable interrupts //Capture Voltage while ( !AD1CON1bits.DONE ) //Wait for ADC conversion complete { // Do Nothing } AD1CON1bits.DONE = 0; Vneg = ReadADC10(ReadActiveBufferADC10())<<5; //Read new Vneg //***************************************************************************** // Measure Vpos //***************************************************************************** //Be sure ADC is in known state TRISBCLR = iRefBit; //Make ref pin output AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin AD1CON1bits.SAMP = 1; //Start Chold charging Process ChargeDelay(); #if defined( TICKLE_LED1 ) LATFSET = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("di"); // disable interrupts //Setup: SAH cap high, sensor cap low LATBCLR = iChanBit; //Sensor pin low TRISBCLR = iChanBit; //Clear tri-state on sensor pin //Charging the ADC's sample and hold (SAH) capacitor LATBSET = iRefBit; //Make ref pin high TRISBCLR = iRefBit; //Make ref pin output #if defined( CHARGE_DISCHARGE_CYCLE_1 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges TRISBSET = iChanBit; //Tristate sensor pad (make it input) AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_1 ) #if defined( CHARGE_DISCHARGE_CYCLE_2 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_2 ) #if defined( CHARGE_DISCHARGE_CYCLE_3 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_3 ) #if defined( CHARGE_DISCHARGE_CYCLE_4 ) AD1CHSbits.CH0SA = iRefChan; //Switch ADC to ref pin ChargeDelay(); //Wait as ADC SAH cap charges AD1CHSbits.CH0SA = iChan; //Switch ADC to sensor pin ChargeDelay(); //Wait as ADC SAH cap discharges to sensor cap #endif//defined( CHARGE_DISCHARGE_CYCLE_4 ) //Capture Voltage AD1CON1bits.SAMP = 0; //Start A/D conversion #if defined( TICKLE_LED1 ) LATFCLR = 1<<0; // Use pin 5 on J2 (RF0) #endif// defined( TICKLE_LED1 ) asm("ei"); //re-enable interrupts while ( !AD1CON1bits.DONE ) //Wait for ADC conversion complete { //Do Nothing } AD1CON1bits.DONE = 0; Vpos = ReadADC10(ReadActiveBufferADC10())<<5; //Read new Vpos #if defined(USE_DIFFERENTIAL_MEASUREMENTS) Vmeas = Vpos + 32768 - Vneg; //Calculate new Vmeas #else //single ended Vmeas = Vpos; //Single ended measurements #endif //defined USE_DIFFERENTIAL_MEASUREMENTS #if defined(LIMIT_SLEW_RATE) if ( IgnoreCurrentDataFlag == TRUE ) { Vpos = Vneg = 0; Vmeas = OldRawData[button_set_number]; } # if defined(USE_DIFFERENTIAL_MEASUREMENTS) # define VMEAS_DELTA (1<<(5)) # else # define VMEAS_DELTA (1<<(6)) # endif//defined(USE_DIFFERENTIAL_MEASUREMENTS) if (Vmeas > OldRawData[button_set_number]) { OldRawData[button_set_number] += VMEAS_DELTA; } else if(Vmeas < OldRawData[button_set_number]) { OldRawData[button_set_number] -= VMEAS_DELTA; } Vupdate = OldRawData[button_set_number]; #else if ( IgnoreCurrentDataFlag == TRUE ) { Vmeas = Vpos = Vneg = 0; Vupdate = OldRawData[button_set_number]; } else { OldRawData[button_set_number] = Vupdate = Vmeas; } #endif//defined(LIMIT_SLEW_RATE) ButtonCumulativeSum[button_set_number] += Vupdate; #if defined( UART_DUMP_RAW_COUNTS ) CurRawData[ HF_Read_Number ][button_set_number] = Vmeas; #elif defined( UART_DUMP_ALL_COUNTS ) CurRawData[3*HF_Read_Number+0][button_set_number] = Vpos; CurRawData[3*HF_Read_Number+1][button_set_number] = Vneg; CurRawData[3*HF_Read_Number+2][button_set_number] = Vmeas; #endif//defined( UART_DUMP_RAW_COUNTS ) //Measurement teardown LATBCLR = iChanBit; //Make sensor port low to discharge sensor pad //Next Measurement?? button_set_number++; //Increment the button number to move on to the next button if(button_set_number == NumberScanChannels) //if scanned all the buttons { HF_Read_Number++; //Start the next set of HF Scans button_set_number = 0; //Start over at the first button if ( HF_Read_Number < NUM_HF_READS ) // Not done with scans { EmTouchDataReady = FALSE; } else //All HF scans done, compute average, signal we're done { EmTouchDataReady = TRUE; // We're done with complete scan HF_Read_Number = 0; // Start next set of HF scans } } else { EmTouchDataReady = FALSE; } return; // we're done! }
int main(void) { /******************* Setup *****************************/ mPORTBSetPinsAnalogIn(0xFFFF); //Enable all analog //mPORTDSetPinsDigitalOut(BIT_0 | BIT_1 | BIT_8); SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); CloseADC10(); SetChanADC10(INITCH); OpenADC10(CONFIG1, CONFIG2, CONFIG3, CFGPORT, CFGSCAN); ConfigIntADC10(CFGINT); EnableADC10(); //Initialize the DB_UTILS IO channel DBINIT(); // Display the introduction DBPRINTF("Welcome to the PIC32 Starter Kit Tutorial.\n"); DBPRINTF("The build date and time is (" __DATE__ "," __TIME__ ")\n"); /********************* Declarations *********************/ int damper = 0; //ch1 binary read int damperchnum = 0; //damper adc number int hammerchnum = 1; //hammer adc number int samplesize = 1000; int hammerdata[10][samplesize]; //collection of hammer values int damperdata[10][samplesize]; //collection of damper values int index = 0; //index of hammerdata and damperdata arrays int collection[2] = {0,0}; int count = 0; /******************** Initialize Arrays ******************/ int x; int y; for( x = 0; x < 10; x++) { for( y = 0; y < samplesize; y++) { damperdata[x][y] = 0; } } /************************ Stuff to do *********************/ while (count < 4){ damper = ReadADC10(damperchnum); if(damper > 100) { //store data collection[0] = collection[1]; //we are collecting data, falling edge detection collection[1] = 1; if(index<samplesize) { hammerdata[count][index] = ReadADC10(hammerchnum); damperdata[count][index] = damper; index++; //DBPRINTF("Damper: %d \n", damperdata[count][index-1]); } }else{ collection[0] = collection[1]; collection[1] = 0; } if(collection[1] < collection[0]) //rising edge detection { DBPRINTF("Count: %d \n", count); count++; index = 0; } } int i; /******************** Output Memory at End **********************/ for( i = 0; i < 1000; i++) { DBPRINTF("Damper data: %d ", damperdata[1][i]); DBPRINTF("\n"); } return 0; }
/* This version of the callback function replaces the pull-up resistors used in TimerCallBackFunc2 with 10 to 30 charges from the ADC's sample and hold (SAH) capacitor. This improves noise performance at the cost of longer execution. */ void Timer4CallbackFunc3(void) { UINT16 Vpos, Vneg, Vmeas, Vupdate; UINT16 iChan, iChanBit; UINT16 iRefChan, iRefBit; iRefChan = REF_CHANNEL; iRefBit = 1<<iRefChan; iChan = ScanChannels[button_set_number]; iChanBit = 1<<iChan; //Mask shows which bits need changing to toggle between reference and sensor AD1CHS_Mask = (iRefChan<<16)^(iChan<<16); //XOR = bits that are different //***************************************************************************** // Measure Vpos //***************************************************************************** //Bring up ADC in known state AD1CON1bits.SAMP = 1; //Start Chold charging Process LATBCLR = iRefBit; //Ref pin now low TRISBCLR = iRefBit; //Make reference pin output AD1CHSbits.CH0SA = iRefChan; //Switch ADC to grounded reference pin LATBSET = iRefBit; //Make reference pin high TRISBSET = iChanBit; //Tri-state sensor port LATBCLR = iChanBit; //Sensor port low //This charge/discharge cycle is necessary to start the process AD1CHSbits.CH0SA = iRefChan; //Charge ADC Sample and Hold capacitor TRISBSET = iChanBit; //Tri-state sensor port pin again AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # if defined(CHARGE_DISCHARGE_CYCLE_2) AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # endif//defined(CHARGE_DISCHARGE_CYCLE_2) # if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # endif//defined(CHARGE_DISCHARGE_CYCLE_3) # if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button # endif//defined(CHARGE_DISCHARGE_CYCLE_4) AD1CON1bits.SAMP = 0; //Start ADC conversion //Wait for ADC conversion complete while ( !AD1CON1bits.DONE ) { //Do Nothing } AD1CON1bits.DONE = 0; Vpos = ReadADC10(ReadActiveBufferADC10())<<5; //ADC measurement //***************************************************************************** // Measure Vneg //***************************************************************************** #if !defined(USE_DIFFERENTIAL_MEASUREMENTS) # error('This file supports differential measurements only! Use mTouchCap_Timers.c instead.') #endif//!defined(USE_DIFFERENTIAL_MEASUREMENTS) AD1CON1bits.SAMP=1; //Enable sampling again // Repeat charging to bring button capacitor to near Vdd in voltage, using ADC #if defined(BUTTON_CHARGE_CYCLE_1) // Charge cycles 1 - 10 // Button charge #01 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #02 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #03 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #04 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #05 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #06 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #07 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #08 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #09 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #10 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_1) #if defined(BUTTON_CHARGE_CYCLE_2) // Charge cycles 11 - 20 // Button Charge #11 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #12 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #13 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #14 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #15 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #16 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #17 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #18 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #19 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #20 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_2) #if defined(BUTTON_CHARGE_CYCLE_3) // Charge cycles 21 - 30 // Button Charge #21 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #22 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #23 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #24 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #25 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #26 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #27 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #28 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #29 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #30 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_3) #if defined(BUTTON_CHARGE_CYCLE_4) // Charge cycles 31 - 40 // Button Charge #31 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #32 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #33 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #34 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #35 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #36 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #37 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #38 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button Charge #39 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button // Button charge #40 AD1CHSINV = AD1CHS_Mask; //Switch to reference to charge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge button #endif//defined(BUTTON_CHARGE_CYCLE_4) //Button cap is charged, now start dumping charge with ADC's SAH cap LATBCLR = iRefBit; //Make reference pin low # if defined(CHARGE_DISCHARGE_CYCLE_1) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_1) # if defined(CHARGE_DISCHARGE_CYCLE_2) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_2) # if defined(CHARGE_DISCHARGE_CYCLE_3) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_3) # if defined(CHARGE_DISCHARGE_CYCLE_4) AD1CHSINV = AD1CHS_Mask; //Switch to reference to discharge SAH cap AD1CHSINV = AD1CHS_Mask; //Switch to the sensor to charge SAH cap # endif//defined(CHARGE_DISCHARGE_CYCLE_4) AD1CON1bits.SAMP = 0; //Start ADC conversion //Wait for ADC conversion complete while ( !AD1CON1bits.DONE ) { // Do Nothing } AD1CON1bits.DONE = 0; TRISBCLR = iChanBit; //Remove tri-state on sensor port pin, make it output // Read new Vneg Vneg = ReadADC10(ReadActiveBufferADC10())<<5; // Calculate new Vmeas Vmeas = Vpos + 32768 - Vneg; #if defined(LIMIT_SLEW_RATE) # define VMEAS_DELTA (1<<(5)) if (Vmeas > OldRawData[button_set_number]) { OldRawData[button_set_number] += VMEAS_DELTA; } else if(Vmeas < OldRawData[button_set_number]) { OldRawData[button_set_number] -= VMEAS_DELTA; } Vupdate = OldRawData[button_set_number]; #else Vupdate = Vmeas; #endif//defined(LIMIT_SLEW_RATE) ButtonCumulativeSum[button_set_number] += Vupdate; #if defined( UART_DUMP_RAW_COUNTS ) CurRawData[ HF_Read_Number ][button_set_number] = Vmeas; #elif defined( UART_DUMP_ALL_COUNTS ) CurRawData[3*HF_Read_Number+0][button_set_number] = Vpos; CurRawData[3*HF_Read_Number+1][button_set_number] = Vneg; CurRawData[3*HF_Read_Number+2][button_set_number] = Vmeas; #endif//defined( UART_DUMP_RAW_COUNTS ) //Next Measurement?? button_set_number++; //Increment the button number to move on to the next button if(button_set_number == NumberScanChannels) //if scanned all the buttons { HF_Read_Number++; //Start the next set of HF Scans button_set_number = 0; //Start over at the first button if ( HF_Read_Number < NUM_HF_READS ) // Not done with scans { dataReadyCVD = FALSE; } else //All HF scans done, compute average, signal we're done { dataReadyCVD = TRUE; // We're done with complete scan HF_Read_Number = 0; // Start next set of HF scans } } else { dataReadyCVD = FALSE; } return; // we're done! }
virtual reg_t read_analog(){ while (!mAD1GetIntFlag()) Nop(); reg_t val = ReadADC10(bit); mAD1ClearIntFlag(); return val; }
//********************************************************************* int analogRead(uint8_t pin) { int analogValue; unsigned int offset; // buffer offset to point to the base of the idle buffer unsigned int param4; uint8_t channelNumber; //* in most cases (except the uno board) this will be a 1 to 1 mapping channelNumber = analogInPinToBit(pin); //* May 1, 2011 Gene Apperson of Digitlent sent me PIC32MX5XX-6XX-7XX Errata.pdf //* item #26 documents a condition that I/O pins take time if previously set to outputs //* first attempt, set all to 0 // AD1PCFG = 0; // configure and enable the ADC CloseADC10(); // ensure the ADC is off before setting the configuration // define setup parameters for OpenADC10 // Turn module on | ouput in integer | trigger mode auto | enable autosample #define PARAM1 ADC_FORMAT_INTG16 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON // define setup parameters for OpenADC10 // ADC ref external | disable offset test | disable scan mode | perform 2 samples | use dual buffers | use alternate mode #define PARAM2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON // define setup parameters for OpenADC10 // use ADC internal clock | set sample time #define PARAM3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15 // define setup parameters for OpenADC10 // set AN4 and AN5 as analog inputs param4 = channelNumber; // define setup parameters for OpenADC10 // do not assign channels to scan #define PARAM5 SKIP_SCAN_ALL // use ground as neg ref for A | use AN4 for input A | use ground as neg ref for A | use AN5 for input B // SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN4 | ADC_CH0_NEG_SAMPLEB_NVREF | ADC_CH0_POS_SAMPLEB_AN5); // configure to sample AN4 & AN5 // SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN0 | ADC_CH0_NEG_SAMPLEB_NVREF | ADC_CH0_POS_SAMPLEB_AN1); // configure to sample AN4 & AN5 // OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using the parameters defined above switch(channelNumber) { case 0: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN0); break; case 1: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN1); break; case 2: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN2); break; case 3: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN3); break; case 4: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN4); break; case 5: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN5); break; case 6: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN6); break; case 7: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN7); break; case 8: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN8); break; case 9: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN9); break; case 10: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN10); break; case 11: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN11); break; case 12: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN12); break; case 13: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN13); break; case 14: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN14); break; case 15: SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN15); break; } // configure to sample what ever pin was specified OpenADC10( PARAM1, PARAM2, PARAM3, param4, PARAM5 ); // configure ADC using the parameters defined above EnableADC10(); // Enable the ADC //* A delay is needed for the the ADC start up time //* this value started out at 1 millisecond, I dont know how long it needs to be //* 99 uSecs will give us the same approximate sampling rate as the AVR chip // delay(1); delayMicroseconds(99); while ( ! mAD1GetIntFlag() ) { // wait for the first conversion to complete so there will be vaild data in ADC result registers } analogValue = ReadADC10(0); mAD1ClearIntFlag(); return (analogValue); }
int main(void) { UINT8 strBuf[bufLen]; UINT8 bank = 0; #define NSENSORSPERBANK 4 UINT32 cPot, cSensor[2][NSENSORSPERBANK]; UINT8 i; #define NSENSORSINSTALLED 5 UINT16 min_levels[NSENSORSINSTALLED], max_levels[NSENSORSINSTALLED], discriminators[NSENSORSINSTALLED]; #define DISCRIMINATORLEVELPCT ( 75 ) int steps_remaining_in_evaluation = 0; BOOL noteIsOn[NSENSORSINSTALLED] = {0, 0, 0, 0, 0}; UINT32 sensorValue; SYSTEMConfigPerformance (FCY); LED_TRIS = 0; LED_MIDI_TRIS = 0; BTN_TRIS = 1; STEPPER0_TRIS = 0; STEPPER1_TRIS = 0; STEPPER2_TRIS = 0; STEPPER3_TRIS = 0; PWR_BANK0_TRIS = 0; // disable both banks to start PWR_BANK1_TRIS = 1; UART2_RX_PPS_REG = UART2_RX_PPS_ITM; UART2_TX_PPS_REG = UART2_TX_PPS_ITM; UARTConfigure(UART2, UART_ENABLE_PINS_TX_RX_ONLY); UARTSetFifoMode(UART2, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY); UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1); if (DO_MIDI) { UARTSetDataRate(UART2, FPB, 31500); } else { UARTSetDataRate(UART2, FPB, 115200); } UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)); // timer interrupt stuff... // configure the core timer roll-over rate // the internal source is the Peripheral Clock // timer_preset = SYSCLK_freq / pb_div / additional prescale / desired_ticks_per_sec UINT16 timer_preset = (clock_interrupt_period_us * (FPB / 1000000)) / 8; OpenTimer1(T1_ON | T1_SOURCE_INT | T1_PS_1_8, timer_preset); // set up timer interrupt with a priority of 2 and sub-priority of 0 ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_2); // enable multi-vector interrupts INTEnableSystemMultiVectoredInt(); // configure and enable the ADC CloseADC10(); // ensure the ADC is off before setting the configuration /* Notes from ref chapter must set the TRIS bits for these channels (1 (desired) by default) AD1CON1 want form 32-bit integer (0b100) we set the SAMP bit to begin sampling --no-- the ASAM bit will begin autosampling combine this with CLRASAM which will clear ASAM after one set of samples conversion should be auto after that autoconvert when sampling has concluded (SSRC = 0b111) Tad min is 65ns, which is 2.6 PBclock cycles Tad min is 83.33ns, which is 3.3 PBclock cycles AD1CON2 CSCNA on enables scanning of inputs according to AD1CSSL maybe BUFM 2 8-word buffers rather than 1 16-word buffer ALTS alternates between mux A and mux B AD1CON3 ADRC use peripheral bus clock ADC_CONV_CLK_PB TAD: use ADC clock divisor of 4 to give TAD of 100ns to exceed min of 83.33 Sample time (SAMC): use 2 TADs to provide 200ns sampling to exceed min of 132 New strategy: set the bit to power the necessary bank, wait 200 us, and then kick off a sample. AD1CHS CH0SA and CH0SB not used when scanning channels; CH0NA and CH0NB *are* used AD1PCFG zero bits to configure channels as analog; set to zero on reset AD1CSSL one bits to select channel for scan Will want to scan all channels on one bank, then interrupt to switch banks Protect user code by writing valid stuff during interrupt to user area settling time after switching is say 200 us (78us to 0.63 rise) */ AD1CON1 = ADC_FORMAT_INTG32 // output in integer | ADC_CLK_AUTO // conversion begins with clock | ADC_AUTO_SAMPLING_OFF // don't yet start autosample ; AD1CON2 = ADC_VREF_AVDD_AVSS // ADC ref internal | ADC_OFFSET_CAL_DISABLE // disable offset test | ADC_SCAN_ON // enable scan mode (CSCNA) | ADC_SAMPLES_PER_INT_5 | ADC_ALT_BUF_OFF // use single buffer | ADC_ALT_INPUT_OFF // use MUX A only ; AD1CON3 = ADC_SAMPLE_TIME_2 // use 2 TADs for sampling | ADC_CONV_CLK_PB // use PBCLK | ADC_CONV_CLK_Tcy // 4 PBCLK cycles, so TAD is 100ns ; // AD1CHS // CH0NA negative input select for MUX A is Vref- // ASAM will begin a sample sequence // CLRASAM will stop autosampling after completing one sequence // begin conversions automatically SetChanADC10 (ADC_CH0_NEG_SAMPLEA_NVREF); // AD1PCFG // these are in the order in which they will appear in BUF0 AD1CSSL = LS0_ADC_ITM | LS1_ADC_ITM | LS2_ADC_ITM | LS3_ADC_ITM | POT_ADC_ITM ; EnableADC10(); while(1) { // enableADC is set periodically (ADC_INTERVAL_MS) by an interrupt service routine if (enableADC) { // NOTE: the interrupt routine set AD1CON1bits.SAMP = 1; // use AN0, pin 2 // wait for the conversions to complete // so there will be vaild data in ADC result registers while ( ! AD1CON1bits.DONE ); for (i = 0; i < NSENSORSPERBANK; i++) { cSensor[bank][i] = ReadADC10(i); } cPot = POT_ADC_VAL; // current setup has 5 sensors: 2 in bank 0, 3 in bank 1 if (1 && enablePrint && !DO_MIDI) { snprintf (strBuf, bufLen, "%5d <-> %5d | %5d <-> %5d | %5d <-> %5d | %5d <-> %5d | %5d <-> %5d || %5d %3.2f\n", cSensor[0][0], discriminators[0], cSensor[0][1], discriminators[1], cSensor[1][0], discriminators[2], cSensor[1][1], discriminators[3], cSensor[1][2], discriminators[4], cPot, rpm ); SendDataBuffer (strBuf, strlen(strBuf)); enablePrint = 0; } smoothedPotValue = smoothedPotValue * (1.0 - POTEWMAVALUE) + cPot * POTEWMAVALUE; cPot = floor(smoothedPotValue + 0.5); #if (0) // direction not needed for BOOM32, but coded for testing if (cPot > 512) { stepDirection = 1; } else { stepDirection = -1; } // NOTE: my stepper asks for 12V and uses more than 200mA, which is the // limit of my bench power supply... // That may be the limit of how fast we can step. // interval is least at extremes of pot travel float scaledValue = abs(cPot - 512.0) / 512.0; // 1 at ends to 0 in middle scaledValue = 1.0 - sqrt(scaledValue); // 0 at ends to inf in middle int temp = floor(scaledValue * 1000000 + 0.5); #define min_stepper_interval_us 1000 #define max_stepper_interval_us 125000 stepper_interval_us = min_stepper_interval_us + scaledValue * (max_stepper_interval_us-min_stepper_interval_us); #else // desired us/phase: // / 40-160 bpm // * 16-32 beats per rev // ==> 40/32=1.25 - 160/16=10 RPM // / 200 steps/rev // / 4 coils / step // / 2 phases/coil // * 60 sec/min // * 1e6 us/sec // --> factor = 15e6/400 = 3.75e4 // ==> is 3.75e3 (fast) - 6.0e4 // is 7500 to 60000 us/phase #define min_stepper_interval_us 3750 #define max_stepper_interval_us 30000 stepper_interval_us = min_stepper_interval_us + ((1023 - cPot) * (max_stepper_interval_us - min_stepper_interval_us)) / 1024; rpm = ( 60 * 1e6 / stepper_interval_us) / PHASES_PER_REVOLUTION; #endif steps_remaining_in_evaluation--; if (steps_remaining_in_evaluation <= 0) { for (i = 0; i < NSENSORSINSTALLED; i++) { discriminators[i] = min_levels[i] + (max_levels[i] - min_levels[i]) * DISCRIMINATORLEVELPCT / 100; min_levels[i] = 1024; max_levels[i] = 0; } // SendDataBuffer ("\n\n", 2); steps_remaining_in_evaluation = ADC_READINGS_PER_LEVEL_REEVALUATION; } // make determinations about what's on and what's off for (i = 0; i < NSENSORSINSTALLED; i++) { if (i < 2) { sensorValue = cSensor[0][i]; } else { sensorValue = cSensor[1][i - 2]; } if (sensorValue < min_levels[i]) min_levels[i] = sensorValue; if (sensorValue > max_levels[i]) max_levels[i] = sensorValue; BOOL currentValue = sensorValue < discriminators[i]; if (noteIsOn[i] != currentValue) { if (currentValue) { // turn note on if (DO_MIDI) { snprintf (strBuf, bufLen, "%c%c%c", (char) 0x99, (char) i, (char) 64); } else if (NOTE_NOTES) { snprintf (strBuf, bufLen, "NoteOn (%d)\n", i); } } else { // turn note off if (DO_MIDI) { snprintf (strBuf, bufLen, "%c%c%c", (char) 0x89, (char) i, (char) 64); } else if (NOTE_NOTES) { snprintf (strBuf, bufLen, "NoteOff (%d)\n", i); } } if (i == 0) LED_MIDI = currentValue; SendDataBuffer (strBuf, strlen(strBuf)); noteIsOn[i] = currentValue; } } if (0) { snprintf (strBuf, bufLen, "%8d : %3d %3d : %3d %3d : %3d %3d : %3d %3d : %3d %3d :\n", steps_remaining_in_evaluation, min_levels[0], max_levels[0], min_levels[1], max_levels[1], min_levels[2], max_levels[2], min_levels[3], max_levels[3], min_levels[4], max_levels[4] ); SendDataBuffer (strBuf, strlen(strBuf)); } // switch banks bank = 1 - bank; if (bank == 0) { PWR_BANK1 = 0; PWR_BANK1_TRIS = 1; PWR_BANK0 = 1; PWR_BANK0_TRIS = 0; } else { PWR_BANK0 = 0; PWR_BANK0_TRIS = 1; PWR_BANK1 = 1; PWR_BANK1_TRIS = 0; } AD1CON1bits.DONE = 0; enableADC = 0; } // ADC enabled if (enableStep) { theStep += stepDirection; if (theStep >= PHASES_PER_STEP) theStep = 0; if (theStep < 0) theStep = PHASES_PER_STEP - 1; STEPPER0 = stepSequence[theStep][0]; STEPPER1 = stepSequence[theStep][1]; STEPPER2 = stepSequence[theStep][2]; STEPPER3 = stepSequence[theStep][3]; enableStep = 0; } if (enablePrint) { // snprintf (strBuf, bufLen, " stepper_interval_ms = %d\n", stepper_interval_ms); // SendDataBuffer (strBuf, strlen(strBuf)); // enablePrint = 0; } } // infinite loop return -1; }