|
概述 本章通过使用模数转换器(ADC),通过轮询方式采集多个ADC通道电压。
) T3 Y) j' U# p5 Q) h ]5 l硬件准备 首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板: ; v& `4 f N* K+ c# e1 Q" e
y. U9 f& |2 j$ I9 r v& L0 s5 y
/ m. M# H$ u* _& S7 ?
选择芯片型号 使用STM32CUBEMX选择芯片stm32f030r8,如下所示:
7 o* ]: t! f* O
+ c) y$ x; T$ J( `8 w 配置时钟源 HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示: ~/ R/ }8 S2 `
: G, n' q6 ^" ], }: G- N
. e; R% s7 r) n, b0 k1 i- M" y
配置时钟树 STM32F0的最高主频到48M,所以配置48即可:, [$ D& z" _; y# P/ ?
3 }2 E3 B7 F5 q, v( c( d% ~9 |
/ q2 K$ F1 x5 c p8 x; }串口配置 本次实验使用的串口1进行串口通信,波特率配置为115200。
! N$ F( b2 T L
( z1 }6 Z# z1 \# d) f9 T4 o( Q! ?" M3 ]
' e8 ~# w! _0 n
ADC配置 STM32f030中,有一个ADC(模拟/数字转换器),每个 ADC 有 12 位、 10 位、 8 位和 6 位可选,每个ADC有16个外部通道、2个内部通道和一个VBAT 通道的信号。 本文将开ADC的IN0、IN1、IN15一共三个通道,来分别读取ADC,由于串口2和IN2,IN3复用,故不使用IN2、IN3。配置如下:
9 z! S, u0 N# p$ ^ s. Y 生成工程设置 注意在生产工程设置中不能出现中文,不然会报错。
, a. G7 U8 I; B3 R ?6 J& ^ 2 T- n7 f& j* R
0 J) w9 ~- Z/ C* \% T
生成代码% F' a& v3 n, |
! {' C! u* ~/ O
( J4 ~9 k0 ]$ t; Y0 Z! k
配置keil" e p% }* P: Z* b
! F' q7 Y/ R0 [7 m, T/ T1 g
+ p# y: s$ t5 J2 x" P, P 在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。 - /* USER CODE BEGIN Includes */4 B$ b" ^ ?6 }' W F* K: `
- #include "stdio.h", V4 a' V3 u8 o1 S5 h5 l& \9 ]
- /* USER CODE END Includes */
复制代码
. \& p7 J+ B+ o 函数声明和串口重定向: - /* USER CODE BEGIN PTD */6 D5 w- ], U. t" A7 t! l. d: ]7 A
- #ifdef __GNUC__9 T7 |& O i/ l( h
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
4 v; [9 H) B2 s3 O/ U& W3 j6 @ - #else
/ h* ^( A& ?" p( K2 r3 \ - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
! u; c: F# g" J7 ^! S - #endif /* __GNUC__ */
7 ?- Y# G ~% m- G. `& ^. M6 S2 H
$ ^- U" ~. j! q. C- f( ^5 S- ' o1 f# e: I: i K- r2 t
- PUTCHAR_PROTOTYPE
6 h5 l6 e5 K: @) A9 t - {6 [: ~" |! E. U
- HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);6 X# n' [ ^/ h* W' y. m: Y
- return ch;
# g' ]/ Z1 @, z' g - }
9 g* p% D/ k9 y z0 }9 D# c - /* USER CODE END PTD */
复制代码 ) I; W/ L, i: P' K! o, K) E: ` i
变量定义: - /* USER CODE BEGIN 0 */+ e4 }* I6 L I
- uint8_t i;
1 S+ s' m: k0 @" h6 ~ - uint16_t adcBuf[3];//存放ADC
' q7 P3 b& B. t+ g - /* USER CODE END 0 */
复制代码
* _+ y- f% G. @ 主循环: - /* USER CODE BEGIN WHILE */, W" _/ l9 B: m/ S: K
- while (1)
( ~+ P$ s/ m7 @/ d6 `! F1 C' y; Z - {
G) f' z' n8 {# C5 ^: Y. x - /* USER CODE END WHILE */7 ~* d; G' ~' r1 y
- & h6 E; j/ S7 K# b" i9 v
- /* USER CODE BEGIN 3 */
. V \7 a4 C" o% B4 z+ n) o% p& _ - i=0;
5 H* i" {+ g2 D9 N- M, G - while(i<3)0 S8 O4 A0 N' }# l
- {: l5 n" @& V* S& p- T/ E. O
- HAL_ADC_Start(&hadc);//启动ADC9 m* U. T& b7 `' x: Y! f
- HAL_ADC_PollForConversion(&hadc,0xffff);//表示等待转换完成,第二个参数表示超时时间,单位ms.& d% a6 ^3 a1 j4 L9 v' L
- //HAL_ADC_GetState(&hadc1)为换取ADC状态,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用。
9 K4 j( h' K- j4 c1 q( T* W - if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc),HAL_ADC_STATE_REG_EOC))//就是判断转换完成标志位是否设置,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用
8 _7 O* h" J/ Z7 e7 v9 X - {
6 f/ F* C" j: |! }3 N - //读取ADC转换数据,数据为12位。查看数据手册可知,寄存器为16位存储转换数据,数据右对齐,则转换的数据范围为0~2^12-1,即0~4095.
+ h7 B: L; \1 D2 | - adcBuf[i]=HAL_ADC_GetValue(&hadc);
% O/ s# A# @* L; T7 E, W k) e4 @ - printf("\nadc%d=%4.0d,电压=%1.4f",i,adcBuf[i],adcBuf[i]*3.3f/4096);# Q! t: {+ F: ^2 F. o3 e
- i++;
: T' o: X$ v) B# M: u* M2 c - }
3 _3 h- J0 L6 l+ i1 T - }
8 F. ~3 u3 P, z9 h7 V - ! i" J3 w2 {. x
- HAL_ADC_Stop(&hadc);
0 I" b0 S; \9 Q/ g2 Z) A" x - HAL_Delay(500); ' _: S4 o, S* p
- }
+ w$ l/ |% Q' M - /* USER CODE END 3 */
复制代码 : l# y1 G) l/ _) u+ D: G
6 X) S! N# O( h% S" s: y
演示效果 设定adc0口接3.3V,adc1口接GND,adc3口接1.5V,输出如下。) `. [ D& B4 v0 e7 Y0 t0 t1 \% \
0 T; @4 [, P; c. p! q* {
& Q* m9 |9 N& g0 ]
+ z8 a# G% S3 }9 _. O8 @9 S/ V' B$ ` F
, {9 v# J5 h: w% `& ~, H" p
|