G0的介绍
6 h/ R+ ^' n( Q* {/ Y+ sG0是ST新推出的系列,我手上的是ST官方送出的STM32G070RB-NUCLEO板,在峰会上有幸获得。拿到这个板子的第一反应是觉得,它跟STM32F103RB长得好像啊,但一看原理图才发现,G0满满的IO口,IO的占用率高了好多.。
# y. r5 V! }& Q# c4 x! n( e1 Y" A2 s7 t
. j4 `2 H( A6 r. d& j4 \2 k7 K2 a; T
* I! c$ e o1 l安装好STM32CubeMX之后,打开一看,IO的复用也很多,片上外设很丰富,对于普通的控制使用,完全没问题。内置有64K的ROM和128K的flash,对于跑一些UCOSIII 或者RT_Thread等RTOS毫无压力,当然了,emwin这种GUI就算了。官板上,板载STlink,可以很方便的下载,且带有串口,连接的是G0的USART2,使用A2,A3复用。板载一个用户LED和一个用户按键,还有一个复位按键。/ Q: @9 s/ O5 `0 X# d
任何板子都从点灯开始
% [2 L* ]. N. }2 ]; c( o
9 {+ u% t" d8 ~7 N% h开始建立项目并点亮第一个灯4 }! Q+ d1 X C7 \: e
通过配置STM32CubeMX,配置好时钟等外设之后,从原理图上,可以找到LD4接的是A5这个引脚。通过在STM32CubeMX上将该引脚配置为推挽输出模式,点解生成代码即可。STM32CubeMX使用的是HAL库,所以要让LD4交替闪烁,我们使用HAL库上的API
% N0 E ]4 ~% }- z7 U9 V
" }. {6 B4 E9 d+ y% r4 g9 d K: P使用这个API函数,再使用( L7 E/ {2 w Y. Z# `
! ~6 M' |/ ~7 ^则LD4可以以500MS的时间交替闪烁。而这整个过程,只要熟悉了STM32CubeMX,都可以很快建立好工程并实现控制效果。! p$ i" N' {5 _$ ~- ^4 q0 \5 W
9 v- ?. A: h5 ^* s8 h2 B" ^配置ADC* Z3 R8 }" n1 y
通过STM32CubeMX,配置A1,A2两个管脚,复用为ADC功能。ADC的配置程序如下:+ ^0 H" D/ z! N% N1 s% ~0 B% \
0 Z @9 y- F8 H$ m) I. ~% _
- void adc1_init(void) ' L1 `; N, b( K1 z
- {
& ^$ K, _# r) g9 q: b+ Y0 n - GPIO_InitTypeDef GPIO_Init;
" y6 u( l. j0 [$ U8 \5 W - __HAL_RCC_GPIOA_CLK_ENABLE();
4 k+ ~* N* a F - __HAL_RCC_ADC_CLK_ENABLE(); //开启ADC时钟
- r. @2 q$ c4 f- u& A6 R - % {3 v7 D3 T# C! h/ [
- GPIO_Init.Pin = GPIO_PIN_0|GPIO_PIN_1; _9 V! M+ b+ _% ^% a
- GPIO_Init.Mode = GPIO_MODE_ANALOG;) }& o5 }. F, b6 b2 {2 W" p
- GPIO_Init.Pull = GPIO_NOPULL;
e+ J% M" r* b7 J7 y9 x - HAL_GPIO_Init(GPIOA, &GPIO_Init);
) J2 Y7 O: m; p! j5 e/ T ~. ]7 _ - * F) K7 A9 Y5 R8 p9 R" G% K
- hadc1.Instance = ADC1;
, x" l& @. |: Q% A; R. a5 n - hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4分频 64/4= 16MHz
* k1 i0 [% J3 q3 M - hadc1.Init.Resolution = ADC_RESOLUTION_12B; //12位模式
1 W. e6 ~. \4 L, G, v - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
7 D7 E: q5 k3 i2 y7 U6 M! K* ] - hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; //ADC扫描模式 非5 }3 M- b) ~% y2 ~. _! m- a
- hadc1.Init.EOCSelection = DISABLE; //关闭EOC中断( C0 F: c1 W3 o5 E
- hadc1.Init.LowPowerAutoWait = DISABLE; //低功耗自动等待模式
( Z% p* q0 @/ A! D - hadc1.Init.LowPowerAutoPowerOff = DISABLE; //低功耗自动掉电模式0 a3 ?+ z) k t
- hadc1.Init.ContinuousConvMode = DISABLE; //关闭连续转换
& \7 M D0 V' R7 T& y! Z" o - hadc1.Init.NbrOfConversion = 2;
) q# P5 g. S: S$ d! O - hadc1.Init.DiscontinuousConvMode = DISABLE;' D+ d" W# b7 M( Y
- hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;0 {5 L7 ?) T5 ]" O* e. P
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;5 W7 E4 W, Y; z. A1 D; F$ h
- hadc1.Init.DMAContinuousRequests = DISABLE;
$ G) ^1 |+ \& s, z" p! M - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
+ J" L$ U& U; h, A L - hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;% y. W+ E3 k. R! s) \
- hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;( l* B" \/ R8 @) F* b3 `
- hadc1.Init.OversamplingMode = DISABLE;
) I- r! g. A% M/ o' g* {# A/ d% r# ^) c: ] - hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;! C* R# ]0 V& w* Q2 s6 P
- & M" @/ s1 _# t6 U
- if (HAL_ADC_Init(&hadc1) != HAL_OK); e3 `+ Z3 T8 H8 l9 o R. t
- {
1 [; g }1 v, }( g5 g$ Q - Error_Handler();* W0 F1 Y6 O& V% A: Z/ f) S7 |" V
- }
V& i0 H0 k& S" d - }
复制代码 6 S4 g( N$ T: J) ~1 Q- l7 k
而ADC的读取函数,另外编写,0 K( P$ W& l, o$ F) f! N% Q
, j2 K4 a! k, q H; S( n( u! X0 J- uint16_t ADC_GET(uint32_t adc_ch) * B! P, [- B+ E" S. X6 ]0 s
- {. w+ ?. l) y- z3 S% j+ J
- ADC_ChannelConfTypeDef sConfig;6 |% I6 r, v$ I( I, Y
8 V) m2 T) A8 F8 H- n# p. A- sConfig.Channel = adc_ch;# Y |; m( G4 D9 u6 h1 T
- sConfig.Rank = ADC_REGULAR_RANK_1;: l \1 x& m) f2 k" g- A5 E: G% a
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
" u/ c! j: K3 l# O8 I% D z4 X
$ [; ? ~7 w8 k- HAL_ADC_ConfigChannel(&hadc1, &sConfig);5 A N( c& K5 m( c8 B* q1 i9 g7 K
8 ], X# _: V! [- HAL_ADC_Start(&hadc1);
' @+ t3 _5 B1 L" c1 G) R$ e: q - HAL_ADC_PollForConversion(&hadc1,10);
+ y& i. p9 W7 I
% P. T0 V6 A, b- return HAL_ADC_GetValue(&hadc1);; T$ J7 y" X, c8 H" @$ V+ [
- }
复制代码
1 o4 Y( y! n% [6 j. ?0 _! h- P# ]3 c$ O: ?* |- O. n
最后讲程序烧写进去之后,将会发现一件很神奇的事情,
- P$ }" a8 R- W% E a' y
2 B9 I( J m7 W( E6 W k, F
0 s) C" Z$ T/ G" ~6 s4 U) W5 h3 N: m' k6 i
会出现这样的情况。原因在于ADC初始化两个通道需要比较长的时间,而慢慢地会回归到正常值。在使用STM32F103ZET6的时候并没有出现这种情况。但是在STM32F429IG上也有过这种情况的出现,因此本虫认为G070RB的ADC功能并没有F1系列的好用。
+ m+ ?0 z) R. T! V# l k; L7 C
& _5 F3 D0 d4 ~& q: L Q. Z; e* ^' z6 _
|