2011-12-05 03:55 PM
Hi,
I'm trying to implement a sensor network. I know that I must use DMA to be able to work with multiple ADC channels. Since this is a school assignment, I'm not allowed to use any libraries. For some reason I'm only able to read the first channel. The second one is constant zero. How do I even define that the ADC channel 3 is supposed to go to DMA channel 2 ? Here's a snippet of my code: [CODE] int32_t temperature; //globals uint32_t degree; void ADC_Configuration(void){ RCC->APB2RSTR |= ADC_RESET; //reset RCC->APB2RSTR &= ~ADC_RESET; //cancel reset ADC1->CR2 |= ADC_SWSTART; //set start by SW ADC1->SMPR1 |= ADC_SMP_16; //sample 28.5 on channel 16 ADC1->SMPR2 |= ADC_SMP_3; //sample 7.5 on channel 3 ADC1->SQR3 |= ADC_SQR; //channel 16 first, channel 3 second ADC1->CR2 |= ADC_CALIB_RST; //reset calib, ADON - start ADC1->CR2 |= ADC_DMA_EN; //DMA while (ADC1->CR2 & 0x8); //wait for ADC to reset calibration ADC1->CR2 |= ADC_START_CALIB; //start calibration while (ADC1->CR2 & ADC_START_CALIB); //wait for ADC to start calibration ADC1->CR2 |= ADC_TSVREFE; //TSVREFE, ADON start //jeste treba udelat DMA } /*---------------------------------------------------------------------------- DMA Configuration *----------------------------------------------------------------------------*/ void DMA_Configuration(void){ DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR); DMA1_Channel1->CMAR = (uint32_t)&temperature; DMA1_Channel1->CNDTR = 0x1; DMA1_Channel1->CCR = 0x1A20; DMA1_Channel1->CCR |= 0x1; DMA1_Channel2->CPAR = (uint32_t)&(ADC1->DR); DMA1_Channel2->CMAR = (uint32_t)°ree; DMA1_Channel2->CNDTR = 0x1; DMA1_Channel2->CCR = 0x1A20; DMA1_Channel2->CCR |= 0x1; } int32_t ReadTemp(void){ int32_t temp; uint32_t deg; int32_t v25 = 1738; int32_t avg_slope = 56; int32_t constant = 250000; int32_t magnify = 10000; //temp = (int32_t) degree; temp = (int32_t) temperature; // THIS ONE WORKS, BUT IF I CHANGE IT TO DEGREE, IT BECOMES CONSTANTS ZERO if (temp == v25) return constant; temp = v25 - temp; temp = temp*magnify; temp =temp/avg_slope; temp = temp + constant; return temp; } int main (void) { int32_t temper; float value; RCC_Configuration(); //note that I do send clk to ADC and DMA GPIO_Configuration(); USART_Configuration(); buffer_Init(); // init RX / TX buffers DMA_Configuration(); ADC_Configuration(); ADC1->CR2 |= ADC_SWST_EXTTRIG; temper = ReadTemp(); //clear the first measurement, which is always a bit off while (1) { // Loop forever char string[7]; Delay(4000); ADC1->CR2 |= ADC_SWST_EXTTRIG; temper = ReadTemp(); ADC1->CR2 |= 0x1; value = (float)temper; value = value/10000; snprintf(string, SIZE, ''%f'', value); SendString(string); SendChar(0xD); SendChar(0xA); Delay(4000); } } [/CODE] Any help would be appreciated.2011-12-05 05:19 PM
Any help would be appreciated.
You need to read the manual more thoroughly, especially if you're going to ignore the libraries. Your inability to use the library in your final code does not preclude you from examining all the examples and source code to understand what does and what does not work. ADC1 is only EVER going to use DMA1.Channel1 To read multiple ADC channels, you need to set DMA to run cyclically across multiple memory locations into which it will store your variables. The size of that memory will be dictated by the number of ADC channels you plan on reading.2011-12-06 01:48 AM
>You need to read the manual more thoroughly, especially if you're going to ignore the libraries. Your inability to use the library in your final code does >not preclude you from examining all the examples and source code to understand what does and what does not work.
I've looked at some ADC + DMA samples using libraries, but it I wasn't able to find the libraries itself, so it was pretty useless. Could you provide me with a url to the libraries itself?
>To read multiple ADC channels, you need to set DMA to run cyclically across multiple memory locations into which it will store your variables. The size >of that memory will be dictated by the number of ADC channels you plan on reading.
So, should I only have one memory location and set memory auto increment in the DMA.CR ? And should I only use the DMA.channel1 ? Now, considering that the sensors have different sample rates, wouldn't one of the channels store its reading more often than the other, filling more of the memory than expected?Let's say I expect this behaviour: Memory location = reading from ADC channel1 Memory location + 4 = reading from ADC channel2 ... ...Couldn't something like this happen ? Memory location = reading from ADC channel1 Memory location + 4 = reading from ADC channel1 again Memory location + 8 = reading from ADC channel2 ... ...
2011-12-06 07:10 AM
Could you provide me with a url to the libraries itself?
http://www.st.com/internet/evalboard/product/250863.jsp
Design Support -> Firmware
So, should I only have one memory location and set memory auto increment in the DMA.CR ? Yes, you'll need an arrayAnd should I only use the DMA.channel1 ? You really don't have much of a choice do you? According to the documentation I've read ADC1 is hardwired to DMA1.Channel1. If you have ADC3 that is hardwired to DMA2.Channel5Now, considering that the sensors have different sample rates, wouldn't one of the channels store its reading more often than the other, filling more of the memory than expected?
Not sure how you'd handle that, but it sure sounds like fun. I'd guess you'd either have to use a larger array, if the ADC actually permits that kind of interleaving, or change the ADC and DMA configuration at each TC interrupt, or use ADC3/DMA2. If you can do each ADC read on demand, perhaps you don't need DMA, and a simple state machine would suffice. You'll really need to get your head around the documentation, to determine what is and what is not physically possible with the hardware you have chosen. Documentation for STM32F100 series http://www.st.com/internet/mcu/product/216844.jsp Design Support -> Reference Manual http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00246267.pdf See table 54 on page 149
2011-12-06 08:45 AM
Thanks a lot,
I'll get to it and report back if I succeed.