This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Sampling one ADC input on a 2803x?

Hi there, I have a very simple thing I would like to do.  I have an ultrasonic rangefinder connected to the ADCINA0 port of my 28035 MCU.  The rangefinder outputs a voltage level (0 to 3.3V) depending on how close the nearest object is.  I would like to program the MCU so that, when I ask it to, it samples this voltage once and returns the value.  A couple specifications about this:

1.) I don't need oversampling.  The rangefinder isn't precise enough to need it.  (Though I suppose if it's super simple to implement it certainly wouldn't hurt.)

2.) I have plenty of time to be able to wait for the ADC data.  I would much rather not use interrupts to handle this.  Instead, I'd like to just wait for the data to be ready before moving on.

I'm just having trouble cutting through all the bells and whistles that the ADC peripheral offers to get at what I consider to be a super simple task..  If someone could give me an idea of what registers to set, I'm sure I could take it from there with the code.

Thanks!

--Daniel

  • Daniel,

    See appnote SPRA958.

    http://www.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=spra958l&docCategoryId=1&familyId=1414

    It is titled "Running from flash" but forget about that.  The code examples that come with it sample a single ADC channel, like what you want to do.  They do use the ADC interrupt, but it is clean and you can easily just go ahead and use the interrupt.  If you don't want to use the interrupt, modify the code so that you don't enable the ADC interrupt and instead poll the ADC interrupt flag.

    Start with the F28035_nonBIOS_RAM project.  Also, read the appnote first, in particular the entire section 8 that describes what the code is doing.  The code is well commented, so you should be able to understand it and modify as needed.

    Regards,

    David

  • Hey daniel,

    Sounds like a cool project.  What you want to do is use a software force of SOC.  This will look something like this (probably won't compile, but gives you the idea):

    //setup SOC0 and SOC1 (only do this once)

    AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //throwaway sample for 1st sample erratum

    AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //acquisition window is 6+1 = 7 cycles (minimum). can adjust this to make window longer (good if source impedance is not very low)

    AdcRegs.ADCSOC0CTL.bit.CHSEL= 0; //select A0

    AdcRegs.ADCSOC1CTL.bit.CHSEL= 0;  //select A0

    //no need to set AdcRegs.ADCSOCxCTL.bit.TRIGSEL since using software force

    //sample A0 with software (do this as needed)

    AdcRegs.ADCSOCFRC1.all = 0x0003; //set SOC0 and SOC1 to be converted

    asm("    RPT #255 || NOP") //wait 255 cycles plenty longer than conversion time of about 13*2 + 7 + 2, (danger, can't be interrupted, so can affect ISR latency - could use empty for loop or similar to delay instead)

    Uint16 range = AdcResult.ADCRESULT1; //we ignored ADCRESULT0 due to erratum

    //end code

    if you want to add oversampling, also setup SOC2,3,4,...etc to all point to channel a0.  Add more bits to the software force to trigger those SOCs too.  Make sure to wait long enough for those samples.  Then read all the result registers and average them (or do some other filtering)