|
概述 本章通过使用模数转换器(ADC),通过轮询方式采集多个ADC通道电压。
4 k0 b5 _# X7 {3 A$ V# b9 }硬件准备 首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板: ( _- ~+ l' M3 o3 w. O2 u0 C6 D9 n
8 t+ S, Z4 w( z
% `9 E$ n. P0 B4 `2 S# ~选择芯片型号 使用STM32CUBEMX选择芯片stm32f030r8,如下所示:
8 m. r- X4 D0 k# Q, h9 P
% _5 j: ] ]5 ~2 x0 ~. b5 `& }3 q 配置时钟源 HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:
# g+ \0 H5 Q( V( T; Z/ r9 u
( w& ]1 A# b! z% x# c$ r; Q" Q3 H& d
配置时钟树 STM32F0的最高主频到48M,所以配置48即可:
6 ?' t) j# X; y& M1 i- Z $ M6 I% e) s& a9 d: ?6 Y& i5 n
9 u2 i& A7 P6 H6 S串口配置 本次实验使用的串口1进行串口通信,波特率配置为115200。
. |+ X6 V/ W. [8 d
& t' z0 Z# I6 L2 m: T1 I b! `2 j# X6 X% l+ [6 @+ P* m
: ?+ G# i7 Y) ] X9 z, f4 ~2 j' q8 MADC配置 STM32f030中,有一个ADC(模拟/数字转换器),每个 ADC 有 12 位、 10 位、 8 位和 6 位可选,每个ADC有16个外部通道、2个内部通道和一个VBAT 通道的信号。 本文将开ADC的IN0、IN1、IN15一共三个通道,来分别读取ADC,由于串口2和IN2,IN3复用,故不使用IN2、IN3。配置如下: 6 s: g9 L* f9 J/ Z# c
生成工程设置 注意在生产工程设置中不能出现中文,不然会报错。
% E/ v7 M& K S, \4 G8 c ) ?" ?' I# O2 N. G% {9 ^9 u) O8 r% b
+ [; Q1 d3 |: {0 \) X3 h/ v4 i 生成代码+ B; j* D$ Y. B& G( T+ G
9 d4 l; l; c$ r* w: K' R* z
1 t* f" _8 E+ s( n5 r$ b配置keil
' G! L4 L! c1 N" N9 e7 x3 D: c
! Z6 H6 N3 o! g$ w5 h; y+ L6 ?9 D$ M/ e" d3 n; \1 O& X
在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。 - /* USER CODE BEGIN Includes */0 T4 o3 A N+ f
- #include "stdio.h"' R% g6 H. y8 \( T' k8 @
- /* USER CODE END Includes */
复制代码 ) o- g+ U! P* q7 F3 E
函数声明和串口重定向: - /* USER CODE BEGIN PTD */3 w- m; v+ S: X: E/ y
- #ifdef __GNUC__
' l9 C% X/ Q3 F/ B - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
5 I) e2 W4 g0 R: k* y( e - #else! I5 x) ?$ r7 v
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f), t2 Z* |+ Z) m2 p! w% g0 Q2 g1 r/ y3 A
- #endif /* __GNUC__ */
. O2 N8 t; D1 \3 L: U
. G% }! r5 a9 B% x, H3 t2 H, [( \- 3 X5 _* R0 {) k/ x7 d) v/ C
- PUTCHAR_PROTOTYPE
9 K9 b% j5 \ k+ P - {7 X& P4 z# V) C6 u& x+ g1 E# G
- HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
+ E* Z& V w0 c# b/ Z - return ch;$ Z6 {. `6 @6 X. o* a S; ]
- }4 {: [$ X& m4 o8 p7 P
- /* USER CODE END PTD */
复制代码 + z+ O9 U' c/ [) B5 D# m3 r1 \
变量定义: - /* USER CODE BEGIN 0 */: N+ P: ]+ F: j+ N! [5 S1 r
- uint8_t i;) K- J8 p2 H% t! v$ ]( g
- uint16_t adcBuf[3];//存放ADC
& i+ Z+ f ~' G- L" M( l - /* USER CODE END 0 */
复制代码
, F- B0 ]( X( V6 S( A 主循环: - /* USER CODE BEGIN WHILE */
1 j0 W$ A s. U) O8 |6 S - while (1)
; c0 N7 g4 z* ~" A* @3 } - {
' L) B! O. T! J# f - /* USER CODE END WHILE */
6 @# q) ~3 Y s) N# o - ! T: w$ b+ M) [! |; c7 D
- /* USER CODE BEGIN 3 */
q7 C) o3 ~ q- ` - i=0; / _7 t1 Y% R& |! [0 M# w
- while(i<3)0 x0 k6 U$ o$ K5 J/ P' R
- {
; A r8 C# a8 w1 w( r - HAL_ADC_Start(&hadc);//启动ADC
# r, i0 Y0 F3 K, w7 h: d - HAL_ADC_PollForConversion(&hadc,0xffff);//表示等待转换完成,第二个参数表示超时时间,单位ms.* s8 @% S9 \2 _1 o
- //HAL_ADC_GetState(&hadc1)为换取ADC状态,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用。
" }! w7 ~/ [5 |4 V - if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc),HAL_ADC_STATE_REG_EOC))//就是判断转换完成标志位是否设置,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用! L$ Y3 M) v& W1 e' N
- {
4 t6 q$ y9 u9 c2 S% \7 Z) _7 S9 o2 J - //读取ADC转换数据,数据为12位。查看数据手册可知,寄存器为16位存储转换数据,数据右对齐,则转换的数据范围为0~2^12-1,即0~4095.
2 W) u6 F. i, _9 r* F; s - adcBuf[i]=HAL_ADC_GetValue(&hadc);
3 f, N# R" W7 D h! x& n2 A - printf("\nadc%d=%4.0d,电压=%1.4f",i,adcBuf[i],adcBuf[i]*3.3f/4096);
* z- I4 U- \1 M* a+ D( A - i++;, b7 _" P) Q6 t" n
- }
! R6 ]- Z0 G. i$ g7 r: X# w - }
; t" |, L/ L q
# e# j+ ?; @# o: z \- K- HAL_ADC_Stop(&hadc);: \) e' {! j4 ~1 l$ t* X" ^1 d
- HAL_Delay(500);
* Y0 C; h1 ?8 h' i4 u5 _ - }! g2 c$ ~/ U+ K8 K" b0 Q* w
- /* USER CODE END 3 */
复制代码
1 y. q9 p/ K7 j6 b, _; D8 }9 ?4 t M3 a6 C8 K
演示效果 设定adc0口接3.3V,adc1口接GND,adc3口接1.5V,输出如下。; n2 A t- p- }- k
4 l7 O# g% @0 ~+ [5 t
9 v7 {5 M" x7 G' T3 I$ c l
7 P' s- x/ S+ b# X% C/ C5 l0 d, w9 Y) r ) y: P' V! H5 T |+ z! W( t4 U/ U
! o, J# v( P1 I# v
+ q# j( A( ~. h9 I' D! K2 z |