libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
stm32_adc.hpp
1#pragma once
2
3#include <initializer_list>
4
5#include "main.h"
6
7#ifdef HAL_ADC_MODULE_ENABLED
8
9#ifdef ADC
10#undef ADC
11#endif
12
13#include "adc.hpp"
14#include "libxr.hpp"
15#include "libxr_def.hpp"
16
17namespace LibXR
18{
19
24{
25 template <typename, typename = void>
27 {
28 float Get(ADC_HandleTypeDef* hadc)
29 {
30 UNUSED(hadc);
31 return 4095.0f;
32 }
33 };
34
35 template <typename T>
36 struct GetADCResolution<T, std::void_t<decltype(std::declval<T>().Init.Resolution)>>
37 {
38 float Get(T* hadc)
39 {
40 switch (hadc->Init.Resolution)
41 {
42#ifdef ADC_RESOLUTION_16B
43 case ADC_RESOLUTION_16B:
44 return 65535.0f;
45#endif
46#ifdef ADC_RESOLUTION_12B
47 case ADC_RESOLUTION_12B:
48 return 4095.0f;
49#endif
50#ifdef ADC_RESOLUTION_10B
51 case ADC_RESOLUTION_10B:
52 return 1023.0f;
53#endif
54#ifdef ADC_RESOLUTION_8B
55 case ADC_RESOLUTION_8B:
56 return 255.0f;
57#endif
58#ifdef ADC_RESOLUTION_6B
59 case ADC_RESOLUTION_6B:
60 return 63.0f;
61#endif
62 default:
63 return 4095.0f;
64 }
65 }
66 };
67
68 template <typename T, typename = void>
69 struct HasContinuousConvMode : std::false_type
70 {
71 };
72
73 template <typename T>
75 T, std::void_t<decltype(std::declval<T>()->Init.ContinuousConvMode)>>
76 : std::true_type
77 {
78 };
79
80 template <typename T, typename = void>
81 struct HasDMAContinuousRequests : std::false_type
82 {
83 };
84
85 template <typename T>
87 T, std::void_t<decltype(std::declval<T>()->Init.DMAContinuousRequests)>>
88 : std::true_type
89 {
90 };
91
92 template <typename T, typename = void>
93 struct HasNbrOfConversion : std::false_type
94 {
95 };
96
97 template <typename T>
99 T, std::void_t<decltype(std::declval<T>()->Init.NbrOfConversion)>> : std::true_type
100 {
101 };
102
103 template <typename T, typename = void>
104 struct HasDMACircularMode : std::false_type
105 {
106 };
107
108 template <typename T>
110 T, std::void_t<decltype(std::declval<T>()->DMA_Handle->Init.Mode)>> : std::true_type
111 {
112 };
113
114 template <typename T, typename = void>
115 struct HasConversionDataManagement : std::false_type
116 {
117 };
118
119 template <typename T>
121 T, std::void_t<decltype(std::declval<T>()->Init.ConversionDataManagement)>>
122 : std::true_type
123 {
124 };
125
126 template <typename T>
127 static typename std::enable_if<HasContinuousConvMode<T>::value>::type
128 AssertContinuousConvModeEnabled(T hadc)
129 {
130 ASSERT(hadc->Init.ContinuousConvMode == ENABLE);
131 }
132
133 template <typename T>
134 static typename std::enable_if<!HasContinuousConvMode<T>::value>::type
135 AssertContinuousConvModeEnabled(T)
136 {
137 }
138
139 template <typename T>
140 static typename std::enable_if<HasContinuousConvMode<T>::value>::type
141 AssertContinuousConvModeDisabled(T hadc)
142 {
143 ASSERT(hadc->Init.ContinuousConvMode == DISABLE);
144 }
145
146 template <typename T>
147 static typename std::enable_if<!HasContinuousConvMode<T>::value>::type
148 AssertContinuousConvModeDisabled(T)
149 {
150 }
151
152 // 有 ConversionDataManagement 的时候,只看 ConversionDataManagement ==
153 // ADC_CONVERSIONDATA_DMA_CIRCULAR
154 template <typename T>
155 static typename std::enable_if<HasConversionDataManagement<T>::value>::type
156 AssertDMAContReqEnabled(T hadc)
157 {
158#ifdef ADC_CONVERSIONDATA_DMA_CIRCULAR
159 ASSERT(hadc->Init.ConversionDataManagement == ADC_CONVERSIONDATA_DMA_CIRCULAR);
160#else
161 UNUSED(hadc);
162#endif
163 }
164
165 // 没有 ConversionDataManagement,但有 DMAContinuousRequests => 维持原有检查
166 template <typename T>
167 static typename std::enable_if<!HasConversionDataManagement<T>::value &&
168 HasDMAContinuousRequests<T>::value>::type
169 AssertDMAContReqEnabled(T hadc)
170 {
171 ASSERT(hadc->Init.DMAContinuousRequests == ENABLE);
172 }
173
174 template <typename T>
175 static typename std::enable_if<!HasConversionDataManagement<T>::value &&
176 !HasDMAContinuousRequests<T>::value>::type
177 AssertDMAContReqEnabled(T)
178 {
179 }
180
181 template <typename T>
182 static typename std::enable_if<HasNbrOfConversion<T>::value>::type AssertNbrOfConvEq(
183 T hadc, uint32_t n)
184 {
185 ASSERT(hadc->Init.NbrOfConversion == n);
186 }
187
188 template <typename T>
189 static typename std::enable_if<!HasNbrOfConversion<T>::value>::type AssertNbrOfConvEq(
190 T, uint32_t)
191 {
192 }
193
194 template <typename T>
195 static typename std::enable_if<HasDMACircularMode<T>::value>::type AssertDMACircular(
196 T hadc)
197 {
198 ASSERT(hadc->DMA_Handle != nullptr);
199 ASSERT(hadc->DMA_Handle->Init.Mode == DMA_CIRCULAR);
200 }
201
202 template <typename T>
203 static typename std::enable_if<!HasDMACircularMode<T>::value>::type AssertDMACircular(T)
204 {
205 }
206
207 public:
211 class Channel : public ADC
212 {
213 public:
221 Channel(STM32ADC* adc, uint8_t index, uint32_t ch);
222
228 float Read() override;
229
230 private:
231 Channel();
232 STM32ADC* adc_;
233 uint8_t index_;
234 uint32_t ch_;
235
236 friend class STM32ADC;
237 };
238
247 STM32ADC(ADC_HandleTypeDef* hadc, RawData dma_buff,
248 std::initializer_list<uint32_t> channels, float vref);
249
253 ~STM32ADC();
254
261 Channel& GetChannel(uint8_t index);
262
269 float ReadChannel(uint8_t channel);
270
271 private:
272 alignas(LibXR::CONCURRENCY_ALIGNMENT) std::atomic<uint32_t> locked_ = 0U;
273 ADC_HandleTypeDef* hadc_;
274 const uint8_t NUM_CHANNELS;
275 uint8_t filter_size_;
276 bool use_dma_;
277 RawData dma_buffer_;
278 float resolution_;
279 Channel** channels_;
280 float vref_;
281
282 float ConvertToVoltage(float adc_value);
283};
284
285} // namespace LibXR
286
287#endif
模拟数字转换器(ADC)基类
Definition adc.hpp:18
可写原始数据视图 / Mutable raw data view
ADC 通道对象 / ADC channel object.
float Read() override
读取 ADC 电压值 / Read ADC voltage
Definition stm32_adc.cpp:46
STM32 ADC 驱动实现 / STM32 ADC driver implementation.
Definition stm32_adc.hpp:24
STM32ADC(ADC_HandleTypeDef *hadc, RawData dma_buff, std::initializer_list< uint32_t > channels, float vref)
构造 ADC 驱动对象 / Construct ADC driver object
Definition stm32_adc.cpp:48
~STM32ADC()
析构函数 / Destructor
Definition stm32_adc.cpp:95
float ReadChannel(uint8_t channel)
读取指定通道电压 / Read channel voltage
Channel & GetChannel(uint8_t index)
获取 ADC 通道对象 / Get ADC channel object
LibXR 命名空间
Definition ch32_can.hpp:14
constexpr size_t CONCURRENCY_ALIGNMENT
并发结构对齐粒度(用于降低多核伪共享) / Alignment policy used by concurrency-oriented structures
Definition libxr_def.hpp:62