2017-05-31 09:05 AM
Hi guys,
i'd like to retrieve a FSR signal from PC0 pin (see jpeg attached for schematic) on my STM32F407VG-Discovery. I've to use System Workbench for STM32 as IDE and HAL driver. This is my code, it should light LED4 when i press the FSR but it doesn't work and i don't know why. Anyone can help me?
Next step will be use DMA for get multiple ADC signal, i've to retrieve in some way 19 signals from 19 FSR
Thanks
PS: with Arduino it works perfectly (with AnalogRead(PIN♯) so i think the hardware connections are corrects)
/**
****************************************************************************** * @file main.c * @author Ac6 * @version V1.0 * @date 01-December-2013 * @brief Default main function. *******************************************************************************/&sharpinclude 'stm32f4xx.h'
&sharpinclude 'stm32f4_discovery.h'static ADC_HandleTypeDef hadc1 = {
.Instance = ADC1};void boardInit(void) {
//Inizializza i driver HAL HAL_Init();//Dichiara le struct per il clock e l'oscillatore
RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct;//Abilita il power clock
__PWR_CLK_ENABLE();//Configurazione volt-scaling
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//Configurazione oscillatore
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE/1000000u); RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct);//Configurazione clock
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);}/* ADC1 init function */
static void ADC1_Init(void){ADC_ChannelConfTypeDef sConfig;/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)*/hadc1.Instance = ADC1;hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;hadc1.Init.Resolution = ADC_RESOLUTION_12B;hadc1.Init.ScanConvMode = ENABLE;hadc1.Init.ContinuousConvMode = ENABLE;hadc1.Init.DiscontinuousConvMode = DISABLE;hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;hadc1.Init.NbrOfConversion = 4;hadc1.Init.DMAContinuousRequests = ENABLE;hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.*/sConfig.Channel = ADC_CHANNEL_11;sConfig.Rank = 1;sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.*/sConfig.Channel = ADC_CHANNEL_2;sConfig.Rank = 2;/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.*/sConfig.Channel = ADC_CHANNEL_14;sConfig.Rank = 3;/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.*/sConfig.Channel = ADC_CHANNEL_15;sConfig.Rank = 4;}void ledInit(void) {
//Inizializzazione LED BSP_LED_Init(LED4); BSP_LED_Init(LED5); BSP_LED_Init(LED6);}void initialize() {
boardInit(); ADC1_Init(); ledInit();}void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{ if(AdcHandle -> Instance == ADC1) BSP_LED_Toggle(LED4);}int main(void)
{ initialize();HAL_NVIC_EnableIRQ(ADC_IRQn);
while(1) {
}}#dma #stm32f4-discovery #adc2017-06-01 06:40 AM
I don't really speak Cube, but one thing leaped to my eye:
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;You configure the ADC for software trigger.
But I miss any code that actually triggers an ADC conversion.
2017-06-01 10:10 AM
Thanks for your reply, but in theory what have i to do to make this code works?
2017-06-01 10:45 AM
>> But I miss any code that actually triggers an ADC conversion.
> Thanks for your reply, but in theory what have i to do to make this code works?
Write code which triggers the conversion, both in main() (to trigger the first conversion) and in the ISR (to maintain repeated conversion, if that is what you desire).
I don't speak Cube either, but normally you'd write 1 to ADC_CR2.SWSTART.
Alternatively, you set the ADC to perform continuous conversion by setting ADC_CR2.CONT, and then you don't need to trigger regularly anymore.
JW
2017-06-01 12:08 PM
Alternatively, you set the ADC to perform continuous conversion by setting ADC_CR2.CONT, and then you don't need to trigger regularly anymore.
Correct. But toggling a LED with the given ADC settings / conversion rate would be a bit harsh to the eyes ;)
2017-06-03 05:44 PM
Is possible to have a code example? After i will reverse-engineering it ahah... my goal isn't turn in the led (this only to test ADC) but is take numeric value of the FSR pressure
2017-06-06 01:12 AM
Short of an actual example:
Assuming your pressure measurement has a low bandwidth, you can try simple way.
Configure the SysTick timer of your sample rate, and call the ADC sample trigger function from the SysTick interrupt.
That would work perfectly well up to several hundred Hertz.
And perhaps review your ADC configuration, if it works well with your hardware (input impedance, sampling time, i.e. time the S&H capacitor is 'charged' ...)