G0的介绍) ~. D$ |& T+ n7 h& _+ [
G0是ST新推出的系列,我手上的是ST官方送出的STM32G070RB-NUCLEO板,在峰会上有幸获得。拿到这个板子的第一反应是觉得,它跟STM32F103RB长得好像啊,但一看原理图才发现,G0满满的IO口,IO的占用率高了好多.。
. D! H2 d0 `9 S5 H6 S, S1 A, z/ V/ B/ e! T+ F% {
& w' L' F$ J# l/ K: p
. Q$ f9 ?- p; r5 s
安装好STM32CubeMX之后,打开一看,IO的复用也很多,片上外设很丰富,对于普通的控制使用,完全没问题。内置有64K的ROM和128K的flash,对于跑一些UCOSIII 或者RT_Thread等RTOS毫无压力,当然了,emwin这种GUI就算了。官板上,板载STlink,可以很方便的下载,且带有串口,连接的是G0的USART2,使用A2,A3复用。板载一个用户LED和一个用户按键,还有一个复位按键。: L& \, c# L( X5 _. m; y
任何板子都从点灯开始/ A: Q/ g/ m9 A2 ^/ n* t5 A- |
/ |7 D$ M: U; I( y! A
开始建立项目并点亮第一个灯6 P1 r0 O9 o0 b/ r5 ]% l4 C2 B
通过配置STM32CubeMX,配置好时钟等外设之后,从原理图上,可以找到LD4接的是A5这个引脚。通过在STM32CubeMX上将该引脚配置为推挽输出模式,点解生成代码即可。STM32CubeMX使用的是HAL库,所以要让LD4交替闪烁,我们使用HAL库上的API) [1 H8 `- s, @; [2 C7 r
0 F: G4 s" F% e# W
使用这个API函数,再使用4 S1 Z3 A8 F- I* R) |
# a8 D3 {+ p8 V( P. V4 q( E则LD4可以以500MS的时间交替闪烁。而这整个过程,只要熟悉了STM32CubeMX,都可以很快建立好工程并实现控制效果。
2 t" R: c$ C1 M, b. ~6 L2 u; S7 B6 y$ B0 V' z2 L
配置ADC
y5 Z( N1 {6 P+ E5 _/ O通过STM32CubeMX,配置A1,A2两个管脚,复用为ADC功能。ADC的配置程序如下:( G( b: ~: K& k/ z) I: j
7 p. R3 h# G v% B9 ?& ?4 c- void adc1_init(void)
( S8 C) W* k. O/ j0 E* F. y- Y' \8 P - {' i; j: x, R C% H+ G+ h8 |
- GPIO_InitTypeDef GPIO_Init;
* j1 F7 b& G" h+ n0 m$ A - __HAL_RCC_GPIOA_CLK_ENABLE();2 f- U! V# Z7 H( G5 @- A
- __HAL_RCC_ADC_CLK_ENABLE(); //开启ADC时钟
: Q& H1 e6 d. O' v - P3 G% N' D( ? [! o% ^
- GPIO_Init.Pin = GPIO_PIN_0|GPIO_PIN_1;
' d' ~5 w1 [( ]. Q; s2 L - GPIO_Init.Mode = GPIO_MODE_ANALOG;6 v3 G( @4 Z* ~# E- o p) O6 u
- GPIO_Init.Pull = GPIO_NOPULL;& M$ M) D7 i& M) @& }; R. Q, I
- HAL_GPIO_Init(GPIOA, &GPIO_Init);( f. S/ c& m; S: u8 f
- 8 @( ]7 R8 X; V9 m+ l& ?; c/ H
- hadc1.Instance = ADC1; , T% @" f9 y7 E! s% Z* T! D$ x, V
- hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4分频 64/4= 16MHz
4 V7 f" G7 I2 V- U - hadc1.Init.Resolution = ADC_RESOLUTION_12B; //12位模式
# |& j: |7 {& U- o1 V - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
0 Q/ w& L( F+ W - hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; //ADC扫描模式 非
2 G# ~6 N) _5 Y2 J: j - hadc1.Init.EOCSelection = DISABLE; //关闭EOC中断% x5 }5 f6 X3 Y+ r3 L
- hadc1.Init.LowPowerAutoWait = DISABLE; //低功耗自动等待模式
, ~4 c% E2 ]6 ~ - hadc1.Init.LowPowerAutoPowerOff = DISABLE; //低功耗自动掉电模式% h! S8 g; p6 p$ _4 u3 L/ Y9 Y' X
- hadc1.Init.ContinuousConvMode = DISABLE; //关闭连续转换
4 |. H. Z& I/ w7 {9 B/ X7 @; d - hadc1.Init.NbrOfConversion = 2;1 t% `) L% P: w) D
- hadc1.Init.DiscontinuousConvMode = DISABLE;
. ?( w, q" C% ^; f# V+ S6 Z - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;9 \, y. @7 _7 V" m& u
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;, o1 r3 w$ N% l/ j" n6 ]$ r& |
- hadc1.Init.DMAContinuousRequests = DISABLE;
* t$ ~! L t3 O" \ - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
! U" ?; P: q# i4 E0 @# F/ n - hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;9 H: Z! h/ v, T9 U
- hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;6 `2 {5 J3 [; b+ a
- hadc1.Init.OversamplingMode = DISABLE;7 d, m1 z% E% w
- hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
) j, @: Z- p1 x3 R; N8 d2 p5 g$ m" @
! S% w+ \* E& |: H F: ^! U4 C- if (HAL_ADC_Init(&hadc1) != HAL_OK); W# K8 H4 b @* ~' c/ M' N
- {
. W/ M6 `: X% I* m - Error_Handler();6 [5 @( J. x8 @( Y: q; ?5 C
- }
, {( r# N3 U- ? D) Y: s+ ?, b - }
复制代码
# u5 a9 s5 T/ J9 g3 P! l而ADC的读取函数,另外编写,, d% L! { t# c, t2 j; T: [5 s% P6 x) m
" r& c& f5 V& w
- uint16_t ADC_GET(uint32_t adc_ch) " ?8 @: L- t2 E) z
- {
! \+ y1 A1 v& I. b - ADC_ChannelConfTypeDef sConfig;* o1 @% M" b" Y
}' g, L+ I0 W* f0 S% m- sConfig.Channel = adc_ch;0 P/ f, e( j( ~ z
- sConfig.Rank = ADC_REGULAR_RANK_1;
2 u5 y0 t" J: A" w: Q' G/ k: D" b - sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
; |: W9 c4 p$ s4 |8 @. W( @& s
: A, {( m: I* {- HAL_ADC_ConfigChannel(&hadc1, &sConfig);
l, l1 X2 B T7 o - 4 X8 a1 l- a& e5 L
- HAL_ADC_Start(&hadc1);" ?; u5 j0 Y( S. z
- HAL_ADC_PollForConversion(&hadc1,10);
. H% K; r& z5 Z% p6 q) q- I
$ a. g p* S* W- u8 }9 a$ z% f- return HAL_ADC_GetValue(&hadc1);
( F9 @6 P1 R5 a1 ]- B$ L0 k - }
复制代码
+ J$ T, E& Y, t
5 |9 C) A8 ?: B1 r6 x1 j最后讲程序烧写进去之后,将会发现一件很神奇的事情,
+ j, }+ |% @* }# z2 a8 g0 t7 r3 v% O* Y
' R! k. f! g, k& q$ H E ]
0 `% t1 _' x4 J* ]7 F! p7 y- N: j/ T( M! f5 r" y
会出现这样的情况。原因在于ADC初始化两个通道需要比较长的时间,而慢慢地会回归到正常值。在使用STM32F103ZET6的时候并没有出现这种情况。但是在STM32F429IG上也有过这种情况的出现,因此本虫认为G070RB的ADC功能并没有F1系列的好用。& n* y" r7 O0 d. p5 M! Q( W
! m5 q2 `! u- M4 z; B
, e( S. @7 f' ?8 m) J
|