STM32CubeMX series|ADC analog-to-digital conversion

ADC analog to digital conversion

1. Introduction to ADC

ADC (analog to digital converter) is the analog-to-digital converter, which can convert analog signals into digital signals. According to the conversion principle, it is mainly divided into three types: successive approximation, double integration, and voltage-frequency conversion. The STM32F1 ADC is a 12-bit successive approximation analog-to-digital converter. It has 18 channels and can measure 16 external and 2 internal signal sources. The A/D conversion of each channel can be executed in single, continuous, scanning or discontinuous mode. The ADC result can be left-justified or right-justified stored in 16-bit storage registers. The analog watchdog feature allows the application to detect whether the input voltage exceeds a user-defined high/low threshold. The ADC clock should not exceed 14M, otherwise the accuracy of the result will decrease. ADC structure block diagram and ADC pin description are as follows:

Insert picture description here
Insert picture description here

  • The voltage input pins and input channel pins are shown in the above table; in addition, there are two internal channels in the main ADC1: channel 16 is connected to the temperature sensor inside the chip, channel 17 is connected to the internal reference voltage V REFINT ; channel 16 of ADC2/ADC3 /17 are connected to the internal V SS
  • ADC conversion is divided into two channel groups: regular channel group (16 channels) and injection channel group (4 channels). Regular channels are equivalent to normal running programs, and injection channels are equivalent to interrupts.
  • After selecting the input channel and conversion sequence, you need to enable the ADC, you can directly turn on the ADC conversion or select an external event to trigger the conversion
  • The maximum working frequency of ADC is 14M, and the distribution factor is generally set to 6, that is, the input clock of ADC ADC_CLK = 12M
  • The ADC needs several ADC_CLK cycles to complete the sampling of the input voltage, the minimum sampling cycle is 1.5 (that is, if you want to achieve the fastest sampling, the sampling cycle should be set to 1.5 cycles, that is, 1.5 times 1/ADC_CLK)
  • ADC total conversion time T conv = sampling time + 12.5 cycles; according to the above settings, T conv = (1.5+12.5) cycles = 14 * (1/12M) = 1.17us, that is, the shortest conversion time is 1.17us
  • The data after ADC conversion is placed in different data registers (16 bits) according to different conversion groups; because the ADC has a 12-bit conversion accuracy, and the data register is 16 bits, there are left-aligned and right-aligned when storing data. Minute
  • The rule group contains 16 channels but there is only one register corresponding to the data. If you use multi-channel conversion, you should remove the data after the channel conversion is completed, or turn on the DMA mode to transfer the data to the memory, otherwise it will cause data cover
  • Enable the corresponding interrupt flag bit, ADC can generate corresponding interrupts in three ways: rule conversion and injection conversion end, analog watchdog event, DMA request

2. Hardware design

In this experiment, the external voltage value is sampled through ADC1 channel 1, and the sampled AD value and the converted voltage value are printed out through the USART1 serial port. At the same time, the D1 indicator flashes, indicating that the system is operating normally

  • D1 indicator
  • ADC1_INT1
  • USART1 serial port
  • Potentiometer

Insert picture description here

3. Software design

3.1 STM32CubeMX settings
  • RCC sets external HSE, clock is set to 72M, ADC prescaler factor is set to 6, ADC_CLK is 12MHz

Insert picture description here

  • PC0 is set to GPIO push-pull output mode, pull-up, high-speed, and the default output level is high
  • USART1 is selected as the asynchronous communication mode, the baud rate is set to 115200Bits/s, the transmission data length is 8Bit, no parity, 1 stop bit
  • Activate ADC1 channel 1, set right alignment, turn off scan, continuous and discontinuous modes, enable regular conversion, set software trigger, set sampling time 1.5 cycles

Insert picture description here

  • Enter the project name, select the project path (no Chinese), select MDK-ARM V5; check Generated periphera initialization as a pair of'.c/.h' files per IP; click GENERATE CODE to generate the project code
3.2 MDK-ARM programming
  • The ADC initialization function can be seen in the adc.c file
void MX_ADC1_Init(void){
    
    
  ADC_ChannelConfTypeDef sConfig = {
    
    0};
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK){
    
    
    Error_Handler();
  }
  /** Configure Regular Channel*/
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
    
    
    Error_Handler();
  }
}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle){
    
    
  GPIO_InitTypeDef GPIO_InitStruct = {
    
    0};
  if(adcHandle->Instance==ADC1){
    
    
    /* ADC1 clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  }
}
  • Add the following test program to the while loop of the main function, ADC1 has a 12-bit conversion accuracy, so the voltage resolution is: 3.3/(2 12 ) = 3.3/4096
while (1){
    
    
  HAL_ADC_Start(&hadc1);	//启动ADC转换
  HAL_ADC_PollForConversion(&hadc1,10);	//等待转换完成,10ms表示超时时间
  AD_Value = HAL_ADC_GetValue(&hadc1);	//读取ADC转换数据(12位数据)
  printf("ADC1_IN1 ADC value: %d\r\n",AD_Value);
  Vol_Value = AD_Value*(3.3/4096);	//AD值乘以分辨率即为电压值
  printf("ADC1_IN1 VOL value: %.2fV\r\n",Vol_Value);
  
  HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
  HAL_Delay(1000);
}

4. Download verification

After the compilation is correct, download it to the development board, you can see that the D1 indicator light keeps flashing when the system is running, when the potentiometer is adjusted, the obtained AD conversion value and voltage value will change, and print out through the serial port

Insert picture description here

Guess you like

Origin blog.csdn.net/Chuangke_Andy/article/details/108768563