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

STM32 ADC 驱动实现 / STM32 ADC driver implementation. More...

#include <stm32_adc.hpp>

Collaboration diagram for LibXR::STM32ADC:
[legend]

Data Structures

class  Channel
 ADC 通道对象 / ADC channel object. More...
 
struct  GetADCResolution
 
struct  GetADCResolution< T, std::void_t< decltype(std::declval< T >().Init.Resolution)> >
 
struct  HasContinuousConvMode
 
struct  HasContinuousConvMode< T, std::void_t< decltype(std::declval< T >() ->Init.ContinuousConvMode)> >
 
struct  HasConversionDataManagement
 
struct  HasConversionDataManagement< T, std::void_t< decltype(std::declval< T >() ->Init.ConversionDataManagement)> >
 
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)
 构造 ADC 驱动对象 / Construct ADC driver object
 
 ~STM32ADC ()
 析构函数 / Destructor
 
ChannelGetChannel (uint8_t index)
 获取 ADC 通道对象 / Get ADC channel object
 
float ReadChannel (uint8_t channel)
 读取指定通道电压 / Read channel voltage
 

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< HasConversionDataManagement< T >::value >::type AssertDMAContReqEnabled (T hadc)
 
template<typename T >
static std::enable_if<!HasConversionDataManagement< T >::value &&HasDMAContinuousRequests< T >::value >::type AssertDMAContReqEnabled (T hadc)
 
template<typename T >
static std::enable_if<!HasConversionDataManagement< T >::value &&!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

STM32 ADC 驱动实现 / STM32 ADC driver implementation.

Definition at line 22 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 )

构造 ADC 驱动对象 / Construct ADC driver object

Parameters
hadcHAL ADC 句柄 / HAL ADC handle
dma_buffDMA 缓冲区 / DMA buffer
channelsADC 通道列表 / ADC channel list
vref参考电压 / Reference voltage

Definition at line 48 of file stm32_adc.cpp.

50 : hadc_(hadc),
51 NUM_CHANNELS(channels.size()),
52 filter_size_(CalculateFilterSize(dma_buff, channels.size())),
53 use_dma_(hadc_->DMA_Handle != nullptr),
54 dma_buffer_(dma_buff),
55 resolution_(GetADCResolution<ADC_HandleTypeDef>{}.Get(hadc)),
56 channels_(new Channel*[NUM_CHANNELS]),
57 vref_(vref)
58{
59 auto it = channels.begin();
60 for (uint8_t i = 0; i < NUM_CHANNELS; ++i)
61 {
62 channels_[i] = new Channel(this, i, *it++);
63 }
64
65#if defined(ADC_CALIB_OFFSET_AND_LINEARITY) && defined(ADC_SINGLE_ENDED)
66 HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET_AND_LINEARITY, ADC_SINGLE_ENDED);
67#elif defined(ADC_CALIB_OFFSET_LINEARITY) && defined(ADC_SINGLE_ENDED)
68 HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED);
69#elif defined(ADC_CALIB_OFFSET) && defined(ADC_SINGLE_ENDED)
70 HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
71#elif defined(ADC_SINGLE_ENDED)
72 HAL_ADCEx_Calibration_Start(hadc, ADC_SINGLE_ENDED);
73#else
74 HAL_ADCEx_Calibration_Start(hadc);
75#endif
76
77 if (use_dma_)
78 {
79 /* DMA must be in circular mode */
80 AssertContinuousConvModeEnabled<H>(hadc_);
81 AssertDMAContReqEnabled<H>(hadc_);
82 AssertDMACircular<H>(hadc_);
83 AssertNbrOfConvEq<H>(hadc_, NUM_CHANNELS);
84 HAL_ADC_Start_DMA(hadc_, reinterpret_cast<uint32_t*>(dma_buffer_.addr_),
85 NUM_CHANNELS * filter_size_);
86 }
87 else
88 {
89 AssertNbrOfConvEq<H>(hadc_, 1);
90 AssertContinuousConvModeDisabled<H>(hadc_);
91 HAL_ADC_Start(hadc_);
92 }
93}
void * addr_
数据起始地址 / Data start address

◆ ~STM32ADC()

STM32ADC::~STM32ADC ( )

析构函数 / Destructor

Definition at line 95 of file stm32_adc.cpp.

96{
97 use_dma_ ? HAL_ADC_Stop_DMA(hadc_) : HAL_ADC_Stop(hadc_);
98 for (uint8_t i = 0; i < NUM_CHANNELS; ++i)
99 {
100 delete channels_[i];
101 }
102 delete[] channels_;
103}

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 140 of file stm32_adc.hpp.

141 {
142 ASSERT(hadc->Init.ContinuousConvMode == DISABLE);
143 }

◆ AssertContinuousConvModeDisabled() [2/2]

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

Definition at line 147 of file stm32_adc.hpp.

148 {
149 }

◆ AssertContinuousConvModeEnabled() [1/2]

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

Definition at line 127 of file stm32_adc.hpp.

128 {
129 ASSERT(hadc->Init.ContinuousConvMode == ENABLE);
130 }

◆ AssertContinuousConvModeEnabled() [2/2]

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

Definition at line 134 of file stm32_adc.hpp.

135 {
136 }

◆ AssertDMACircular() [1/2]

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

Definition at line 194 of file stm32_adc.hpp.

196 {
197 ASSERT(hadc->DMA_Handle != nullptr);
198 ASSERT(hadc->DMA_Handle->Init.Mode == DMA_CIRCULAR);
199 }

◆ AssertDMACircular() [2/2]

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

Definition at line 202 of file stm32_adc.hpp.

203 {
204 }

◆ AssertDMAContReqEnabled() [1/3]

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

Definition at line 155 of file stm32_adc.hpp.

156 {
157#ifdef ADC_CONVERSIONDATA_DMA_CIRCULAR
158 ASSERT(hadc->Init.ConversionDataManagement == ADC_CONVERSIONDATA_DMA_CIRCULAR);
159#else
160 UNUSED(hadc);
161#endif
162 }

◆ AssertDMAContReqEnabled() [2/3]

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

Definition at line 168 of file stm32_adc.hpp.

169 {
170 ASSERT(hadc->Init.DMAContinuousRequests == ENABLE);
171 }

◆ AssertDMAContReqEnabled() [3/3]

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

Definition at line 176 of file stm32_adc.hpp.

177 {
178 }

◆ 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 181 of file stm32_adc.hpp.

183 {
184 ASSERT(hadc->Init.NbrOfConversion == n);
185 }

◆ AssertNbrOfConvEq() [2/2]

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

Definition at line 188 of file stm32_adc.hpp.

190 {
191 }

◆ ConvertToVoltage()

float STM32ADC::ConvertToVoltage ( float adc_value)
private

Definition at line 245 of file stm32_adc.cpp.

246{
247 return adc_value * vref_ / resolution_;
248}

◆ GetChannel()

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

获取 ADC 通道对象 / Get ADC channel object

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

Definition at line 105 of file stm32_adc.cpp.

105{ return *channels_[index]; }

◆ ReadChannel()

float STM32ADC::ReadChannel ( uint8_t channel)

读取指定通道电压 / Read channel voltage

Parameters
channel通道号 / Channel number
Returns
float 电压值 / Voltage value

Definition at line 107 of file stm32_adc.cpp.

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

Field Documentation

◆ channels_

Channel** LibXR::STM32ADC::channels_
private

Definition at line 278 of file stm32_adc.hpp.

◆ dma_buffer_

RawData LibXR::STM32ADC::dma_buffer_
private

Definition at line 276 of file stm32_adc.hpp.

◆ filter_size_

uint8_t LibXR::STM32ADC::filter_size_
private

Definition at line 274 of file stm32_adc.hpp.

◆ hadc_

ADC_HandleTypeDef* LibXR::STM32ADC::hadc_
private

Definition at line 272 of file stm32_adc.hpp.

◆ locked_

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

Definition at line 271 of file stm32_adc.hpp.

◆ NUM_CHANNELS

const uint8_t LibXR::STM32ADC::NUM_CHANNELS
private

Definition at line 273 of file stm32_adc.hpp.

◆ resolution_

float LibXR::STM32ADC::resolution_
private

Definition at line 277 of file stm32_adc.hpp.

◆ use_dma_

bool LibXR::STM32ADC::use_dma_
private

Definition at line 275 of file stm32_adc.hpp.

◆ vref_

float LibXR::STM32ADC::vref_
private

Definition at line 279 of file stm32_adc.hpp.


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