前言
& H' b/ q7 y6 |- F9 ?* d模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高低阈值,用户可以预先设定个模拟看门狗的上下限电压值,一旦采集到的电压超出该上下限,将会触发模拟看门狗中断。模拟看门狗一般用于检测单个的常规或注入转换通道,或同时检测所有的常规和注入通道。1 w6 n5 t3 b# k D; p' G4 M! N) v
模块框图
, D" j+ d8 r5 X( R; q, D2 v0 ], t1 z+ d8 Q0 R- I w
^9 ]& |9 `7 q) a) t6 r模拟看门狗可以预先设置 ADC 转换的高低阈值,ADC_HTR 寄存器来配置 ADC 转换的上限阈值,ADC_LTR 寄存器用来配置ADC 转换的下限阈值。 o+ S6 h5 h$ \
6 F0 p( J1 f2 K$ j0 [. ^应用示例2 Y' m6 Q& i! k
ADC 配置代码
+ a% z& X5 [# z+ `; V- /**
! b, T1 \7 K8 D6 V( H# V0 i
" D6 Z5 M* s0 m6 q" j8 E. a- * @brief ADC configuration) Q# ], l7 z3 a8 G, M
- * @param None+ }6 c0 r$ s7 V3 o( q. ~0 D6 ?4 g: `
- * @retval None+ v. H# N+ \* |; S6 c7 H/ ^
- */5 n q8 D: X9 R9 a8 e
- static void ADC_Config(void)
4 u: n; J& E0 n2 Q, F0 B - {
9 m- ]: p. v: u w - ADC_ChannelConfTypeDef sConfig;
$ M4 Q- Z+ F/ ~- R$ U - ADC_AnalogWDGConfTypeDef AnalogWDGConfig;4 |) u0 D& }$ N& H
- U% X! O4 D1 [+ Q
- /* Configuration of ADCx init structure: ADC parameters and regular group */' f8 f( O, \0 q8 {! h, G! v
- AdcHandle.Instance = ADCx;, K% O" K% B7 G* \+ i b/ P7 s
- AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; /* Asynchronous3 K: V5 z; w5 w
- clock mode, input ADC clock not divided */
( R# k8 a6 f& I- @ - AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit0 d Q8 w5 _- S: V$ K: x. k
- resolution for converted data */- d; o4 [6 L# R* U# T8 ?. w+ S% o7 g
- AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Rightalignment for converted data */# E* c& e U% H! a9 M, u
- AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer
( c6 {1 W$ P% n) ~ - disabled (ADC conversion on only 1 channel: channel set on rank 1) */; O0 Z/ y1 P+ E6 q m+ C/ n8 h& z4 f Y
- AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag
; N. a* B2 j) v% D - picked-up to indicate conversion end */
, N9 _- X" g L& Q3 F Y7 E) o - AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed3 H7 @/ R3 B4 P
- conversion feature disabled */; ]) Y6 g9 D) k* ?# k* `4 m
- AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous# C, ]7 v: M: Y+ ^* c q M) n
- mode disabled to have only 1 conversion at each conversion trig */
9 ]0 U9 Z5 b( B - AdcHandle.Init.NbrOfConversion = 1; /* Parameter
1 [, I3 |' W% b% a2 X: {, s - discarded because sequencer is disabled */
5 O# O/ @8 u( Y7 i& l1 K o: ` - AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter7 H: i* D3 h: L s
- discarded because sequencer is disabled */
9 H0 f N9 s) D9 ^' S2 z - AdcHandle.Init.NbrOfDiscConversion = 1; /* Parameter' a( I; }: P! d e/ q
- discarded because sequencer is disabled */. o; Y5 M8 p+ b* C- Q: B1 \, x5 ?
- AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_TRGO; /* Timer 3
; J7 ~( g9 { _$ B( P8 F% } - external event triggering the conversion */
3 Q3 c0 ^+ i: E4 D: h - AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; /* Parameter6 z# Z( I6 {$ ?( l' ]+ Q( s
- discarded because software trigger chosen */
' d8 o! ~% I2 b# B, Q! y* O! K2 k2 X j - AdcHandle.Init.DMAContinuousRequests = ENABLE; /* DMA circular
" W5 B* q. R, x+ n$ d( ] - mode selected */
' B3 s5 c6 I$ A! X1 O - AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is/ F6 E) g6 N3 Z' m' h: V
- overwritten with the last conversion result in case of overrun */
- B9 E, |3 U* p7 v - AdcHandle.Init.OversamplingMode = DISABLE; /* No( C6 u7 G; C: K1 t: p+ ~. R% M; g2 T
- oversampling */8 y' _/ y- i$ }: i6 f
- if (HAL_ADC_Init(&AdcHandle) != HAL_OK)2 a5 x* I/ n& y! E: q% d4 Q
- {1 L& G6 _8 P2 U
- /* ADC initialization error */+ F& p4 v1 V) q' G
- Error_Handler();, Y% e; ] m Z. a8 V, ?
- }- w/ X1 n* {2 D' ~
- /* Configuration of channel on ADCx regular group on sequencer rank 1 */; @! q! g( |& y$ m+ L
- /* Note: Considering IT occurring after each ADC conversion if ADC */
7 N2 e3 B$ s0 G0 }) U - /* conversion is out of the analog watchdog window selected (ADC IT */# S3 I; ~! F i+ h; _' D
- /* enabled), select sampling time and ADC clock with sufficient */
1 [% k% y! s) _4 Y9 {8 r - /* duration to not create an overhead situation in IRQHandler. */ j0 P0 O& f5 a) E" `! j
- sConfig.Channel = ADC_CHANNEL_5; /* Sampled channel number */9 H# d: t, d. I/ s* o& W
- sConfig.Rank = ADC_REGULAR_RANK_1; /* Rank of sampled channel number
1 u A3 J+ K0 H! J/ i" {0 [7 B - ADCx_CHANNEL */
) A2 c9 r G Q; T - sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; /* Sampling time (number of clock: O2 @6 }$ C% {0 a- r2 ~
- cycles unit) */$ X7 A6 G( j2 w; }% @7 f
- sConfig.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */
2 M q3 M, {3 H! D! u8 ` - sConfig.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */" o7 u" a; F* Z3 x
- sConfig.Offset = 0; /* Parameter discarded because* [; v3 _( n( \6 S2 ~' Y# c0 f
- offset correction is disabled */
" v- }1 j, k7 L- R* u: ]# D6 ] - % W$ v/ E/ E. ]; s6 a6 c0 s2 ~
- if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
- V0 ?4 f8 }% A! Q1 A - {
6 C* n( h, I, G* B- M6 N4 { - /* Channel Configuration Error */
+ c) ?# t* N8 J - Error_Handler();
( C3 X; d" I' Z, Q, _5 u - }$ G2 k$ T4 Q0 l& Q; K9 U' N
' \/ p, N+ Z6 c- /* Set analog watchdog thresholds in order to be between steps of DAC */6 E8 L/ K! @/ j; d8 C8 ~" Q( p8 ]
- /* voltage. */6 N2 V, A' |8 s [
- /* - High threshold: between DAC steps 1/2 and 3/4 of full range: */
9 \1 T) f# Y) w( G& \; Y+ Z2 C - /* 5/8 of full range (4095 Vdda=3.3V): 2559 2.06V */8 q( p& _/ w* G8 n% V) P
- /* - Low threshold: between DAC steps 0 and 1/4 of full range: */! r9 x/ O$ _7 M
- /* 1/8 of full range (4095 Vdda=3.3V): 512 0.41V */
* i- }+ }' f4 r% ]$ k) W4 C4 c - /* Analog watchdog 1 configuration */3 [: p: d9 s2 o' x7 I; e# J
- AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_1;
. u( e2 ?" B0 F- M n - AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_ALL_REG;
; x6 {$ D7 {4 c) W" i5 ^3 U - AnalogWDGConfig.Channel = ADCx_CHANNELa;4 n8 J% d8 i5 j/ w! _% b
- AnalogWDGConfig.ITMode = ENABLE;! Q; {9 y ]0 W* J |
- AnalogWDGConfig.HighThreshold = (RANGE_12BITS * 5/8);
, i e* x9 q8 B7 y. ^ - AnalogWDGConfig.LowThreshold = (RANGE_12BITS * 1/8);; m% [' N- t1 a: [
- if (HAL_ADC_AnalogWDGConfig(&AdcHandle, &AnalogWDGConfig) != HAL_OK)
% {. p. d7 p- ?, E W9 k9 ?& H - {9 Y }* O. C& ~/ |& m
- /* Channel Configuration Error */ j5 f4 ^9 w. n# z) r, w
- Error_Handler();! W. a! C, D$ t2 J' \
- }7 u, w# w4 z. M/ Q( E( o& {- w. Z
6 }& Z. q/ j3 L4 v: v- }
复制代码 % L/ }# h) h* s7 t4 n) ~
如上图所示,AnalogWDGConfig 结构体中分别使能了模拟看门狗及中断,设置了电压的上下阈值 HighThreshold 和LowThreshold。模拟参考电压为 3.3V,以上代码设置的下限电压阈值为 3.3*1/8=0.41V,上限电压阈值为 3.3*5/8=2.06V。5 B8 |$ B2 S q
2 p4 k) q0 R I' T' B模拟看门狗中断服务程序8 X% Y4 J* G1 @( d' u7 K% }$ ]
- /**4 z( M! R4 _/ n6 g2 @9 r7 n
+ B# F) h+ _$ u1 o5 x+ x& u- * @brief Analog watchdog callback in non blocking mode.
# w, {0 y5 H3 P - * @param hadc: ADC handle# w( ]: I) X" H. ?) }# w
- * @retval None( z, P/ {6 H) a% g
- */
o; p s) Y/ L+ ]- z - void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)9 a' c; N3 O- u3 V y
- {
0 }8 f( L% d, m9 e - /* Set variable to report analog watchdog out of window status to main */( R1 o D6 | X
- /* program. */
; P% u& `/ _0 q4 A( v9 h; w - ubAnalogWatchdogStatus = SET;
+ _% d- p: [/ g4 |$ Z4 b - }
复制代码 1 [! _! G/ e6 n: N
当模拟看门狗检测到电压高于上限或者低于下限时将会产生看门狗中断,中断服务程序触发后,可以做出一些应对措施。这里置了 ubAnalogWatchdogStatus 标志,然后由主程序去根据标志的值去执行相应处理程序。2 y9 e4 M- d! ?% @9 @1 d, F
- /* Infinite loop */
) t4 r0 G( q1 Q% t+ a - while (1)
- h+ A% Y) |! |, G8 Q' h - {
) Z2 J6 k4 X2 D! E+ k$ ^, q - /* Turn-on/off LED1 in function of ADC conversion result */2 N! Y2 G5 z( q; l" @' X
- /* - Turn-off if voltage is into AWD window */
( d+ \' I! |! r - /* - Turn-on if voltage is out of AWD window */2 w) w* B) U6 N7 ?' ~' d! r$ b$ G
- /* Variable of analog watchdog status is set into analog watchdog */# I- y$ i M; H! Z$ U4 v! f7 Y
- /* interrupt callback */
! l9 D7 I+ ~6 F$ f } - if (ubAnalogWatchdogStatus == RESET)! x6 q0 `# h5 G; J) S' I
- {
* y5 q* I9 b9 V% q0 B - BSP_LED_Off(LED1);
1 {7 Y. \9 u7 U - }. k, |. d2 `3 U# _; P$ \1 r
- else
% }7 F% \+ f' w8 m y - {1 j" u$ o9 E4 n9 E" N
- BSP_LED_On(LED1);
+ L. E! Y/ r f; o - + h; _3 e& A# D: [) ^
- /* Reset analog watchdog status for next loop iteration */
( g L( ~" y0 A& S - ubAnalogWatchdogStatus = RESET;
' a* H6 D0 D% L; R/ m9 V - }- N" }( F' h( J- d- l {
- }
复制代码
' ?: F7 c' @' }9 L( v, b& y, S+ i; {启动 ADC 转换代码2 w& d% m0 T; V
- #define ADCCONVERTEDVALUES_BUFFER_SIZE 256 /* Size of array+ N* K( \ U" j0 u0 c& Z
- aADCxConvertedValues[] */: T' H% j. E+ ^6 t: M: _
- /* Variable containing ADC conversions results */, s; U, Y4 Z+ U/ z- v8 u
- __IO uint16_t aADCxConvertedValues[ADCCONVERTEDVALUES_BUFFER_SIZE];
( d% c9 k# u2 P4 Z) }! |1 D - /* Start ADC conversion on regular group with transfer by DMA */
: m1 R* R: L' a - if (HAL_ADC_Start_DMA(&AdcHandle,
) E+ _, {* ~ A) M - (uint32_t *)aADCxConvertedValues,
, x4 W& K/ r9 d( |5 y9 P - ADCCONVERTEDVALUES_BUFFER_SIZE
0 F' n. M4 r \' R! y - ) != HAL_OK)
7 }& x7 E2 i0 e; f; o8 H5 G( n - {! r; f' U+ p/ f& c9 J3 [4 F& Q0 l
- /* Start Error */
, |% M+ s- A8 Q' l: O - Error_Handler();
t/ F9 c$ T% V2 X - }
复制代码
. ^3 \% n) U; j0 t2 G7 n7 D4 V使用循环模式 DMA 启动 ADC 转换,DMA 可以降低 CPU 负载。( G Z# c& b0 Q
- g" S& @' g8 ~) v, g8 w
结论, l( S6 ~; E+ [1 U
控制系统中,需要测量严格电压、压力、温度等范围的信号,使用模拟看门狗能够快速地检测到异常状况,并做出相应的应对措施,以确保设备安全。9 J- {7 k3 @6 `- [2 V
! n/ [+ i5 V( U' z" X" | |