G0的介绍6 b' o9 z! P1 P! {( T# G5 W3 D
G0是ST新推出的系列,我手上的是ST官方送出的STM32G070RB-NUCLEO板,在峰会上有幸获得。拿到这个板子的第一反应是觉得,它跟STM32F103RB长得好像啊,但一看原理图才发现,G0满满的IO口,IO的占用率高了好多.。
) K& | M5 ~1 W3 q
0 H" V, a6 \5 F$ I
! H2 o" `+ G% H X% J; h1 Q6 q' t: G& ^6 G# I' P" e0 Z
安装好STM32CubeMX之后,打开一看,IO的复用也很多,片上外设很丰富,对于普通的控制使用,完全没问题。内置有64K的ROM和128K的flash,对于跑一些UCOSIII 或者RT_Thread等RTOS毫无压力,当然了,emwin这种GUI就算了。官板上,板载STlink,可以很方便的下载,且带有串口,连接的是G0的USART2,使用A2,A3复用。板载一个用户LED和一个用户按键,还有一个复位按键。
6 v8 H* a8 Z4 s$ P9 ]. v8 R任何板子都从点灯开始# y4 n- R. c4 O& X' ~& z y: O
8 Q; Y7 y0 N; h8 V3 S6 h& ~
开始建立项目并点亮第一个灯+ @0 K6 y* ?; ^0 z" h
通过配置STM32CubeMX,配置好时钟等外设之后,从原理图上,可以找到LD4接的是A5这个引脚。通过在STM32CubeMX上将该引脚配置为推挽输出模式,点解生成代码即可。STM32CubeMX使用的是HAL库,所以要让LD4交替闪烁,我们使用HAL库上的API
" G6 d, p# P6 `' s7 M' j! X/ ?" I3 i* }; V* S
使用这个API函数,再使用
- e8 y! Y3 R! J% ]则LD4可以以500MS的时间交替闪烁。而这整个过程,只要熟悉了STM32CubeMX,都可以很快建立好工程并实现控制效果。
7 w0 G6 E2 P6 n0 w8 H# D1 i, Z" d0 N# {; B+ h9 M& x3 ?5 s0 g
配置ADC
( Q2 o4 `# V6 z! T通过STM32CubeMX,配置A1,A2两个管脚,复用为ADC功能。ADC的配置程序如下:
* T- ~" i2 m; G. p7 }9 @
/ v1 h( i+ q) T, P& N- void adc1_init(void) 7 p8 f h9 d( T
- {! T3 b1 U: n0 m9 g
- GPIO_InitTypeDef GPIO_Init;
3 [2 }! R/ V/ V$ |; X" v1 ]) T% \5 L - __HAL_RCC_GPIOA_CLK_ENABLE();
3 M. U6 v& G- p* j3 q; r8 G) T, f, W - __HAL_RCC_ADC_CLK_ENABLE(); //开启ADC时钟
) o7 ~; y6 W4 y; ~+ \
9 s' V/ o" D- L- l8 W& j- GPIO_Init.Pin = GPIO_PIN_0|GPIO_PIN_1;
3 l0 c; U/ v) T0 k. s - GPIO_Init.Mode = GPIO_MODE_ANALOG; ?. T. v$ {# @' l! l4 p! b/ m7 o" ?
- GPIO_Init.Pull = GPIO_NOPULL;
/ Y( K- O- n( q) a2 z: F$ U1 t8 m+ e - HAL_GPIO_Init(GPIOA, &GPIO_Init);" A4 Q8 o. O: G" N% t! J
- - H$ t# X. ~9 D- \. ^ y
- hadc1.Instance = ADC1; & V: z+ M# k6 v- F7 {) u! X/ o: n6 K: O
- hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4分频 64/4= 16MHz/ w; I+ p7 Y. x- F7 \
- hadc1.Init.Resolution = ADC_RESOLUTION_12B; //12位模式6 e3 V& X! V, x* G& z p' U
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
; V5 }* Q& y+ P$ }, F, h( j - hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; //ADC扫描模式 非
0 e7 L, x" Q6 q - hadc1.Init.EOCSelection = DISABLE; //关闭EOC中断. V- W: C' S* b
- hadc1.Init.LowPowerAutoWait = DISABLE; //低功耗自动等待模式
2 s7 g/ R3 }* ]1 o - hadc1.Init.LowPowerAutoPowerOff = DISABLE; //低功耗自动掉电模式& U: C: B4 k5 b2 }7 Z" c- B `" ]0 y
- hadc1.Init.ContinuousConvMode = DISABLE; //关闭连续转换( T/ @4 n, M5 P
- hadc1.Init.NbrOfConversion = 2;9 [$ B3 |& p0 _2 A% W) H% U9 G
- hadc1.Init.DiscontinuousConvMode = DISABLE;
4 w+ N. f* @# m; e# W - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
# W; s8 X. [5 m5 e, B5 t - hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;" E: h! O+ Y& X- S1 K8 A' a
- hadc1.Init.DMAContinuousRequests = DISABLE;
% ~/ _8 O9 r- i' b7 \% l! n - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;# S- _3 A' r6 v# a4 Y& D
- hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
& o& s u% O( }# M% W - hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;
# u: N3 R/ p @+ N - hadc1.Init.OversamplingMode = DISABLE;
$ v1 Q) P/ O4 m+ _ - hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
0 R$ S& V2 H) c/ Y3 P/ U J - - { d- C# N$ S
- if (HAL_ADC_Init(&hadc1) != HAL_OK)
( k$ |3 Z3 Y+ H( x# X p - {
& j9 A. ~& R0 N6 u& {1 R, C - Error_Handler();# c% y) R6 I6 o& x: h, S
- }
复制代码
( w7 ]: V" q( E/ O1 a而ADC的读取函数,另外编写,7 N* `0 j/ C" I) O4 l' {- A# u2 V0 `
. l2 \# O4 J+ A9 h
- uint16_t ADC_GET(uint32_t adc_ch) . ]: O2 j1 N' q5 T0 Z
- {% y H: G: H Z: a0 O/ |: W8 k |
- ADC_ChannelConfTypeDef sConfig;
& }) C2 p- K1 {7 f) m - * S/ y8 N3 |+ Q$ L9 F
- sConfig.Channel = adc_ch;3 ]8 t4 }0 q( m* X V$ E" g9 K. @* e
- sConfig.Rank = ADC_REGULAR_RANK_1;3 I y" g" ~* n" b
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;! [1 F2 b0 y4 C
7 d; o n; E( M" e( o- HAL_ADC_ConfigChannel(&hadc1, &sConfig);
9 B V. f9 P% ~2 e, H3 v- t - 8 \9 ]) Y5 F. g- S, o0 J! i
- HAL_ADC_Start(&hadc1);! ^+ Y4 A; k. `- K
- HAL_ADC_PollForConversion(&hadc1,10);
" B. a* e; c! ?, L3 r, s- U1 U
( N9 V* ^; v3 }6 b" h" y- return HAL_ADC_GetValue(&hadc1);) Z6 Z1 B2 o& P+ k/ n6 H! P) I, f7 |) ]
- }
复制代码
' y- z7 A3 }8 \- a9 e! S. u最后讲程序烧写进去之后,将会发现一件很神奇的事情,6 m. E6 v( O9 A" k
/ o' {; \# t7 ^$ P
会出现这样的情况。原因在于ADC初始化两个通道需要比较长的时间,而慢慢地会回归到正常值。在使用STM32F103ZET6的时候并没有出现这种情况。但是在STM32F429IG上也有过这种情况的出现,因此本虫认为G070RB的ADC功能并没有F1系列的好用。! ^4 d" T4 T u
9 Z p& d9 \9 r* v" m% Y. e# n
* S, Z5 d7 `8 R8 U" _8 | `! L |