2.8. ADC
2.8.1. Introduction
ADC (Analog-to-digital Converter) can convert continuous analog signals into discrete digital signals.
The ADC module in BL MCU series has the following characteristics:
Support selecting 12/14/16 bits conversion result output
ADC maximum working clock is 2MHZ
Support 2.0V, 3.2V optional internal reference voltage
DMA support
Support four modes: single channel single conversion, continuous single channel conversion, single multi-channel conversion and continuous multi-channel conversion mode
Support both single-ended and differential input modes
12 external analog channels
2 DAC internal channels
1 VBAT /2 channel
2.8.2. ADC Device Structure Definition
typedef struct adc_device {
struct device parent;
adc_clk_div_t clk_div;
adc_vref_t vref;
bool continuous_conv_mode;
bool differential_mode;
adc_data_width_t data_width;
adc_fifo_threshold_t fifo_threshold;
adc_pga_gain_t gain;
} adc_device_t;
parent inherits the properties of the parent class
clk_div Partial frequency clock in ADC module
vref 2.0/3.2V reference voltage optional
continuous_conv_mode Whether to select continuous mode. If it is in continuous mode, once adc_start operation, ADC will continue to work until adc_stop. If it is not in continuous mode, adc will only convert the result once every adc_start.
differential_mode Whether it is in differential mode, if it is in differential mode, negative voltage can be measured.
data_width Measurement width selection, the actual accuracy of ADC is 12 bits, but the accuracy of 14bits / 16bits can be achieved by averaging multiple times through OSR. Note that when a higher data width is selected, the frequency will decrease due to averaging. For details, please refer to the enumeration information.
fifo_threshold This parameter affects the DMA handling threshold and ADC FIFO interrupt threshold
gain ADC gain selection for input signal
Others to be added
2.8.3. ADC Device Parameter Configuration Table
Each ADC has a parameter configuration macro, the macro definition is located in the peripheral_config.h
file under the bsp/board/xxx
directory, and the variable definition is located in hal_adc.c
, so there is no need for the user to define it by himself . When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_ADC0
to take effect, and at the same time, the ADC
device can be registered and used.
/*Parameter configuration macro*/
#if defined(BSP_USING_ADC0)
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
.clk_div = ADC_CLOCK_DIV_32, \
.vref = ADC_VREF_3P2V, \
.continuous_conv_mode = DISABLE, \
.differential_mode = DISABLE, \
.data_width = ADC_DATA_WIDTH_16B_WITH_256_AVERAGE, \
.fifo_threshold = ADC_FIFO_THRESHOLD_1BYTE, \
.gain = ADC_GAIN_1 \
}
#endif
#endif
/*Variable definitions*/
static adc_device_t adcx_device[ADC_MAX_INDEX] = {
#ifdef BSP_USING_ADC0
ADC0_CONFIG,
#endif
};
备注
The above configuration can be modified through ADC_DEV(dev)->xxx
and can only be used before device_open
.
2.8.4. ADC Device Interface
ADC device interfaces all follow the interfaces provided by the standard device driver management layer.
2.8.4.1. adc_register
adc_register
is used to register an ADC device standard driver interface.Before registering, you need to open the macro definition of the corresponding ADC device. For example, define the macro BSP_USING_ADC0
to use the ADC0
device. After the registration is completed, other interfaces can be used. If no macro is defined, the ADC0
device cannot be used.
int adc_register(enum adc_index_type index, const char *name);
index device index to be registered
name device name to be registered
index
is used to select ADC device configuration, one index corresponds to one ADC device configuration, for example, ADC0_INDEX
corresponds to ADC0_CONFIG
configuration. index
has the following optional types:
enum adc_index_type
{
#ifdef BSP_USING_ADC0
ADC0_INDEX,
#endif
ADC_MAX_INDEX
};
2.8.4.2. device_open
device_open
is used to open an ADC device,this funtion calls adc_open
actually.
int device_open(struct device *dev, uint16_t oflag);
dev device handle
oflag open mode
return Error code, 0: open successfully, others: error
oflag
provides the following types
#define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in rotation sending mode */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in rotation receiving mode */
#define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */
#define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */
#define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */
#define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */
2.8.4.3. device_close
device_close
is used to close an ADC device,this funtion calls adc_close
actually.
int device_close(struct device *dev);
dev device handle
return Error code, 0: open successfully, others: error
2.8.4.4. device_control
device_control
is used to control and modify the parameters of the adc device according to commands.This funtion calls adc_control
actually.
int device_control(struct device *dev, int cmd, void *args);
dev Device handle
cmd Device control commands
args Control parameter
return Different control commands return different meanings.
In addition to standard control commands, serial devices also have their own special control commands.
#define DEVICE_CTRL_ADC_CHANNEL_START 0x10
#define DEVICE_CTRL_ADC_CHANNEL_STOP 0x11
#define DEVICE_CTRL_ADC_CHANNEL_CONFIG 0x12
#define DEVICE_CTRL_ADC_VBAT_ON 0x13
#define DEVICE_CTRL_ADC_VBAT_OFF 0x14
#define DEVICE_CTRL_ADC_TSEN_ON 0x15
#define DEVICE_CTRL_ADC_TSEN_OFF 0x16
args
input is different depending on cmd
, the list is as follows:
cmd |
args |
description |
---|---|---|
DEVICE_CTRL_SET_INT |
adc_it_type |
Enable ADC device interrupt |
DEVICE_CTRL_CLR_INT |
adc_it_type |
Disable ADC device interrupt |
DEVICE_CTRL_CONFIG |
ADC_param_cfg_t |
Modify ADC configuration |
DEVICE_CTRL_ADC_CHANNEL_CONFIG |
adc_channel_cfg_t |
Modify ADC channel configuration |
DEVICE_CTRL_ATTACH_RX_DMA |
struct device* |
Link receiving DMA device |
DEVICE_CTRL_ADC_CHANNEL_START |
NULL |
Start/continue ADC conversion |
DEVICE_CTRL_ADC_CHANNEL_STOP |
NULL |
Stop ADC conversion |
DEVICE_CTRL_ADC_VBAT_ON |
NULL |
Turn on the internal VDD measurement circuit |
DEVICE_CTRL_ADC_VBAT_OFF |
NULL |
Turn off the internal VDD measurement circuit |
DEVICE_CTRL_ADC_TSEN_ON |
NULL |
Turn on the internal temperature measurement circuit (requires hardware support) |
DEVICE_CTRL_ADC_TSEN_OFF |
NULL |
Turn off the internal temperature measurement circuit (requires hardware support) |
2.8.4.5. device_read
device_read
is used to receive the data of ADC device, the receiving mode can be polling, interrupt, dma.
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
dev Dvice handle
pos No effect
buffer Buffer to read
size Length to read
return Error code, 0: open successfully, others: error
2.8.4.6. device_set_callback
device_set_callback
is used to register an ADC threshold interrupt callback function.
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
dev Device handle
callback The interrupt callback function to be registered
dev Device handle
args Receive and send buffer, the data type is uint8_t*
size Transmission length
event Type of interrupt event
event
type is as follows:
enum ADC_event_type
{
ADC_EVENT_FIFO_READY,
ADC_EVENT_OVERRUN,
ADC_EVENT_UNDERRUN,
};