2020-05-14 05:01 AM
Hi every one.
I want to read the value of a potentiometer connected to the pinA1, and if the read value is more than 2000, one of the LEDs, otherwise the second LED, will be on.
Can anybody please help me? what is wrong with my code? I don't have too much experience and I can't find problem.
#include "stm32f0xx.h"
#include "stm32f0xx_conf.h"
void Delay(__IO uint32_t nCount) {
while(nCount--) {
}
}
int main(int argc, char* argv[])
{
//(#) ADC pins (pA1) configuration --------------------------------------------------------------
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//leds (pB0... pB3) configuration--------------------------------------------------------------
GPIO_InitTypeDef GPIO_LEDs;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_LEDs.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_LEDs.GPIO_Mode = GPIO_Mode_OUT;
GPIO_LEDs.GPIO_OType = GPIO_OType_PP;
GPIO_LEDs.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_LEDs.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_LEDs);
//ADC-------------------------------------------------------------------------------------------
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_GetCalibrationFactor(ADC1);
ADC_Cmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET);
ADC_StartOfConversion(ADC1);
uint16_t valueADC = ADC_GetConversionValue(ADC1);
ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_1_5Cycles);
//dma--------------------------------------------------------------------------------------
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr= (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)&valueADC;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
ADC_DMACmd(ADC1, ENABLE);
while (1)
{
if(valueADC<2000){
GPIO_SetBits(GPIOB, GPIO_Pin_0);
GPIO_ResetBits(GPIOB, GPIO_Pin_1);
}
else if(valueADC>2000){
GPIO_SetBits(GPIOB, GPIO_Pin_1);
GPIO_ResetBits(GPIOB, GPIO_Pin_0);
}
}
}
2020-05-14 06:05 AM
Declare valueADC as volatile, otherwise the main loop may keep it in a register, and never pick up any changes at the memory location allocated to it.
All variables touched by DMA or interrupt handlers should be declared as volatile.
It is also good practice to declare those variables with static storage duration, i.e. never as local variables.
2020-05-14 06:58 AM
volatile uint16_t valueADC = ADC_GetConversionValue(ADC1);
Thanks a lot. I did that, but it still doesn't work.
all LEDs are off. When I change the potentiometer, nothing happens.
2020-05-14 07:43 AM
What MCU is that?
Please post the contents of the DMA and ADC registers.
2020-05-14 10:33 AM
stm32f091
Do you mean ADC and DMA register map?
2020-05-14 12:19 PM
I mean the contents of the registers. Then it would be possible to check them against the pages preceding the ones that you have posted.