|
概述 本章通过使用模数转换器(ADC),通过轮询方式采集多个ADC通道电压。
% \& i& Z$ w/ E! N" ~硬件准备 首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:
6 s: D5 O* p* Z- ^3 H 1 }. x" e: J8 G) h1 _
- k$ P7 T3 [& C/ m$ f4 R4 K选择芯片型号 使用STM32CUBEMX选择芯片stm32f030r8,如下所示:
$ D8 ]% q! a: o2 g/ Y( O. }
3 ~/ a& E4 B" m& F 配置时钟源 HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:/ F2 B" j7 F) ^* j3 C3 W4 c3 F
1 o( T, N" ]1 _& j+ o* r$ I# k1 z. ?6 i! j3 k
配置时钟树 STM32F0的最高主频到48M,所以配置48即可:- Q$ k8 B2 @4 o/ Z5 D$ c
! n9 r; J# J2 b, u. V
, \1 y5 \# x J: M: u串口配置 本次实验使用的串口1进行串口通信,波特率配置为115200。
: k# Q5 E4 j$ I& ~
% ^2 G2 |4 z5 l2 M+ m3 b
$ U/ i5 l. V5 v6 j
1 V5 [; k' f, j6 q; }& g; \# bADC配置 STM32f030中,有一个ADC(模拟/数字转换器),每个 ADC 有 12 位、 10 位、 8 位和 6 位可选,每个ADC有16个外部通道、2个内部通道和一个VBAT 通道的信号。 本文将开ADC的IN0、IN1、IN15一共三个通道,来分别读取ADC,由于串口2和IN2,IN3复用,故不使用IN2、IN3。配置如下:
1 ]/ \6 i0 i$ _/ m4 h5 f 生成工程设置 注意在生产工程设置中不能出现中文,不然会报错。8 H. M) A" q! N f b
+ N4 ~, b+ y3 p$ G% H$ y3 z
* S& H5 y7 l! v2 i' V' h 生成代码
) v* T. j6 X2 D% W
& \8 A9 R) i# ?) u' K2 m/ o3 |3 i1 ]! e2 X% [! `
配置keil
1 b! a, Y0 i% ^: ]( A. c2 v- X3 n: J7 ~- p
# L) J; ^% R; S0 S0 m7 I 在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。 - /* USER CODE BEGIN Includes */
" n/ _1 L* Z+ Q6 B - #include "stdio.h"
3 ]2 C: b' D" s3 d3 ` - /* USER CODE END Includes */
复制代码 0 q5 @( o. ]* h1 m
函数声明和串口重定向: - /* USER CODE BEGIN PTD */0 P W0 Y3 o5 `1 h" G
- #ifdef __GNUC__
* s/ J7 R9 `. ^" T' a - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)9 \9 u! d K5 Q# A
- #else9 M7 |- D6 h0 `, C/ F
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)/ h, ~9 A7 E. T4 m6 ^9 l
- #endif /* __GNUC__ */
! W' U; P- a; K" @; E7 I1 d
5 F9 @3 m2 `. d- 2 f r: I% s- e
- PUTCHAR_PROTOTYPE" b) j6 N1 |2 O# G6 L# R8 A
- {6 k8 K' v( Z# ?5 e" v
- HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
3 Q- F; }4 h% U) q5 p - return ch;4 s2 r6 C: O* P3 K9 O k
- }3 O. ^: E, k( e. P
- /* USER CODE END PTD */
复制代码 3 v4 [4 o; A3 x2 b* d2 T, A
变量定义: - /* USER CODE BEGIN 0 */; ^3 {* d( q: ]8 ~( i6 h
- uint8_t i;: m4 T& _$ N3 K7 ~1 A3 k
- uint16_t adcBuf[3];//存放ADC
1 d/ s# G0 G0 }7 h9 t( B0 y - /* USER CODE END 0 */
复制代码
7 ?# B# n. l) q, R. s 主循环: - /* USER CODE BEGIN WHILE */0 ~5 V5 \$ ] R: X& t( M4 L- J
- while (1)
* r9 \- V# A" u - {1 t; y; ^9 m+ O7 c- g' m+ ] E
- /* USER CODE END WHILE */
* r( u8 [! d0 h' @+ F - ; t! \& c( c8 k5 U, m
- /* USER CODE BEGIN 3 */
& U8 L3 k. v/ A+ g0 H) z6 r - i=0;
$ p! M. a# ?. v - while(i<3)
6 S" _1 L; f/ V/ `8 |" _ - {
* u7 x' u4 t/ V3 G - HAL_ADC_Start(&hadc);//启动ADC
/ q3 @) y% |, S7 b - HAL_ADC_PollForConversion(&hadc,0xffff);//表示等待转换完成,第二个参数表示超时时间,单位ms.' N' L) G+ x. D+ p5 b
- //HAL_ADC_GetState(&hadc1)为换取ADC状态,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用。
) p A: l# s, A6 C - if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc),HAL_ADC_STATE_REG_EOC))//就是判断转换完成标志位是否设置,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用8 Z' N9 Z3 h/ E( k0 W `; o9 X! b0 V) A
- {
1 O8 }! Z9 o0 t; V - //读取ADC转换数据,数据为12位。查看数据手册可知,寄存器为16位存储转换数据,数据右对齐,则转换的数据范围为0~2^12-1,即0~4095.
9 R0 `+ x7 u f/ C( ~- Z - adcBuf[i]=HAL_ADC_GetValue(&hadc);
9 U3 O* X, I2 H9 X9 Y( D" g2 u# } - printf("\nadc%d=%4.0d,电压=%1.4f",i,adcBuf[i],adcBuf[i]*3.3f/4096);
. L/ _4 H! z' K - i++;! S! x( v; g; f5 O+ ~4 y T
- }+ i5 M- d) z: k- m
- }
! X) M: g5 ?" c, t
- B) c- T( E9 }7 u( p. p& ^. t2 l- HAL_ADC_Stop(&hadc);! L* D, l. k Q. G9 O- f
- HAL_Delay(500); 8 Z4 ?& a7 w x8 j. S# C0 }2 K1 ^8 ^
- }$ B- v5 e" D& P; @" t9 [
- /* USER CODE END 3 */
复制代码
" ]; o% Y* J, x7 Q0 x2 s" F8 A+ a, A/ M
演示效果 设定adc0口接3.3V,adc1口接GND,adc3口接1.5V,输出如下。( z) r L, j) K7 X, j3 q; O. n
' R5 A! i! V8 u1 c2 R' ]2 \$ Z1 p- H, w
7 D% p* \0 M; g, M, q; v, h, o 6 h0 }) k, S% q% t* G; k3 j
$ E' y" ^) i7 t& l0 w- x6 z4 O5 X5 r% m' F; j$ k
|