Estoy buscando implementar ADC y DMA con HAL en un F767. Quiero que el ADC siempre convierta y almacene en la memoria a través de DMA hasta que alcance el límite de búfer de 320 y luego quiero ir a una función de devolución de llamada completa de conversión. ADC parece estar bien habilitado y convierte los valores hasta el límite del búfer y luego pasa a la rutina de devolución de llamada de conversión. El problema que tengo es que cuando compruebo el búfer ADC en la función de devolución de llamada de conversión completa es que la primera mitad del búfer ADC (exactamente la primera mitad, 0 a 160) está llena de estos valores cuando la entrada ADC está conectada a tierra:
Esperaría valores entre 0 y aproximadamente 15 en el peor de los casos, por lo que es parcialmente consistente.
Cuando conecto el ADC a 3V, esperaría cerca de 4096, pero en cambio obtengo:
Como los valores SON más bajos cuando el ADC está conectado a tierra y más altos cuando el ADC está conectado a 3V, no son valores completamente basura, no son solo valores aleatorios almacenados en la memoria. Además, después de la primera mitad del búfer, todo son solo ceros, así que estoy pensando que tal vez configuré mal el ADC o lo leí mal. Supongo que debido a que el DMA almacena los valores en la matriz, solo necesito verificar la matriz durante la función de devolución de llamada de conversión, pero esto no funciona. El tamaño del búfer y la llamada DMA
//this code before main #define ADC_BUFFER_LENGTH 340 //5000khz signal / 1.67 Msps = 334 samples
uint32_t ADC_Val[ADC_BUFFER_LENGTH];
//this code after main but before while loop
HAL_ADC_Start_DMA(&hadc1, ADC_Val, ADC_BUFFER_LENGTH);
Y la inicialización del ADC:
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
//ADC operating @ 1.6MHz - 100MHz/4 = 25MHz
//25MHz/(12+3) = 1.67Msps
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** 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 = ADC_SCAN_DISABLE;
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 = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
y mi función de devolución de llamada de conversión:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
//chop out sample window 1 and 2
//sample window 1
//Pulse Tx is 50 uS wide, there is a settling delay of 20us = 70us
//with a sampling rate of 1.67Msps 70*1.67 = 119 samples
uint32_t ADC_SW1_Temp[ADC_SW1_LENGTH] = {0};
//30us sampled window @ 1.67Msps = 50 samples
for(int i = 0 ; i < ADC_SW1_LENGTH; i++)
{
ADC_SW1_Temp[i] = ADC_Val[(ADC_SW1_START + i)];
}
ADC_SW_1 = 0;
}
¿Hay algo aquí que sea obviamente incorrecto? Si no, ¿cuál es la mejor manera de abordar la depuración de DMA y ADC?
No es un ADC de 32 bits, pero está interpretando sus salidas como UINT32.
Mirando sus códigos inactivos, por ejemplo, 131073 = 2 ( * 2 ** 16) + 1, o 2 y 1 si estaban empaquetados UINT16,
Así que todos esos valores me parecen bien.
Podría hacer lo mismo con los valores de "3V", pero te dejaré hacerlo.
¡Debe habilitar las solicitudes continuas de DMA!
hadc1.Init.DMAContinuousRequests = HABILITAR;
Y asegúrese de que la función DMA_INIT() se llame antes que ADC1_Init()
crisd91
carl gilberto
usuario_1818839