STM32L151 ADC clock configuration crawling record

table of Contents

I. Introduction

Second, the digging process

Three, pit filling record


I. Introduction

First of all, what I mean by "crawling" is not that there is a problem with the clock of STM32L151. The clock of STM32L151 is definitely okay, but there are some differences with the clock configuration of STM32F1 or F4 . I did not pay attention to these differences. I thought that the clocks of L1 and F1 should be the same, so I got this pit-climbing note. It’s quite exciting to dig the pit and fill it by myself! Still too young!

Second, the digging process

We used the L151 chip in a project. I used the CubeMAX configuration to generate the project. Among them, the L151 ADC is used to collect multi-channel analog quantities, using the DMA method. Due to low power consumption (this chip is used for low power consumption), there is an internal high-speed clock (HSI) configuration in the clock initialization . Since the previous F1 series of single-chip computers use more, HSI in the F1 project I haven't used it before. I thought the clocks should be the same, so I manually initialized the HSI to shield it. Paste the HSI configuration that was blocked by me, SystemClock_Config is automatically generated by 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);
    ....
}

Three, pit filling record

CubeMAX is used to configure ADC_IN18 to collect the analog quantity of this channel cyclically. The key configuration is:

1. DMA: peripheral address and memory address, mode is cyclic mode (necessary for ADC multi-channel), data length.

2. ADC: Data alignment is 12bit right-aligned, low power consumption mode is turned on, multi-channel scanning is started, channel conversion is turned into continuous mode, disabling discontinuous mode, DMA transmission is started, channel sequence and sampling time of the rule group are set. The initialization content is as follows (no problem):

/* 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);
}

It stands to reason that after all these configurations are completed, the ADC should be able to collect. But it doesn’t work, my first reaction is Nani? ? ? what? ? ? Can this be configured in the F1 project just now? With a dazed look. Then I started to check the hardware and found that the pin has voltage; it still didn’t work, and then I started to check the configuration. Various comparisons made the register and F103 correct, and found that the ADC register of L151 is different from the ADC register of F103. Yes , but it still did not solve the problem; when I was beginning to doubt my life, I suddenly remembered the clock ( because I was pitted by the L151 GPIO clock configuration two days ago, I lit the lamp for a day, and finally found that there was a problem with the clock configuration ), Then I started to compare the clock trees of F103 and L151. As expected, the problem appeared on the clock. First, attach the clock comparison chart.

problem causes:

ADC clock source in F103: HSE ---> PLLCLK ---> HCLK ---> APB2 ---> ADC clock

ADC clock source in L151: HSI ---> ADC clock

 

The source of GPIO clock in F103: HSE ---> PLLCLK ---> HCLK ---> PCLK2 ---> APB2 peripheral clock

GPIO clock source in L151: HSE ---> PLLCLK ---> HCLK ---> PCLK1 ---> APB1 peripheral clock

 

Therefore, in STM32L151, the initial HSI clock must be enabled, otherwise the ADC cannot be used! ! !

 

 

 

Guess you like

Origin blog.csdn.net/m0_37845735/article/details/105890138