|
概述 本章通过使用模数转换器(ADC),通过轮询方式采集多个ADC通道电压。
1 E: x: |7 u$ H2 K硬件准备 首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:
: ~9 m4 D. L$ V
Y, t9 e& L( [) }$ e$ k7 H$ |% W& y
选择芯片型号 使用STM32CUBEMX选择芯片stm32f030r8,如下所示: ; z- M4 p* b( _2 {2 t
* O, X2 X. o1 K- |- n# u
配置时钟源 HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:2 q+ L# C, u, K
9 N- ^5 t0 X8 i! T
7 @! w A& `- S+ f5 K
配置时钟树 STM32F0的最高主频到48M,所以配置48即可:
5 j* \ y/ Z9 E6 `( p2 d6 T
* ?! U" P3 F' t, ~+ q# O3 x6 ^* S, r8 G. c; C) Y G
串口配置 本次实验使用的串口1进行串口通信,波特率配置为115200。
. G% u4 W9 N x, k% G / K& f% Z% @7 Y: Z
! ~/ u2 }2 f" F5 m: V* o/ C6 i: L0 l& \7 ]( n, E8 f
ADC配置 STM32f030中,有一个ADC(模拟/数字转换器),每个 ADC 有 12 位、 10 位、 8 位和 6 位可选,每个ADC有16个外部通道、2个内部通道和一个VBAT 通道的信号。 本文将开ADC的IN0、IN1、IN15一共三个通道,来分别读取ADC,由于串口2和IN2,IN3复用,故不使用IN2、IN3。配置如下:
+ ?- N/ U8 n1 _2 O2 U5 s7 f. A 生成工程设置 注意在生产工程设置中不能出现中文,不然会报错。
( E _$ z- a% ]. d8 f; Y
( H# _- c8 L% v& ^
8 t# s/ t% G: `/ L9 o( S: q 生成代码/ z& O; Q; i. \ q3 D, S
1 E! C, l* [- p: ?% c4 M$ R3 W
' j4 p) D+ O' p9 Y% ~* {配置keil
1 [) H0 d: G1 k. @4 D& j
! w M2 w I3 ^2 T1 Y4 M$ `* l9 y7 C+ R ^5 n
在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。 - /* USER CODE BEGIN Includes */
, j {: `8 T7 p/ ^, c5 S - #include "stdio.h"
7 v' [: G. Z5 | I" } - /* USER CODE END Includes */
复制代码
, _+ N" y# O: r" C) F 函数声明和串口重定向: - /* USER CODE BEGIN PTD */
1 O$ D) ]- m( [" v& \ - #ifdef __GNUC__
k; H. A% `) u, }7 T - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
. m" ?4 l9 N: u1 P8 n0 S - #else- g6 I: A! k! L, A
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
) @. y, M3 ]& H2 V P3 _9 M) x - #endif /* __GNUC__ */
) A- t$ R3 d9 a9 h. f0 P - ! z. P- T" B: ^% t8 {
- * }+ x! | ]; C" a+ E! y
- PUTCHAR_PROTOTYPE. Y& n+ h& [* \% M5 C
- {9 N( K1 v5 D4 Z6 q
- HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
6 Q: A3 j7 X1 ]- M - return ch;
) a% `& Y2 b& F. y$ V2 t5 d6 H" @ - }, A) R: y* z5 d4 N* k
- /* USER CODE END PTD */
复制代码 & x9 y" F4 d( f4 w/ \
变量定义: - /* USER CODE BEGIN 0 */
" y) [9 [( N4 Z& }: ]; X. Z - uint8_t i;
( i: C+ h0 X, `( D$ z- w4 i5 W - uint16_t adcBuf[3];//存放ADC
, N! C9 }3 P% U - /* USER CODE END 0 */
复制代码 2 \+ K8 i {. ~& C6 ^8 Q
主循环: - /* USER CODE BEGIN WHILE */
+ u) b% _: E/ q) T1 X - while (1)
' d( A+ v0 y# n, { - {
: Z& e, g% V0 T - /* USER CODE END WHILE */
2 i7 ^& U: c/ d' X# w - 4 P9 i) O- k$ V8 z" R4 s
- /* USER CODE BEGIN 3 */* n. c& d, E3 O; Q/ a
- i=0; n! Q5 H7 o) B# m8 z" V9 b
- while(i<3)
" s0 V0 p8 b. C( e# D - {8 D5 k8 Y7 W* g; V2 ?
- HAL_ADC_Start(&hadc);//启动ADC) T, H' y, m% j' ^9 G6 ~+ x
- HAL_ADC_PollForConversion(&hadc,0xffff);//表示等待转换完成,第二个参数表示超时时间,单位ms.
' W2 ]7 j: C8 Z. F/ C - //HAL_ADC_GetState(&hadc1)为换取ADC状态,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用。, N( _9 |% o' }) u6 Z4 v
- if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc),HAL_ADC_STATE_REG_EOC))//就是判断转换完成标志位是否设置,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用
4 w- O' D. R, [, N% G; W - {1 F: K W% r1 N+ k
- //读取ADC转换数据,数据为12位。查看数据手册可知,寄存器为16位存储转换数据,数据右对齐,则转换的数据范围为0~2^12-1,即0~4095.8 [- d ?& P& ]3 f5 n k
- adcBuf[i]=HAL_ADC_GetValue(&hadc);; B: E' k& v% Z z7 r* n
- printf("\nadc%d=%4.0d,电压=%1.4f",i,adcBuf[i],adcBuf[i]*3.3f/4096);2 Y; i$ {* e8 P; V6 F
- i++;5 T0 M3 G: a- D2 C' e
- }" k8 G8 M( t) l' i
- }! d7 }. g. M! @; V+ }: f
6 M: [7 b4 T. R) i6 b$ h( Y- HAL_ADC_Stop(&hadc);/ m9 h8 R4 y; y9 c. Z
- HAL_Delay(500); # g j O; n) G( d! N
- }
$ p' d- i6 R! M0 j) y" q) Z2 \6 O - /* USER CODE END 3 */
复制代码 ( e- j/ Y! j% l0 L F
0 |1 _$ \ S: H; z+ Y# F# A演示效果 设定adc0口接3.3V,adc1口接GND,adc3口接1.5V,输出如下。
6 W7 {5 u. G8 J. y : b! E* I- @+ i# ]" V1 z
8 x; i/ o0 z+ q$ X4 N; h! ^! [, e- p0 K
: A( N0 } U$ g3 p4 f* g: ?" R8 e. N5 D5 {# H! H
|