STM32L151 Registro de rastreo de configuración de reloj ADC

Tabla de contenido

I. Introducción

En segundo lugar, el proceso de excavación.

Tres, récord de llenado de fosas


I. Introducción

En primer lugar, lo que quiero decir con "rastreo" no es que haya un problema con el reloj de STM32L151. El reloj de STM32L151 definitivamente está bien, pero hay algunas diferencias con la configuración del reloj de STM32F1 o F4 . No presté atención a estas diferencias. Pensé que los relojes de L1 y F1 deberían ser los mismos, así que obtuve esta nota de escalada en boxes. Cavo los boxes y los lleno yo solo, ¡lo cual es bastante emocionante! ¡Todavía es demasiado joven!

En segundo lugar, el proceso de excavación.

Usamos el chip L151 en un proyecto, utilicé la configuración CubeMAX para generar el proyecto, entre ellos, el L151 ADC se usa para recolectar cantidades analógicas multicanal, usando el método DMA. Debido al bajo consumo de energía (este chip se usa para un bajo consumo de energía), hay una configuración de reloj interno de alta velocidad (HSI) en la inicialización del reloj . Dado que la serie F1 anterior de computadoras de un solo chip usa más, HSI en el proyecto F1 No lo he usado antes, pensé que los relojes deberían ser los mismos, así que inicialicé manualmente el HSI para protegerlo. Pegue la configuración de HSI que bloqueé , SystemClock_Config es generado automáticamente por CUberMAX

void SystemClock_Config(void)
{
    ....
    LL_RCC_HSI_Enable();
    /* Wait till HSI is ready */
    while(LL_RCC_HSI_IsReady() != 1)
    {
    }
    LL_RCC_HSI_SetCalibTrimming(16);
    ....
}

Tres, récord de llenado de fosas

CubeMAX se utiliza para configurar ADC_IN18 para recopilar la cantidad analógica de este canal de forma cíclica. La configuración clave es:

1. DMA: dirección de periférico y dirección de memoria, el modo es cíclico (necesario para ADC multicanal), longitud de datos.

2. ADC: la alineación de datos está alineada a la derecha de 12 bits, se activa el modo de bajo consumo de energía, se inicia el escaneo multicanal, la conversión de canal se convierte en modo continuo, se deshabilita el modo discontinuo, se inicia la transmisión DMA, se establece la secuencia de canal y el tiempo de muestreo del grupo de reglas. El contenido de inicialización es el siguiente (no hay problema):

/* ADC init function */
void MX_ADC1_Init(void)
{
	LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
	LL_ADC_InitTypeDef ADC_InitStruct = {0};
	LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};

	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
	/* Peripheral clock enable */
	LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);

	LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
	/**ADC GPIO Configuration  
	PB12   ------> ADC_IN18 
	*/
	GPIO_InitStruct.Pin = LL_GPIO_PIN_12;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	/* ADC DMA Init */

	/* ADC Init */
	LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
    LL_DMA_SetPeriphAddress        (DMA1, LL_DMA_CHANNEL_1,(uint32_t)(&ADC1->DR));		
    LL_DMA_SetMemoryAddress        (DMA1, LL_DMA_CHANNEL_1,(uint32_t)(&stADCData.DMA[0]));	
	LL_DMA_SetChannelPriorityLevel (DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);
	LL_DMA_SetMode                 (DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);
	LL_DMA_SetPeriphIncMode        (DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
	LL_DMA_SetMemoryIncMode        (DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
	LL_DMA_SetPeriphSize           (DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD);
	LL_DMA_SetMemorySize           (DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
	LL_DMA_DisableChannel          (DMA1, LL_DMA_CHANNEL_1);
	//这里的长度为 MemorySize类型的长度,比如MemorySize=Byte则为字节长度,MemorySize=HALFWORD则为半字长度
	LL_DMA_SetDataLength           (DMA1, LL_DMA_CHANNEL_1, ADC_CH_MAX);
	LL_DMA_EnableChannel           (DMA1, LL_DMA_CHANNEL_1);
	
	/* ADC interrupt Init */
	NVIC_SetPriority(ADC1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
	NVIC_EnableIRQ(ADC1_IRQn);

	/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
	*/
	ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV1;
	LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
	ADC_InitStruct.Resolution         = LL_ADC_RESOLUTION_12B;
	ADC_InitStruct.DataAlignment      = LL_ADC_DATA_ALIGN_RIGHT;
	ADC_InitStruct.LowPowerMode       = LL_ADC_LP_AUTOWAIT|LL_ADC_LP_AUTOPOWEROFF_IDLE_PHASE;
	ADC_InitStruct.SequencersScanMode = LL_ADC_SEQ_SCAN_ENABLE;
	LL_ADC_Init(ADC1, &ADC_InitStruct);
	ADC_REG_InitStruct.TriggerSource    = LL_ADC_REG_TRIG_SOFTWARE;
	ADC_REG_InitStruct.SequencerLength  = LL_ADC_REG_SEQ_SCAN_DISABLE;
	ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
	ADC_REG_InitStruct.ContinuousMode   = LL_ADC_REG_CONV_CONTINUOUS; //LL_ADC_REG_CONV_SINGLE  LL_ADC_REG_CONV_CONTINUOUS
	ADC_REG_InitStruct.DMATransfer      = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;//LL_ADC_REG_DMA_TRANSFER_UNLIMITED LL_ADC_REG_DMA_TRANSFER_NONE
	LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
	LL_ADC_REG_SetFlagEndOfConversion(ADC1, LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV);
	LL_ADC_SetChannelsBank(ADC1, LL_ADC_CHANNELS_BANK_A);
	/** Configure Regular Channel 
	*/
	LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_18);
	LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_18, LL_ADC_SAMPLINGTIME_384CYCLES);

	LL_ADC_Enable(ADC1);

	//    LL_ADC_EnableIT_EOS(ADC1);//使能转换结束后产生中断

	LL_ADC_REG_StartConversionSWStart(ADC1);
}

Es lógico pensar que después de completar todas estas configuraciones, el ADC debería poder recopilar. Pero no funciona, ¿mi primera reacción es Nani? ? ? ¿Qué? ? ? ¿Se puede configurar esto en el proyecto F1 ahora mismo? Con una mirada aturdida. Luego comencé a verificar el hardware y descubrí que el pin tiene voltaje; todavía no funcionaba, y luego comencé a verificar la configuración. Varias comparaciones hicieron que el registro y F103 fueran correctos, y descubrí que el registro ADC de L151 es diferente del registro ADC de F103. , pero aún así no resolvió el problema; cuando comenzaba a dudar de mi vida, de repente me acordé del reloj ( porque hace dos días me enfrenté a la configuración del reloj GPIO L151, encendí la lámpara por un día y finalmente descubrí que había un problema con la configuración del reloj ), Luego comencé a comparar los árboles de reloj de F103 y L151. Como era de esperar, el problema apareció en el reloj. Primero, adjunte la tabla de comparación de reloj.

causas del problema:

Fuente de reloj ADC en F103: HSE ---> PLLCLK ---> HCLK ---> APB2 ---> Reloj ADC

Fuente de reloj ADC en L151: HSI ---> Reloj ADC

 

La fuente del reloj GPIO en F103: HSE ---> PLLCLK ---> HCLK ---> PCLK2 ---> Reloj periférico APB2

Fuente del reloj GPIO en L151: HSE ---> PLLCLK ---> HCLK ---> PCLK1 ---> Reloj periférico APB1

 

Por lo tanto, en STM32L151, el reloj HSI inicial debe estar habilitado; de lo contrario, no se puede usar el ADC. ! !

 

 

 

Supongo que te gusta

Origin blog.csdn.net/m0_37845735/article/details/105890138
Recomendado
Clasificación