libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::STM32ADC Class Reference

STM32ADC 类,用于处理 STM32 系统的 ADC 通道。 Provides handling for STM32 ADC channels. More...

#include <stm32_adc.hpp>

Collaboration diagram for LibXR::STM32ADC:
[legend]

Data Structures

class  Channel
 STM32ADC 类,用于处理 STM32 系统的 ADC 通道。 Provides handling for STM32 ADC. More...
 
struct  GetADCResolution
 获取 ADC 分辨率 Get ADC resolution More...
 
struct  GetADCResolution< T, std::void_t< decltype(std::declval< T >().Init.Resolution)> >
 获取 ADC 分辨率 Get ADC resolution More...
 
struct  HasContinuousConvMode
 
struct  HasContinuousConvMode< T, std::void_t< decltype(std::declval< T >() ->Init.ContinuousConvMode)> >
 
struct  HasDMACircularMode
 
struct  HasDMACircularMode< T, std::void_t< decltype(std::declval< T >() ->DMA_Handle->Init.Mode)> >
 
struct  HasDMAContinuousRequests
 
struct  HasDMAContinuousRequests< T, std::void_t< decltype(std::declval< T >() ->Init.DMAContinuousRequests)> >
 
struct  HasNbrOfConversion
 
struct  HasNbrOfConversion< T, std::void_t< decltype(std::declval< T >() ->Init.NbrOfConversion)> >
 

Public Member Functions

 STM32ADC (ADC_HandleTypeDef *hadc, RawData dma_buff, std::initializer_list< uint32_t > channels, float vref)
 STM32ADC 类,用于处理 STM32 系统的 ADC 通道。 Provides handling for STM32.
 
 ~STM32ADC ()
 析构函数 Destructor
 
ChannelGetChannel (uint8_t index)
 获取 ADC 通道对象 Get ADC channel object
 
float ReadChannel (uint8_t channel)
 读取 ADC
 

Private Member Functions

float ConvertToVoltage (float adc_value)
 

Static Private Member Functions

template<typename T >
static std::enable_if< HasContinuousConvMode< T >::value >::type AssertContinuousConvModeEnabled (T hadc)
 
template<typename T >
static std::enable_if<!HasContinuousConvMode< T >::value >::type AssertContinuousConvModeEnabled (T)
 
template<typename T >
static std::enable_if< HasContinuousConvMode< T >::value >::type AssertContinuousConvModeDisabled (T hadc)
 
template<typename T >
static std::enable_if<!HasContinuousConvMode< T >::value >::type AssertContinuousConvModeDisabled (T)
 
template<typename T >
static std::enable_if< HasDMAContinuousRequests< T >::value >::type AssertDMAContReqEnabled (T hadc)
 
template<typename T >
static std::enable_if<!HasDMAContinuousRequests< T >::value >::type AssertDMAContReqEnabled (T)
 
template<typename T >
static std::enable_if< HasNbrOfConversion< T >::value >::type AssertNbrOfConvEq (T hadc, uint32_t n)
 
template<typename T >
static std::enable_if<!HasNbrOfConversion< T >::value >::type AssertNbrOfConvEq (T, uint32_t)
 
template<typename T >
static std::enable_if< HasDMACircularMode< T >::value >::type AssertDMACircular (T hadc)
 
template<typename T >
static std::enable_if<!HasDMACircularMode< T >::value >::type AssertDMACircular (T)
 

Private Attributes

std::atomic< uint32_t > locked_ = 0U
 
ADC_HandleTypeDef * hadc_
 
const uint8_t NUM_CHANNELS
 
uint8_t filter_size_
 
bool use_dma_
 
RawData dma_buffer_
 
float resolution_
 
Channel ** channels_
 
float vref_
 

Detailed Description

STM32ADC 类,用于处理 STM32 系统的 ADC 通道。 Provides handling for STM32 ADC channels.

Definition at line 24 of file stm32_adc.hpp.

Constructor & Destructor Documentation

◆ STM32ADC()

STM32ADC::STM32ADC ( ADC_HandleTypeDef * hadc,
RawData dma_buff,
std::initializer_list< uint32_t > channels,
float vref )

STM32ADC 类,用于处理 STM32 系统的 ADC 通道。 Provides handling for STM32.

Parameters
hadcADC外设 ADC device
dma_buffDMA缓冲区 DMA buffer
channelsADC通道列表 List of ADC channels
vref参考电压 Reference voltage

Definition at line 29 of file stm32_adc.cpp.

31 : hadc_(hadc),
32 NUM_CHANNELS(channels.size()),
33 filter_size_(dma_buff.size_ / NUM_CHANNELS / 2),
34 use_dma_(hadc_->DMA_Handle != nullptr),
35 dma_buffer_(dma_buff),
36 resolution_(GetADCResolution<ADC_HandleTypeDef>{}.Get(hadc)),
37 channels_(new Channel*[NUM_CHANNELS]),
38 vref_(vref)
39{
40 auto it = channels.begin();
41 for (uint8_t i = 0; i < NUM_CHANNELS; ++i)
42 {
43 channels_[i] = new Channel(this, i, *it++);
44 }
45
46#if defined(ADC_CALIB_OFFSET_AND_LINEARITY) && defined(ADC_SINGLE_ENDED)
47 HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET_AND_LINEARITY, ADC_SINGLE_ENDED);
48#elif defined(ADC_CALIB_OFFSET_LINEARITY) && defined(ADC_SINGLE_ENDED)
49 HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED);
50#elif defined(ADC_CALIB_OFFSET) && defined(ADC_SINGLE_ENDED)
51 HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
52#elif defined(ADC_SINGLE_ENDED)
53 HAL_ADCEx_Calibration_Start(hadc, ADC_SINGLE_ENDED);
54#else
55 HAL_ADCEx_Calibration_Start(hadc);
56#endif
57
58 if (use_dma_)
59 {
60 /* DMA must be in circular mode */
61 AssertContinuousConvModeEnabled<H>(hadc_);
62 AssertDMAContReqEnabled<H>(hadc_);
63 AssertDMACircular<H>(hadc_);
64 AssertNbrOfConvEq<H>(hadc_, NUM_CHANNELS);
65 HAL_ADC_Start_DMA(hadc_, reinterpret_cast<uint32_t*>(dma_buffer_.addr_),
66 NUM_CHANNELS * filter_size_);
67 }
68 else
69 {
70 AssertNbrOfConvEq<H>(hadc_, 1);
71 AssertContinuousConvModeDisabled<H>(hadc_);
72 HAL_ADC_Start(hadc_);
73 }
74}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.

◆ ~STM32ADC()

STM32ADC::~STM32ADC ( )

析构函数 Destructor

Definition at line 76 of file stm32_adc.cpp.

77{
78 use_dma_ ? HAL_ADC_Stop_DMA(hadc_) : HAL_ADC_Stop(hadc_);
79 for (uint8_t i = 0; i < NUM_CHANNELS; ++i)
80 {
81 delete channels_[i];
82 }
83 delete[] channels_;
84}

Member Function Documentation

◆ AssertContinuousConvModeDisabled() [1/2]

template<typename T >
static std::enable_if< HasContinuousConvMode< T >::value >::type LibXR::STM32ADC::AssertContinuousConvModeDisabled ( T hadc)
inlinestaticprivate

Definition at line 136 of file stm32_adc.hpp.

137 {
138 ASSERT(hadc->Init.ContinuousConvMode == DISABLE);
139 }

◆ AssertContinuousConvModeDisabled() [2/2]

template<typename T >
static std::enable_if<!HasContinuousConvMode< T >::value >::type LibXR::STM32ADC::AssertContinuousConvModeDisabled ( T )
inlinestaticprivate

Definition at line 142 of file stm32_adc.hpp.

143 {
144 }

◆ AssertContinuousConvModeEnabled() [1/2]

template<typename T >
static std::enable_if< HasContinuousConvMode< T >::value >::type LibXR::STM32ADC::AssertContinuousConvModeEnabled ( T hadc)
inlinestaticprivate

Definition at line 124 of file stm32_adc.hpp.

125 {
126 ASSERT(hadc->Init.ContinuousConvMode == ENABLE);
127 }

◆ AssertContinuousConvModeEnabled() [2/2]

template<typename T >
static std::enable_if<!HasContinuousConvMode< T >::value >::type LibXR::STM32ADC::AssertContinuousConvModeEnabled ( T )
inlinestaticprivate

Definition at line 130 of file stm32_adc.hpp.

131 {
132 }

◆ AssertDMACircular() [1/2]

template<typename T >
static std::enable_if< HasDMACircularMode< T >::value >::type LibXR::STM32ADC::AssertDMACircular ( T hadc)
inlinestaticprivate

Definition at line 171 of file stm32_adc.hpp.

173 {
174 ASSERT(hadc->DMA_Handle != nullptr);
175 ASSERT(hadc->DMA_Handle->Init.Mode == DMA_CIRCULAR);
176 }

◆ AssertDMACircular() [2/2]

template<typename T >
static std::enable_if<!HasDMACircularMode< T >::value >::type LibXR::STM32ADC::AssertDMACircular ( T )
inlinestaticprivate

Definition at line 178 of file stm32_adc.hpp.

179 {
180 }

◆ AssertDMAContReqEnabled() [1/2]

template<typename T >
static std::enable_if< HasDMAContinuousRequests< T >::value >::type LibXR::STM32ADC::AssertDMAContReqEnabled ( T hadc)
inlinestaticprivate

Definition at line 148 of file stm32_adc.hpp.

149 {
150 ASSERT(hadc->Init.DMAContinuousRequests == ENABLE);
151 }

◆ AssertDMAContReqEnabled() [2/2]

template<typename T >
static std::enable_if<!HasDMAContinuousRequests< T >::value >::type LibXR::STM32ADC::AssertDMAContReqEnabled ( T )
inlinestaticprivate

Definition at line 154 of file stm32_adc.hpp.

155 {
156 }

◆ AssertNbrOfConvEq() [1/2]

template<typename T >
static std::enable_if< HasNbrOfConversion< T >::value >::type LibXR::STM32ADC::AssertNbrOfConvEq ( T hadc,
uint32_t n )
inlinestaticprivate

Definition at line 159 of file stm32_adc.hpp.

161 {
162 ASSERT(hadc->Init.NbrOfConversion == n);
163 }

◆ AssertNbrOfConvEq() [2/2]

template<typename T >
static std::enable_if<!HasNbrOfConversion< T >::value >::type LibXR::STM32ADC::AssertNbrOfConvEq ( T ,
uint32_t  )
inlinestaticprivate

Definition at line 165 of file stm32_adc.hpp.

167 {
168 }

◆ ConvertToVoltage()

float STM32ADC::ConvertToVoltage ( float adc_value)
private

Definition at line 228 of file stm32_adc.cpp.

229{
230 return adc_value * vref_ / resolution_;
231}

◆ GetChannel()

STM32ADC::Channel & STM32ADC::GetChannel ( uint8_t index)

获取 ADC 通道对象 Get ADC channel object

Parameters
index通道索引 Channel index
Returns
Channel& 通道对象 Channel object

Definition at line 86 of file stm32_adc.cpp.

86{ return *channels_[index]; }

◆ ReadChannel()

float STM32ADC::ReadChannel ( uint8_t channel)

读取 ADC

Parameters
channel通道号 Channel number
Returns
float

Definition at line 88 of file stm32_adc.cpp.

89{
90 if (channel >= NUM_CHANNELS)
91 {
92 ASSERT(false);
93 return -1.0f;
94 }
95
96 uint16_t* buffer = reinterpret_cast<uint16_t*>(dma_buffer_.addr_);
97 if (use_dma_)
98 {
99#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
100 SCB_InvalidateDCache_by_Addr(buffer, filter_size_ * NUM_CHANNELS * 2);
101#endif
102 uint32_t sum = 0;
103 for (uint8_t i = 0; i < filter_size_; ++i)
104 {
105 sum += buffer[channel + i * NUM_CHANNELS];
106 }
107 return ConvertToVoltage(static_cast<float>(sum) / static_cast<float>(filter_size_));
108 }
109
110 ADC_ChannelConfTypeDef config = {};
111 uint32_t time = 0;
112 UNUSED(time);
113#if defined(ADC_SAMPLETIME_16CYCLES)
114 time = ADC_SAMPLETIME_16CYCLES;
115#elif defined(ADC_SAMPLETIME_16CYCLES_5)
116 time = ADC_SAMPLETIME_16CYCLES_5;
117#elif defined(ADC_SAMPLETIME_17CYCLES)
118 time = ADC_SAMPLETIME_17CYCLES;
119#elif defined(ADC_SAMPLETIME_17CYCLES_5)
120 time = ADC_SAMPLETIME_17CYCLES_5;
121#elif defined(ADC_SAMPLETIME_18CYCLES)
122 time = ADC_SAMPLETIME_18CYCLES;
123#elif defined(ADC_SAMPLETIME_18CYCLES_5)
124 time = ADC_SAMPLETIME_18CYCLES_5;
125#elif defined(ADC_SAMPLETIME_19CYCLES)
126 time = ADC_SAMPLETIME_19CYCLES;
127#elif defined(ADC_SAMPLETIME_19CYCLES_5)
128 time = ADC_SAMPLETIME_19CYCLES_5;
129#elif defined(ADC_SAMPLETIME_20CYCLES)
130 time = ADC_SAMPLETIME_20CYCLES;
131#elif defined(ADC_SAMPLETIME_20CYCLES_5)
132 time = ADC_SAMPLETIME_20CYCLES_5;
133#elif defined(ADC_SAMPLETIME_21CYCLES)
134 time = ADC_SAMPLETIME_21CYCLES;
135#elif defined(ADC_SAMPLETIME_21CYCLES_5)
136 time = ADC_SAMPLETIME_21CYCLES_5;
137#elif defined(ADC_SAMPLETIME_22CYCLES)
138 time = ADC_SAMPLETIME_22CYCLES;
139#elif defined(ADC_SAMPLETIME_22CYCLES_5)
140 time = ADC_SAMPLETIME_22CYCLES_5;
141#elif defined(ADC_SAMPLETIME_23CYCLES)
142 time = ADC_SAMPLETIME_23CYCLES;
143#elif defined(ADC_SAMPLETIME_23CYCLES_5)
144 time = ADC_SAMPLETIME_23CYCLES_5;
145#elif defined(ADC_SAMPLETIME_24CYCLES)
146 time = ADC_SAMPLETIME_24CYCLES;
147#elif defined(ADC_SAMPLETIME_24CYCLES_5)
148 time = ADC_SAMPLETIME_24CYCLES_5;
149#elif defined(ADC_SAMPLETIME_25CYCLES)
150 time = ADC_SAMPLETIME_25CYCLES;
151#elif defined(ADC_SAMPLETIME_25CYCLES_5)
152 time = ADC_SAMPLETIME_25CYCLES_5;
153#elif defined(ADC_SAMPLETIME_26CYCLES)
154 time = ADC_SAMPLETIME_26CYCLES;
155#elif defined(ADC_SAMPLETIME_26CYCLES_5)
156 time = ADC_SAMPLETIME_26CYCLES_5;
157#elif defined(ADC_SAMPLETIME_27CYCLES)
158 time = ADC_SAMPLETIME_27CYCLES;
159#elif defined(ADC_SAMPLETIME_27CYCLES_5)
160 time = ADC_SAMPLETIME_27CYCLES_5;
161#elif defined(ADC_SAMPLETIME_28CYCLES)
162 time = ADC_SAMPLETIME_28CYCLES;
163#elif defined(ADC_SAMPLETIME_28CYCLES_5)
164 time = ADC_SAMPLETIME_28CYCLES_5;
165#elif defined(ADC_SAMPLETIME_29CYCLES)
166 time = ADC_SAMPLETIME_29CYCLES;
167#elif defined(ADC_SAMPLETIME_29CYCLES_5)
168 time = ADC_SAMPLETIME_29CYCLES_5;
169#elif defined(ADC_SAMPLETIME_30CYCLES)
170 time = ADC_SAMPLETIME_30CYCLES;
171#elif defined(ADC_SAMPLETIME_30CYCLES_5)
172 time = ADC_SAMPLETIME_30CYCLES_5;
173#elif defined(ADC_SAMPLETIME_31CYCLES)
174 time = ADC_SAMPLETIME_31CYCLES;
175#elif defined(ADC_SAMPLETIME_31CYCLES_5)
176 time = ADC_SAMPLETIME_31CYCLES_5;
177#elif defined(ADC_SAMPLETIME_32CYCLES)
178 time = ADC_SAMPLETIME_32CYCLES;
179#elif defined(ADC_SAMPLETIME_32CYCLES_5)
180 time = ADC_SAMPLETIME_32CYCLES_5;
181#error "Unsupported sample time"
182#endif
183
184 config.Channel = channels_[channel]->ch_;
185#if defined(ADC_REGULAR_RANK_1)
186 config.Rank = ADC_REGULAR_RANK_1;
187#else
188 config.Rank = 1;
189#endif
190#if defined(ADC_SINGLE_ENDED) && !defined(STM32L0)
191 config.SingleDiff = ADC_SINGLE_ENDED;
192#endif
193#if defined(ADC_OFFSET_NONE)
194 config.OffsetNumber = ADC_OFFSET_NONE;
195 config.Offset = 0;
196#endif
197#if !defined(STM32L0)
198 config.SamplingTime = time;
199#endif
200
201 uint32_t expected = 0U;
202
203 if (!locked_.compare_exchange_strong(expected, 0xF0F0F0F0U, std::memory_order_acquire,
204 std::memory_order_relaxed))
205 {
206 // Multiple threads are working on the same adc peripheral
207 // Please use dma mode
208 ASSERT(false);
209 return 0.0f;
210 }
211
212 HAL_ADC_ConfigChannel(hadc_, &config);
213
214 uint32_t sum = 0;
215 for (uint8_t i = 0; i < filter_size_; ++i)
216 {
217 HAL_ADC_Start(hadc_);
218 HAL_ADC_PollForConversion(hadc_, 20);
219 buffer[channel + i * NUM_CHANNELS] = HAL_ADC_GetValue(hadc_);
220 sum += buffer[channel + i * NUM_CHANNELS];
221 }
222
223 locked_.store(0, std::memory_order_release);
224
225 return ConvertToVoltage(static_cast<float>(sum) / static_cast<float>(filter_size_));
226}

Field Documentation

◆ channels_

Channel** LibXR::STM32ADC::channels_
private

Definition at line 257 of file stm32_adc.hpp.

◆ dma_buffer_

RawData LibXR::STM32ADC::dma_buffer_
private

Definition at line 255 of file stm32_adc.hpp.

◆ filter_size_

uint8_t LibXR::STM32ADC::filter_size_
private

Definition at line 253 of file stm32_adc.hpp.

◆ hadc_

ADC_HandleTypeDef* LibXR::STM32ADC::hadc_
private

Definition at line 251 of file stm32_adc.hpp.

◆ locked_

std::atomic<uint32_t> LibXR::STM32ADC::locked_ = 0U
private

Definition at line 250 of file stm32_adc.hpp.

◆ NUM_CHANNELS

const uint8_t LibXR::STM32ADC::NUM_CHANNELS
private

Definition at line 252 of file stm32_adc.hpp.

◆ resolution_

float LibXR::STM32ADC::resolution_
private

Definition at line 256 of file stm32_adc.hpp.

◆ use_dma_

bool LibXR::STM32ADC::use_dma_
private

Definition at line 254 of file stm32_adc.hpp.

◆ vref_

float LibXR::STM32ADC::vref_
private

Definition at line 258 of file stm32_adc.hpp.


The documentation for this class was generated from the following files: