[MCU framework] [BSP layer] [cx32l003][bsp_adc] ADC configuration and use

ADC is the English abbreviation of the supplier of analog-to-digital converter. It is an electronic component that can c...
  1. ADC is the English abbreviation of the supplier of analog-to-digital converter. It is an electronic component that can convert analog signals into digital signals. Usually, after sampling and holding the signal, quantization and coding are carried out. These two processes are realized at the same time of transformation.

Resolution - describes the resolution of the ad to the input signal and the accuracy of the numerical part. Generally, 16 bit or 24 bit AD chip is used in analog sampling, which means resolution
For example, the variation range of the input analog voltage is 0 ~ 3.3 V, and the minimum analog voltage that can be distinguished by the output 16 bit binary number is 3.3V / 216 = 0.05 mV;

  1. Conversion error - represents the deviation between the actual voltage and the theoretical voltage of AD, which is generally expressed in the least significant bit. The unit LSB usually appears in the form of relative error, such as relative error ≤± LSB/2, indicating that the error between the actual output digital quantity and the theoretical quantity is less than half of the lowest bit.

Conversion accuracy - it is generally expressed by conversion error and resolution. Specifically, the rounding method is adopted in the process of AD maximum quantization and the accuracy of simulation processing.

Conversion time - that is, the time from the beginning of signal input to the output of a stable signal. Different AD standards have different replacement speeds, so they are selected according to the actual requirements.

Working voltage and reference voltage (internal or external reference): the working voltage is the rated voltage of ad chip. The key is the reference voltage, also known as reference voltage. It can be accessed internally or externally from the chip, which determines the resolution of AD. all reference voltages must be stable.

/******************************************************************************** * @file bsp_adc.c * @author jianqiang.xue * @version V1.0.0 * @date 2021-04-10 * @brief NULL ********************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "RTE_Components.h" #include CMSIS_device_header #include "bsp_gpio.h" #include "bsp_exti.h" #include "bsp_adc.h" /* Private Includes ----------------------------------------------------------*/ #include "business_gpio.h" #include "business_function.h" /* Private Define ------------------------------------------------------------*/ #define ADC0_CH_NUM 8 #define CH_NUM (BS_ADC0_CH0 + BS_ADC0_CH1 + BS_ADC0_CH2 + BS_ADC0_CH3 + BS_ADC0_CH4 + BS_ADC0_CH5 + BS_ADC0_CH6 + BS_ADC0_CH7) /* Private Variables ---------------------------------------------------------*/ // ADC initialization status (0--deinit 1--init) static bool g_adc_init = false; // ADC acquisition data storage buff uint16_t bsp_adc0_val[ADC0_CH_NUM] = ; // Define ADC collection completion callback function typedef void(*bsp_adc0_callback)(void); static bsp_adc0_callback irq_callback; /****************Structure definition****************/ #if BS_ADC0_EN ADC_HandleTypeDef adc0_handle_t = { .Instance = BS_ADC0_BASE, .Init.SamplingTime = ADC_SAMPLE_8CYCLE, // sampling period .Init.ClkSel = ADC_CLOCK_PCLK_DIV32, // ADC clock division .Init.SingleContinueMode = ADC_MODE_CONTINUE, // Continuous conversion mode .Init.NbrOfConversion = BS_ADC0_SAMPLING_TIMES, // Continuous conversion times .Init.AutoAccumulation = ADC_AUTOACC_DISABLE, // Automatic accumulation of ADC conversion results is prohibited .Init.CircleMode = ADC_MULTICHANNEL_NONCIRCLE, // Disable ADC cyclic conversion mode .Init.ExternalTrigConv1 = ADC_SOFTWARE_START, // Disable auto trigger ADC conversion }; #endif /* External Variables --------------------------------------------------------*/ /* Public Function Prototypes ------------------------------------------------*/ #if BS_ADC0_EN /** * @brief ADC0 Initialize and enable the channel * @note NULL * @retval None */ void bsp_adc0_init(void) { #if CH_NUM if (g_adc_init) { return; } __HAL_RCC_ADC_CLK_ENABLE(); // Enable channel adc0_handle_t.Init.ContinueChannelSel = #if BS_ADC0_CH0 ADC_CONTINUE_CHANNEL_0| #endif #if BS_ADC0_CH1 ADC_CONTINUE_CHANNEL_1| #endif #if BS_ADC0_CH2 ADC_CONTINUE_CHANNEL_2| #endif #if BS_ADC0_CH3 ADC_CONTINUE_CHANNEL_3| #endif #if BS_ADC0_CH4 ADC_CONTINUE_CHANNEL_4| #endif #if BS_ADC0_CH5 ADC_CONTINUE_CHANNEL_5| #endif #if BS_ADC0_CH6 ADC_CONTINUE_CHANNEL_6| #endif #if BS_ADC0_CH7 ADC_CONTINUE_CHANNEL_7| #endif 0; HAL_ADC_Init(&adc0_handle_t); // ADC comparison settings ADC_ThresholdConfTypeDef adc0_threshold_conf_t; adc0_threshold_conf_t.ITMode = DISABLE; adc0_threshold_conf_t.CompareMode = ADC_COMP_THRESHOLD_NONE; // Disable ADC compare interrupt control HAL_ADC_ThresholdConfig(&adc0_handle_t, &adc0_threshold_conf_t); HAL_NVIC_SetPriority(BS_ADC0_IRQn, 2); HAL_NVIC_EnableIRQ(BS_ADC0_IRQn); // Enable ADC interrupt g_adc_init = true; #endif } /** * @brief ADC0 The function is turned off and removed * @note NULL * @retval None */ void bsp_adc0_deinit(void) { #if CH_NUM if (!g_adc_init) { return; } HAL_NVIC_DisableIRQ(BS_ADC0_IRQn); // Turn off ADC interrupt HAL_ADC_DeInit(&adc0_handle_t); g_adc_init = false; #endif } /** * @brief ADC0 Start sampling function * @note NULL * @retval None */ void bsp_adc0_start(void) { #if CH_NUM if (!g_adc_init) { return; } HAL_ADC_Start_IT(&adc0_handle_t); // Start ADC interrupt conversion #endif } #else void bsp_adc0_init(void) { } void bsp_adc0_deinit(void) { } void bsp_adc0_start(void) { } #endif /** * @brief Initializes the ADC MSP. * @param hadc: ADC handle * @retval None */ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) { #if BS_ADC0_CH0 BS_ADC0_CH0_GPIO_CLK_ENABLE(); bsp_gpio_init_adc(BS_ADC0_CH0_GPIO_PORT, BS_ADC0_CH0_PIN); #endif #if BS_ADC0_CH1 BS_ADC0_CH1_GPIO_CLK_ENABLE(); bsp_gpio_init_adc(BS_ADC0_CH1_GPIO_PORT, BS_ADC0_CH1_PIN); #endif #if BS_ADC0_CH2 BS_ADC0_CH2_GPIO_CLK_ENABLE(); bsp_gpio_init_adc(BS_ADC0_CH2_GPIO_PORT, BS_ADC0_CH2_PIN); #endif #if BS_ADC0_CH3 BS_ADC0_CH3_GPIO_CLK_ENABLE(); bsp_gpio_init_adc(BS_ADC0_CH3_GPIO_PORT, BS_ADC0_CH3_PIN); #endif #if BS_ADC0_CH4 BS_ADC0_CH4_GPIO_CLK_ENABLE(); bsp_gpio_init_adc(BS_ADC0_CH4_GPIO_PORT, BS_ADC0_CH4_PIN); #endif #if BS_ADC0_CH5 BS_ADC0_CH5_GPIO_CLK_ENABLE(); bsp_gpio_init_adc(BS_ADC0_CH5_GPIO_PORT, BS_ADC0_CH5_PIN); #endif #if BS_ADC0_CH6 BS_ADC0_CH6_GPIO_CLK_ENABLE(); bsp_gpio_init_adc(BS_ADC0_CH6_GPIO_PORT, BS_ADC0_CH6_PIN); #endif // #if BS_ADC0_CH7 // BS_ADC0_CH7_GPIO_CLK_ENABLE() // bsp_gpio_init_adc(BS_ADC0_CH7_GPIO_PORT, BS_ADC0_CH7_PIN); // #endif } #if BS_ADC0_CH0 void HAL_ADC_MultiChannel0_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[0] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_0); } } #endif #if BS_ADC0_CH1 void HAL_ADC_MultiChannel1_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[1] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_1); } } #endif #if BS_ADC0_CH2 void HAL_ADC_MultiChannel2_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[2] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_2); } } #endif #if BS_ADC0_CH3 void HAL_ADC_MultiChannel3_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[3] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_3); } } #endif #if BS_ADC0_CH4 void HAL_ADC_MultiChannel4_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[4] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_4); } } #endif #if BS_ADC0_CH5 void HAL_ADC_MultiChannel5_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[5] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_5); } } #endif #if BS_ADC0_CH6 void HAL_ADC_MultiChannel6_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[6] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_6); } } #endif #if BS_ADC0_CH7 void HAL_ADC_MultiChannel7_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { bsp_adc0_val[7] = HAL_ADC_GetValue(hadc, ADC_CONTINUE_CHANNEL_7); } } #endif /** * @brief [Redefine] ADC sampling completion callback function * @note NULL * @param hadc: ADC handle * @retval None */ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == BS_ADC0_BASE) { if (irq_callback) { irq_callback(); } } } /** * @brief Get ADC0 sampling value * @note NULL * @param ch_num: Channel value * @retval ADC value corresponding to the channel */ uint16_t bsp_adc0_get_ch_val(uint8_t ch_num) { if (ch_num >= ADC0_CH_NUM) { return 0xFFFF; } return bsp_adc0_val[ch_num]; } /** * @brief Register ADC0 sampling completion callback function * @note NULL * @param *event: Bind callback event * @retval 0--Failure 1 -- success */ bool bsp_adc0_irq_callback(void *event) { if (irq_callback != NULL) { return false; } else { irq_callback = (bsp_adc0_callback)event; } return true; }
/******************************************************************************** * @file bsp_adc.h * @author jianqiang.xue * @version V1.0.0 * @date 2021-04-10 * @brief ADC operation ********************************************************************************/ #ifndef __BSP_ADC_H #define __BSP_ADC_H /* Includes ------------------------------------------------------------------*/ #include <stdint.h> #include <stdbool.h> /* Public Function Prototypes -----------------------------------------------*/ void bsp_adc0_init(void); void bsp_adc0_deinit(void); void bsp_adc0_start(void); uint16_t bsp_adc0_get_ch_val(uint8_t ch_num); bool bsp_adc0_irq_callback(void *event); #endif

15 October 2021, 16:32 | Views: 9009

Add new comment

For adding a comment, please log in
or create account

0 comments