首页 > 其他分享 >[单片机框架][bsp层][cx32l003][bsp_adc] ADC配置和使用

[单片机框架][bsp层][cx32l003][bsp_adc] ADC配置和使用

时间:2022-10-31 18:33:25浏览次数:48  
标签:cx32l003 endif bsp 单片机 ADC ADC0 BS adc0


  1. ADC是模数转换器转换器 的供应商的英文简称,是一种能将模拟信号转变为数字信号的电子元件。通常是将信号采样并保持以后,再进行量化和编码,这两个过程是在转化的同时实现的。

分辨率-说明AD对输入信号的分辨能力,及数值部分的精度。一般模拟采样中使用16位还是24位的AD芯片说的就是分辨率.
例如:输入模拟电压的变化范围为0~3.3 V,输出16位二进制数可以分辨的最小模拟电压为3.3V / 216=0.05 mV;

  1. 转化误差-表示AD实际电压与理论电压的偏差,一般用最低有效位来表示,单位LSB,通常以相对误差的形式出现,比如相对误差≤±LSB/2,表明实际输出的数字量和理论量误差小于最低位的一半。

转换精度-这里一般用转化误差和分辨率来表述,具体就是AD最大量化过程中采用了四舍五入的方法及模拟处理部分的精度问题。

转化时间-即从信号输入开始到输出稳定的信号所经过的时间。不同的AD准换的速度不同,根据实际要求来选型。

工作电压和基准电压(内部或者外部基准):工作电压是AD芯片工作的额定电压,关键的是基准电压,又叫参考电压,可以来之芯片内部又或者外部接入,其决定了AD的分辨率,所有基准电压一定要稳。

模块简介

本芯片内部集成了一个 12 位高精度、高转换速率的逐次逼近(SAR)型模数转换器(ADC)模块。具

有以下特性:

⚫ 12 位转换精度

⚫ 1Msps 转换速度

⚫ 8 路转换通道:7 个引脚通道、1 个 VCAP 校准通道

⚫ 参考电压(Refence Voltage)为电源电压

⚫ ADC 的电压输入范围:0-VREF

⚫ 3 种转换模式:单次转换、连续转换、累加转换

⚫ ADC 的转换速率软件可配

⚫ 支持片内及外设中断自动触发 ADC 转换启动,有效降低芯片功耗、提高转换实时性

[单片机框架][bsp层][cx32l003][bsp_adc] ADC配置和使用_stm32

/********************************************************************************
* @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初始化状态(0--deinit 1--init)
static bool g_adc_init = false;
// ADC采集数据存储buff
uint16_t bsp_adc0_val[ADC0_CH_NUM] = {0};

// 定义ADC采集完毕回调函数
typedef void(*bsp_adc0_callback)(void);
static bsp_adc0_callback irq_callback;

/****************结构体定义****************/
#if BS_ADC0_EN
ADC_HandleTypeDef adc0_handle_t =
{
.Instance = BS_ADC0_BASE,
.Init.SamplingTime = ADC_SAMPLE_8CYCLE, // 采样周期
.Init.ClkSel = ADC_CLOCK_PCLK_DIV32, // ADC时钟分频
.Init.SingleContinueMode = ADC_MODE_CONTINUE, // 连续转换模式
.Init.NbrOfConversion = BS_ADC0_SAMPLING_TIMES, // 连续转换次数
.Init.AutoAccumulation = ADC_AUTOACC_DISABLE, // 禁止ADC转换结果自动累加
.Init.CircleMode = ADC_MULTICHANNEL_NONCIRCLE, // 禁止ADC循环转换模式
.Init.ExternalTrigConv1 = ADC_SOFTWARE_START, // 禁用自动触发ADC转换
};
#endif
/* External Variables --------------------------------------------------------*/
/* Public Function Prototypes ------------------------------------------------*/
#if BS_ADC0_EN
/**
* @brief ADC0初始化,并使能通道
* @note NULL
* @retval None
*/
void bsp_adc0_init(void)
{
#if CH_NUM
if (g_adc_init)
{
return;
}
__HAL_RCC_ADC_CLK_ENABLE();

// 使能通道
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; // 禁止 ADC比较中断控制
HAL_ADC_ThresholdConfig(&adc0_handle_t, &adc0_threshold_conf_t);
HAL_NVIC_SetPriority(BS_ADC0_IRQn, 2);
HAL_NVIC_EnableIRQ(BS_ADC0_IRQn); // 使能ADC中断
g_adc_init = true;
#endif
}

/**
* @brief ADC0功能关闭,并移除
* @note NULL
* @retval None
*/
void bsp_adc0_deinit(void)
{
#if CH_NUM
if (!g_adc_init)
{
return;
}
HAL_NVIC_DisableIRQ(BS_ADC0_IRQn); // 关闭ADC中断
HAL_ADC_DeInit(&adc0_handle_t);
g_adc_init = false;
#endif
}

/**
* @brief ADC0 启动采样功能
* @note NULL
* @retval None
*/
void bsp_adc0_start(void)
{
#if CH_NUM
if (!g_adc_init)
{
return;
}
HAL_ADC_Start_IT(&adc0_handle_t); // 启动ADC中断转换
#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 [重定义] ADC采样完毕回调函数
* @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 得到ADC0采样值
* @note NULL
* @param ch_num: 通道值
* @retval 通道对应的ADC值
*/
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 注册ADC0采样完毕回调函数
* @note NULL
* @param *event: 绑定回调事件
* @retval 0--失败 1--成功
*/
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操作
********************************************************************************/

#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


标签:cx32l003,endif,bsp,单片机,ADC,ADC0,BS,adc0
From: https://blog.51cto.com/xuejianqiang/5810873

相关文章