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
16namespace LibXR
17{
18
23{
24 template <typename, typename = void>
26 {
27 float Get(ADC_HandleTypeDef* hadc)
28 {
29 UNUSED(hadc);
30 return 4095.0f;
31 }
32 };
33
34 template <typename T>
35 struct GetADCResolution<T, std::void_t<decltype(std::declval<T>().Init.Resolution)>>
36 {
37 float Get(T* hadc)
38 {
39 switch (hadc->Init.Resolution)
40 {
41#ifdef ADC_RESOLUTION_16B
42 case ADC_RESOLUTION_16B:
43 return 65535.0f;
44#endif
45#ifdef ADC_RESOLUTION_12B
46 case ADC_RESOLUTION_12B:
47 return 4095.0f;
48#endif
49#ifdef ADC_RESOLUTION_10B
50 case ADC_RESOLUTION_10B:
51 return 1023.0f;
52#endif
53#ifdef ADC_RESOLUTION_8B
54 case ADC_RESOLUTION_8B:
55 return 255.0f;
56#endif
57#ifdef ADC_RESOLUTION_6B
58 case ADC_RESOLUTION_6B:
59 return 63.0f;
60#endif
61 default:
62 return 4095.0f;
63 }
64 }
65 };
66
67 template <typename T, typename = void>
68 struct HasContinuousConvMode : std::false_type
69 {
70 };
71
72 template <typename T>
74 T, std::void_t<decltype(std::declval<T>()->Init.ContinuousConvMode)>>
75 : std::true_type
76 {
77 };
78
79 template <typename T, typename = void>
80 struct HasDMAContinuousRequests : std::false_type
81 {
82 };
83
84 template <typename T>
86 T, std::void_t<decltype(std::declval<T>()->Init.DMAContinuousRequests)>>
87 : std::true_type
88 {
89 };
90
91 template <typename T, typename = void>
92 struct HasNbrOfConversion : std::false_type
93 {
94 };
95
96 template <typename T>
98 T, std::void_t<decltype(std::declval<T>()->Init.NbrOfConversion)>> : std::true_type
99 {
100 };
101
102 template <typename T, typename = void>
103 struct HasDMACircularMode : std::false_type
104 {
105 };
106
107 template <typename T>
109 T, std::void_t<decltype(std::declval<T>()->DMA_Handle->Init.Mode)>> : std::true_type
110 {
111 };
112
113 template <typename T, typename = void>
114 struct HasConversionDataManagement : std::false_type
115 {
116 };
117
118 template <typename T>
120 T, std::void_t<decltype(std::declval<T>()->Init.ConversionDataManagement)>>
121 : std::true_type
122 {
123 };
124
125 template <typename T>
126 static typename std::enable_if<HasContinuousConvMode<T>::value>::type
127 AssertContinuousConvModeEnabled(T hadc)
128 {
129 ASSERT(hadc->Init.ContinuousConvMode == ENABLE);
130 }
131
132 template <typename T>
133 static typename std::enable_if<!HasContinuousConvMode<T>::value>::type
134 AssertContinuousConvModeEnabled(T)
135 {
136 }
137
138 template <typename T>
139 static typename std::enable_if<HasContinuousConvMode<T>::value>::type
140 AssertContinuousConvModeDisabled(T hadc)
141 {
142 ASSERT(hadc->Init.ContinuousConvMode == DISABLE);
143 }
144
145 template <typename T>
146 static typename std::enable_if<!HasContinuousConvMode<T>::value>::type
147 AssertContinuousConvModeDisabled(T)
148 {
149 }
150
151 // 有 ConversionDataManagement 的时候,只看 ConversionDataManagement ==
152 // ADC_CONVERSIONDATA_DMA_CIRCULAR
153 template <typename T>
154 static typename std::enable_if<HasConversionDataManagement<T>::value>::type
155 AssertDMAContReqEnabled(T hadc)
156 {
157#ifdef ADC_CONVERSIONDATA_DMA_CIRCULAR
158 ASSERT(hadc->Init.ConversionDataManagement == ADC_CONVERSIONDATA_DMA_CIRCULAR);
159#else
160 UNUSED(hadc);
161#endif
162 }
163
164 // 没有 ConversionDataManagement,但有 DMAContinuousRequests => 维持原有检查
165 template <typename T>
166 static typename std::enable_if<!HasConversionDataManagement<T>::value &&
167 HasDMAContinuousRequests<T>::value>::type
168 AssertDMAContReqEnabled(T hadc)
169 {
170 ASSERT(hadc->Init.DMAContinuousRequests == ENABLE);
171 }
172
173 template <typename T>
174 static typename std::enable_if<!HasConversionDataManagement<T>::value &&
175 !HasDMAContinuousRequests<T>::value>::type
176 AssertDMAContReqEnabled(T)
177 {
178 }
179
180 template <typename T>
181 static typename std::enable_if<HasNbrOfConversion<T>::value>::type AssertNbrOfConvEq(
182 T hadc, uint32_t n)
183 {
184 ASSERT(hadc->Init.NbrOfConversion == n);
185 }
186
187 template <typename T>
188 static typename std::enable_if<!HasNbrOfConversion<T>::value>::type AssertNbrOfConvEq(
189 T, uint32_t)
190 {
191 }
192
193 template <typename T>
194 static typename std::enable_if<HasDMACircularMode<T>::value>::type AssertDMACircular(
195 T hadc)
196 {
197 ASSERT(hadc->DMA_Handle != nullptr);
198 ASSERT(hadc->DMA_Handle->Init.Mode == DMA_CIRCULAR);
199 }
200
201 template <typename T>
202 static typename std::enable_if<!HasDMACircularMode<T>::value>::type AssertDMACircular(T)
203 {
204 }
205
206 public:
210 class Channel : public ADC
211 {
212 public:
220 Channel(STM32ADC* adc, uint8_t index, uint32_t ch);
221
227 float Read() override;
228
229 private:
230 Channel();
231 STM32ADC* adc_;
232 uint8_t index_;
233 uint32_t ch_;
234
235 friend class STM32ADC;
236 };
237
246 STM32ADC(ADC_HandleTypeDef* hadc, RawData dma_buff,
247 std::initializer_list<uint32_t> channels, float vref);
248
252 ~STM32ADC();
253
260 Channel& GetChannel(uint8_t index);
261
268 float ReadChannel(uint8_t channel);
269
270 private:
271 alignas(LIBXR_CACHE_LINE_SIZE) std::atomic<uint32_t> locked_ = 0U;
272 ADC_HandleTypeDef* hadc_;
273 const uint8_t NUM_CHANNELS;
274 uint8_t filter_size_;
275 bool use_dma_;
276 RawData dma_buffer_;
277 float resolution_;
278 Channel** channels_;
279 float vref_;
280
281 float ConvertToVoltage(float adc_value);
282};
283
284} // namespace LibXR
285
286#endif
模拟数字转换器(ADC)基类
Definition adc.hpp:18
原始数据封装类。 A class for encapsulating raw data.
ADC 通道对象 / ADC channel object.
float Read() override
读取 ADC 电压值 / Read ADC voltage
Definition stm32_adc.cpp:27
STM32 ADC 驱动实现 / STM32 ADC driver implementation.
Definition stm32_adc.hpp:23
STM32ADC(ADC_HandleTypeDef *hadc, RawData dma_buff, std::initializer_list< uint32_t > channels, float vref)
构造 ADC 驱动对象 / Construct ADC driver object
Definition stm32_adc.cpp:29
~STM32ADC()
析构函数 / Destructor
Definition stm32_adc.cpp:76
float ReadChannel(uint8_t channel)
读取指定通道电压 / Read channel voltage
Definition stm32_adc.cpp:88
Channel & GetChannel(uint8_t index)
获取 ADC 通道对象 / Get ADC channel object
Definition stm32_adc.cpp:86
LibXR 命名空间
Definition ch32_can.hpp:14