Tengo ADC en stm32f429 con 3 canales activados (escribiendo datos con DMA). Aunque sospecho que esta pregunta puede no ser específica de STM32, probablemente sea una pregunta general de ADC.
LA "RESPUESTA"
He encontrado "solución". Intenté utilizar los canales 6 y 7 en lugar de 1 y 2: el problema desapareció. Aparentemente los canales 1 y 2 son "especial", aunque no pude encontrar por qué en la hoja de datos (o la perdí). Tal vez sean más exigentes con la potencia de entrada, id. Si hay alguien ¿Quién puede dar alguna información? Siéntase libre, lo aceptaré como un respuesta (si es lo suficientemente bueno). Tal vez es stm32 específico, quién sabe ...
- Los 3 canales obtienen el valor de conversión ADC correcto si los conecto al potenciómetro (o directamente a Vcc (valor 4095) o GND (valor 0))
- Si los dejo flotando, las cosas se ponen extrañas: el canal 0 tiene un valor de ~ 400 y los canales 1 y 2 tienen un valor de 0. ¿Qué está pasando?
- Y el problema real es que tengo 3 sensores que quiero conectar al ADC, pero por alguna razón, solo el canal 0 del ADC funciona y el canal 1 y 2 no funcionan con el sensor (¡a pesar de que estaban trabajando con potes!)
Lo que he hecho / notado:
- Parece que esto no tiene nada que ver con el hecho de que uso tres sensores. Intenté probar uno por uno. La conclusión es que los sensores funcionan bien con el canal 0 y no funcionan en absoluto en los canales 1 y 2. incluso cuando se prueban uno por uno sin causar problemas entre sí.
- Esto es realmente extraño: cuando pruebo con el osciloscopio la salida de mi sensor, funciona bien sin ADC conectado en absoluto o con el canal 0 conectado. Ahora, tan pronto como conecto el canal 1 o 2 a él, el osciloscopio muestra cero independientemente de lo que haga con el piezo.
Mi sensor está configurado es básicamente un sensor piezoeléctrico con algunos diodos para engancharlo a 3.3 V y omitir la parte negativa (también intenté poner una resistencia 1M en paralelo a la tapa, pero esto no resolvió nada).
En esta captura de pantalla puede ver la ventana de depuración en Keil uVision, muestra el valor 403 en el canal 0 de ADC, incluso si no hay nada conectado. Medí que es ~ 200-250 mV. Debido a que el canal 0 es el único que funciona con el sensor, asumo que otros canales deberían tener el mismo ~ 250 mV, pero no lo son.
Aquí están mis configuraciones para stm32f429 usando la biblioteca HAL. Todos los canales deberían estar conectados de la misma manera, pero me pregunto si algo está mal en las configuraciones ...
void MX_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_CLOCKPRESCALER_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION12b;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 3;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = EOC_SEQ_CONV;
HAL_ADC_Init(&hadc1);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 3;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
Y el archivo stm32f4xx_hal_msp.c
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/* Peripheral clock enable */
__ADC1_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA0/WKUP ------> ADC1_IN0
PA1 ------> ADC1_IN1
PA2 ------> ADC1_IN2
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_adc1.Instance = DMA2_Stream0;
hdma_adc1.Init.Channel = DMA_CHANNEL_0;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_adc1);
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
EDIT 1
También intenté usar un sensor piezoeléctrico con resistencia de 1M, lo mismo, tan pronto como conecto el ch 1 o 2, el osciloscopio muestra cero.
EDIT 2
Una cosa más extraña: soné los pines ch1 y ch2 y parecen estar conectados a tierra. O_o