Go Down

Topic: Reading analog channel MANUALLY (Read 1 time) previous topic - next topic

rs1485

Hi!

Me and my buddy are trying to read an analog chanel to no avail.

The task is part of a weather station that we are building for a course that requires it.
We do not have access to the libraries that include functions like;
AnalogRead(), PinMode(), DigitalWrite() etc so everything has to be done manually by setting bits on every register.

This is what we tried to read the analog channel:
Code: [Select]

*ADC_CHER = 1<<5; //Enables channel 5
*ADC_MR = 1<<7; //Enables freerun mode to convert continously
while(true)
{
    if(...key pressed...)
          printf("%d   \n", *ADC_CDR5 & 0xFFF); //Prints the converted data that's stored on the channels own register
}


The analog pin is hooked up to a photo resistor (LDR).
The program always prints 0 whenever I press the key.
We are working with "Arduino DUE"

What are we doing wrong?

Gericom

You first need to setup something like this:
Code: [Select]

adc_init(ADC, 84000000, 84000000/2, 0);
adc_configure_timing(ADC, 1, ADC_SETTLING_TIME_3, 0);
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

rs1485

As I said, we don't have access to those libraries. I.e. no adc_init and the other.

I would appreciate if you could copy the implementations of those 2 functions.
However, you say "like this" so I  assume that you are only guessing.

chriskner

rs1485,

The source is included with the Arduino distribution.

I believe it's all there, if you look for it.

You'll want to read the chip's datasheet as well.

Does the course project require that you _not_ use Arduino's libraries?  I ask because I wonder 'what could possibly be the point of all of this'?

If the use of the Arduino libraries is forbidden, then is is a great exercise.  I just hope that it's not due tomorrow.

-Chris

Gericom


As I said, we don't have access to those libraries. I.e. no adc_init and the other.

I would appreciate if you could copy the implementations of those 2 functions.
However, you say "like this" so I  assume that you are only guessing.

I am not guessing as I am using it myself, but I am not sure of that kind of things are actually initialize by default. Anyway, here are the functions.
adc_init:
Code: [Select]

/**
* \brief Initialize the given ADC with the specified ADC clock and startup time.
*
* \param p_adc Pointer to an ADC instance.
* \param ul_mck Main clock of the device (value in Hz).
* \param ul_adc_clock Analog-to-Digital conversion clock (value in Hz).
* \param uc_startup ADC start up time. Please refer to the product datasheet
* for details.
*
* \return 0 on success.
*/
uint32_t adc_init(Adc *p_adc, const uint32_t ul_mck,
const uint32_t ul_adc_clock, const uint8_t uc_startup)
{
uint32_t ul_prescal;

/*  Reset the controller. */
p_adc->ADC_CR = ADC_CR_SWRST;

/* Reset Mode Register. */
p_adc->ADC_MR = 0;

/* Reset PDC transfer. */
p_adc->ADC_PTCR = (ADC_PTCR_RXTDIS | ADC_PTCR_TXTDIS);
p_adc->ADC_RCR = 0;
p_adc->ADC_RNCR = 0;

ul_prescal = ul_mck / (2 * ul_adc_clock) - 1;
p_adc->ADC_MR |= ADC_MR_PRESCAL(ul_prescal) |
((uc_startup << ADC_MR_STARTUP_Pos) &
ADC_MR_STARTUP_Msk);
return 0;
}

And adc_configure_timing:
Code: [Select]

/**
* \brief Configure ADC timing.
*
* \param p_adc Pointer to an ADC instance.
* \param uc_tracking ADC tracking time = uc_tracking / ADC clock.
* \param uc_settling Analog settling time = (uc_settling + 1) / ADC clock.
* \param uc_transfer Data transfer time = (uc_transfer * 2 + 3) / ADC clock.
*/
void adc_configure_timing(Adc *p_adc, const uint8_t uc_tracking,
const enum adc_settling_time_t settling,const uint8_t uc_transfer)
{
p_adc->ADC_MR |= ADC_MR_TRANSFER(uc_transfer)
| settling | ADC_MR_TRACKTIM(uc_tracking);
}
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

Go Up