几乎每个嵌入式应用程序中都使用的一个常见功能是 ADC 模块(模数转换器)。这些模数转换器可以从温度传感器、倾斜传感器、电流传感器、弯曲传感器等模拟传感器读取电压。现在,我们学习 如何使用 STM32F103C8 中的 ADC 读取模拟电压,我们将一个电位器连接到 STM32 Blue Pill 板,通过改变电位器阻值为ADC提供不同的电压,将读取的电压显示在 1602 LCD 上。2 D0 T+ R$ \* M1 m, U4 e
' m0 u& g. F# r0 I1 JSTM32F103C8 中的 ADC
+ `2 a, j! p6 ?/ y2 R5 i在 STM32F103C8有 10 个通道、12 位 ADC,输入范围为 0V -3.3V。它将 0 到 3.3 伏之间的输入电压映射为 0 到 4095 之间的整数值。
! a/ o- A, U! A/ }; J* @' s! K# H: |$ m2 r. U
这里的术语 10 通道意味着有 10 个 ADC 引脚可以用来测量模拟电压。术语 12 位表示ADC 的分辨率,表示000000000000-111111111111(2^12即 4096)。这是我们 ADC 的采样步数,因此我们的 ADC 值的范围从 0 到 4095。该值将从 0 增加到4095基于每步电压值,可通过方面方式计算
W% j# U5 y1 H7 @7 ?" d
9 E! v" P& R- R, W2 a( H电压 / 步数 = 参考电压 / 4096 = (3.3/4096= 8.056mV) 每单位。$ Z, a2 N, F& c, P. ]2 ?( P
! p; |5 S; R4 B! N. H1 D: A' o
模拟信号如何转换为数字格式
3 c" \) u' U: U- ^) P& R5 R% m/ ]由于计算机仅存储和处理二进制/数字值(1 和 0)。因此,模拟信号(如传感器的伏特输出)必须转换为数字值以进行处理,并且转换需要准确。当在模拟输入端向 STM32 提供输入模拟电压时,模拟值被读取并存储在整数变量中. 使用以下方式将存储的模拟值(0-3.3V)转换为整数值(0-4096):, k9 C* ?1 H- w5 ~( ?
- J) r- ?0 g0 h$ D# C输入电压 = (ADC 值 / ADC 分辨率) * 参考电压( S" ?5 m8 o' r: U: t6 w6 `
7 R4 r# ]& F: _& z$ _分辨率 = 4096
/ K' h* m# G, f
& n K" r: p% }$ ^参考电压 = 3.3V
% d) b7 g$ ~3 r0 S( x' s1 Z3 M g$ s! t& R: \. C8 y
STM32F103C8T6 中的 ADC 引脚
) r, u8 d7 B: Z7 {6 M; |+ E VSTM32 中有 10 个ADC引脚,从 PA0 到 PB1。
6 F* k: u% z- f! F, @; Q3 M; f/ q" }( L$ N0 u
" t) O1 w& O; o' f* R
' D6 S+ z1 _; O& e0 b电路图及说明
7 L @) F8 ?( N. m! _
/ r2 K- s; g: f+ \4 X
- C. w! x0 |# V7 ]
% X$ Y; ~- v$ `# Z2 c- U, R) a2 S* l6 }1 @# G' T
LCD与STM32连接
# X, Z' N; L% R+ H: l" t! q5 V) O$ w0 T. w- c
' _5 j, X# {+ \ l/ p
" p: e, y7 ]# ^1602 LCD根据上表进行连接。电路中有两个电位器,第一个用于分压器,用于改变电压并为 STM32 提供模拟输入。该电位器的左侧引脚从 STM32(3.3V)获得输入正电压,右侧引脚接地,电位器的中心引脚连接到 STM32 的模拟输入引脚(PA7)。另一个电位器用于改变 LCD 显示屏的对比度。STM32 的电源由 PC的 USB 电源提供。. Q; W" h1 [6 s* |5 d" G$ i" Q
: N* d6 E8 x6 ?- F9 H( X6 o
4 G, {( J0 L/ `! P7 b4 K! r6 d% v, K( d% p
对 STM32 进行编程以读取 ADC 值% E. C+ Y$ W- C" k" q8 f# s
通过 STM32 的 USB 端口将其连接到 PC 并开始使用 ARDUINO IDE 进行编程。在程序中,读取模拟值并使用该值计算电压,然后在 LCD 屏幕上显示模拟值和数字值。
o' k2 G9 A: y+ N. @- a" {- d
' V( A9 G9 X+ d' G5 k: ^- #include <LiquidCrystal.h> // LCD 库3 d$ v5 g5 ?) `- V
- //首先 定义出 LCD 引脚。这些定义了 LCD 引脚连接到 STM32 的哪个引脚。. M% D- \7 @! L( y H# {
- //你可以根据自己的需求进行修改。6 \% w# i( p' ?% F$ j. O u2 ], h
- const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14;2 e; @, R9 w7 M% U0 {8 g9 u
- LiquidCrystal lcd(rs, en, d4, d5, d6, d7); //初始化LCD% b. e! B% \& x( L4 M
- const int analogip = PA7;//模拟输入引脚/ {& `. X! V0 @+ u- S
- void setup()4 x( z9 _& ?5 `% q: W
- {% ~- b4 }+ g/ k* d$ v
- lcd.begin(16, 2); //我们使用的是 16*2 LCD1 K% S$ X; y# v
- lcd.clear(); //清屏/ b7 M0 s+ n( |2 q( s
- lcd.setCursor(0, 0); //设置光标在第一行第一列
/ H6 P: j+ ]) b3 C" o - lcd.print("Hello Wrold!"); //LCD显示这个
, t. Q/ K% G/ a7 V - lcd.setCursor(0, 1); //设置光标在第二行第一列
' F9 [2 Y; y- j# c7 u. W' ?+ H - lcd.print("STM32F103C8"); //LCD显示这个
' u8 p5 `5 I5 N. |+ n7 f - delay(2000);//等待两秒
" y$ r8 G. }# E) i2 c - lcd.clear(); //清屏
3 ?1 r) F0 b* N A2 B5 s - lcd.setCursor(0, 0); //设置光标在第一行第一列: R. l9 [9 _: N1 b
- lcd.print("USING ADC IN");//打印这个. V) Y& d. X* Q9 U( D, P8 |
- lcd.setCursor(0,1); //设置光标在第二行第一列6 E7 g. x' ?, c w
- lcd.print("STM32F103C8");//打印这个
* P0 m* I3 j, r: ]9 ~* Y2 { - delay(2000); //等待两秒- x' f3 A3 G7 ^
- lcd.clear(); //清屏
+ |7 E- C `' I& y- M - }
( s- i+ K6 Q2 G, \& t
* H& u) ]7 a+ o: P( h e* L% U- void loop()+ g5 g) \( Q* G( h
- {' s, t- O r4 F$ `5 _" _
- int val = analogRead(PA7); // 从引脚 A7 读取 ADC 值, o' m" @2 q5 O4 p" R5 M
- float voltage = (float(val)/4096) * 3.3; //将 ADC 值转换为电压值# ]+ g4 ` m9 j( @" E: _
- lcd.setCursor(0, 0); // 将光标设置到第 0 列第 0 行5 t" V0 {+ z, ~
- lcd.print("ADC Val:");
0 d& U0 M9 M* k - lcd.print(val); //显示ADC值
; I8 i1 a, U$ S - lcd.setCursor(0, 1); // 将光标设置到第 0 列第 1 行: z: g. ?0 O/ p$ W" u7 m
- lcd.print("Voltage:");' R$ b2 \1 A5 u( b9 E- x3 o
- lcd.print(voltage);//显示电压2 b9 h6 j* G) H
- % V/ v# }8 R* O/ E4 ]
- + e/ f% ~& t$ W0 f8 y. s; w
复制代码
: a; L3 J$ y9 ^* L& ?9 P: s |