cancel
Showing results for 
Search instead for 
Did you mean: 

Adc doesn't work when timers are used

d4ng3r09
Associate II
Posted on June 22, 2014 at 13:14

Hi , i am reading a value from an lm35 value with the adc .When it reaches a specified level , i trigger pin 8 on gpio A for a certain delay then shut it down and wait the same delay to restart the process if this value is reached again.

I get things to work by using a simple loop to make a delay but after that i decided to get more precise delay and wrote a code for a delay with timers. I tried the 2 delay function to toggle a led and it worked but when i introduced them with the ADC ,this one doesn't give anymore correct reading values. I am using stm32f0 discovery. Here is my code:

#include <
stm32f0xx_tim.h
>
#include ''stm32f0xx.h''
#include<
stm32f0xx_gpio.h
>
#include<
stm32f0xx_rcc.h
>
#include<
stm32f0xx_pwr.h
>
#include<
stm32f0xx_adc.h
>
void configTimer() {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;
TIM_TimeBaseInitStruct.TIM_Prescaler = 8000 - 1;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
//TIM_SetCounter(TIM2,42000);
TIM_Cmd(TIM2, ENABLE);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
//TIM_PrescalerConfig()
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct2;
TIM_TimeBaseInitStruct2.TIM_Period = 60000 - 1;
TIM_TimeBaseInitStruct2.TIM_Prescaler = 8000 - 1;
TIM_TimeBaseInitStruct2.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct2.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct2.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct2);
TIM_Cmd(TIM3, ENABLE);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
}
void delay10() {
while (1) {
if (TIM_GetFlagStatus(TIM2, TIM_FLAG_Update) != RESET) {
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
break;
}
}
}
void delay60() {
while (1) {
if (TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) != RESET) {
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
break;
}
}
}
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStruct ;
void AdcConfiguration(){
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
/* Initialize the ADC_ContinuousConvMode member */
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
/* Initialize the ADC_ExternalTrigConvEdge member */
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
/* Initialize the ADC_ExternalTrigConv member */
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
/* Initialize the ADC_DataAlign member */
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
/* Initialize the ADC_ScanDirection member */
ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Upward ;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_Init(ADC1,&ADC_InitStruct);
ADC_ChannelConfig( ADC1,ADC_Channel_1, ADC_SampleTime_239_5Cycles);
ADC_Cmd(ADC1, ENABLE);
ADC_StartOfConversion(ADC1);
}
void InitPins()
{RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure2;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure2.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStructure2.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure2);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void delay()
{long j=0;
while (j<
50000000
)// delay 15 secondes
{
j++;
}
}
void main(void)
{int 
j
=
0
;
uint16_t 
value
=
0
;
float 
temp
=
0
;
AdcConfiguration();
configTimer();
InitPins();
ADC_StartOfConversion(ADC1);
GPIO_ResetBits( GPIOA,GPIO_Pin_8);
while(1)
{ ADC_StartOfConversion(ADC1);
while (j<20)
{
value
=
ADC_GetConversionValue
(ADC1)+value;
j
=j+1;
}
j
=
0
;
value
=value/20;
temp
=
100
*(value*3.3/4096+0.015);
if (temp>32)
{GPIO_SetBits( GPIOC,GPIO_Pin_8);
GPIO_SetBits( GPIOA,GPIO_Pin_8);
delay10();
GPIO_ResetBits( GPIOA,GPIO_Pin_8);
GPIO_ResetBits( GPIOC,GPIO_Pin_8);
delay10();
ADC_StopOfConversion(ADC1);
value=0;
temp=0;
}
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
void PWR_BackupAccessCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the Backup Domain Access */
PWR->CR |= PWR_CR_DBP;
}
else
{
/* Disable the Backup Domain Access */
PWR->CR &= (uint32_t)~((uint32_t)PWR_CR_DBP);
}
}
#endif

8 REPLIES 8
raptorhal2
Lead
Posted on June 22, 2014 at 18:47

I am not sure results can be guaranteed using the F0 library with an F4 processor.

The ADC DR register is read repeatedly without a test for a new conversion complete.

Cheers, Hal

d4ng3r09
Associate II
Posted on June 22, 2014 at 21:54

My bad , i am using f0 (sorry for that ).

I guess i will try that and keep you updated!

Thank you.

Posted on June 22, 2014 at 22:35

Are you even sure it's getting to the GPIO/Delay code? As indicated above you really should wait on the ADC EOC before reading the result.

You seem to throw away a lot of precision with the way you're doing the math there, and I'm pretty sure all the DISCO boards run at 3.0V and not 3.3V
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 22, 2014 at 22:41

uint32_t value=0; // can't use 16-bit 20*4096 > 65535
float temp=0;
..
// value=value/20;
// temp=100*(value*3.3/4096+0.015);
temp = 0f * (((float)value * 3.0f) / (40f * 0f)) + 0.015f);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
d4ng3r09
Associate II
Posted on June 23, 2014 at 10:09 This is my updated code:

while (1) {
ADC_StartOfConversion(ADC1);
while (j < 
20
) {
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET)
{
}
ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
value
= 
ADC_GetConversionValue
(ADC1) + value;
j
= j + 1;
}
j
= 
0
;
value
= value / 20;
temp
= 
100
* (value * 3 / 4096 + 0.015);
if (temp > 32) {
GPIO_SetBits(GPIOC, GPIO_Pin_8);
GPIO_SetBits(GPIOA, GPIO_Pin_8);
delay10();
GPIO_ResetBits(GPIOA, GPIO_Pin_8);
GPIO_ResetBits(GPIOC, GPIO_Pin_8);
 delay60();

}
ADC_StopOfConversion(ADC1);
value = 0;
temp = 0;
}
}

I found a new bug now:the program seems to run the 10 seconds delay but never the 60 seconds.I inversed the 60 seconds function with the 10 seconds but then the led was never shut down. Another point : i replaced delay60 by calling 6 times delay10 then i simulated the temperature level a first time and every thing seemed to be ok until i tried to simulate it again then i noticed that the LED blinked slightly to finally start the cycle normally again after a 'random' period of time. Can somebody help me to solve this problem? Thank you for your attention.
Posted on June 23, 2014 at 16:23

I don't know what your processor speed is, but 60 seconds is billions of ticks at 24 MHz, and I'm not sure your timer factors with get you there.
 Suggest you setup a 1ms SysTick, and wait for 60000 ticks. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
d4ng3r09
Associate II
Posted on June 24, 2014 at 18:07

Actually i used both delay functions on simple gpio toggle and it was fine but when i introduced the adc it didn''t seem to work.

Posted on June 24, 2014 at 18:09

And the value of temp is what?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..