最近为了学习HAL库和熟悉STM32CUBEIDE软件,用手上STM32F407板子做了小工程,里面包含有串口1,串口2的使用,定时器中断,EXTI,DAC输出,ADC的DMA读取和用SPI驱动的TFT彩屏显示。
* a2 `2 H7 b; ?8 Y2 _/ _# B先放一张工程做好的图吧
8 b# t, f4 `) v6 P) W" l+ ^
4 _# L9 h% R6 {9 _& z程序很简单,用CUBEMX初始化后,只需要自己写回调函数和主函数的部分,先看一下外设的CUBEMX初始化;
' K, \2 \3 E2 I2 ~/ E& A/ @(1)USART1和USART2
; D/ ]+ i" i/ l ' R5 G; A: C: l* `' l( {6 H" k

" b7 }% p, s3 U. w% y! P1 ^两个串口的初始化是一样的这是设置的NVIC中断不同,后面放出工程的NVIC配置。" {4 `; v( v' f4 G* e0 g
(2)TIM3: Y) w8 o8 ^$ g: J
1 a1 s* O, W, K; P: q
0 ?' I9 M) k" m: A
定时器的配置要多一点,但只用定时器则比较简单. ~ l1 E' m' \% @3 W
(3)ADC6% t6 [4 _' o! }; i% g

* t `4 r: ?* j
5 x: Z2 f* P! c, i$ R( X" } 2 R9 ]+ q r0 h3 O0 w
0 t! H u( P7 \/ Q7 w' G {
ADC的DMA读取设置! Q( L' o! `$ e
' G# u' d: l) f& d/ P
(4)DAC1) } Z- d% w- Z: k3 ?' N

: m- c i) b, J(5)SPI2( x8 ]; D) R$ g" F* q' N6 K

( I; g/ F1 c: n(6)EXTI
' w; F5 b& X, R 7 D2 J d6 F" @; Q/ V
(7)NVIC
; R* T3 z9 r# n1 y 0 k N; Y5 i/ q
(8)GPIO) n! A1 Q) X8 N3 N! l

7 `0 t6 i+ ^; L2 r' u5 b所有的外设初始化配置完成了;
/ H2 z" i2 ]! r) ~' J
' a; U1 ]0 M. s, N& x' D, p1 {$ r下面看一下中断相应的回调函数,在HAL库中,写中断处理函数和标准库不同,我个人认为现在只需要在回调函数里写内容就行了,我们看一下HAL库里面的IRQ函数,比如HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)- void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) X9 [" ?4 m! S1 Z$ Y
- {: K j3 Y- v/ c5 R j8 r( R" n4 p. P
- /* EXTI line interrupt detected */
E, a) X; c6 Y; E' l, N0 R - if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
: C! z+ X1 A) i% q. U% M - {
+ S% t7 U$ [ v g - __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
' Q& ?& Z" q1 t# e T) G( Q, Y. e - HAL_GPIO_EXTI_Callback(GPIO_Pin);
: {# f: {8 s) c, A) M; ^! X6 T - }- \, ]# ~7 |3 A
- }4 U8 A7 d; a9 T
- % D( Y; k) f# J6 H4 `: _
- /**
% Q) ~+ [+ d8 D/ s - * @brief EXTI line detection callbacks.
. s* c% |. n! k7 W - * @param GPIO_Pin Specifies the pins connected EXTI line# c+ q& A$ k9 J" Z% Z
- * @retval None
" a( N! B Y' v4 T: U8 l - */' U4 W4 w: N, V# I: _! k. a
- __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)& i5 ?2 K2 q8 |
- {5 S. Z. o1 J# C3 c; U: | [
- /* Prevent unused argument(s) compilation warning */0 U6 |/ |( A" h+ J5 O
- UNUSED(GPIO_Pin);$ a% m1 T* i9 y$ d
- /* NOTE: This function Should not be modified, when the callback is needed,: b, ]" y- s) p; \+ C
- the HAL_GPIO_EXTI_Callback could be implemented in the user file
0 Y& {) t4 B# U/ ] - */
5 r7 O2 s' m9 S( A: W: T; V& a - }
复制代码 HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)里面会调用 HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)函数,而 HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)是需要自己编写。( Z% M: H6 [' w. H) E
9 z C( M. |" K/ i(1)串口7 \ ?9 C8 R S2 H) @! X# L0 h: Y; c
( j! v' n5 J! o, p1 ]$ I5 v. y- uint8_t RX_buff[RX_len];8 A' g4 c' ]$ y# J4 G* Z
- uint8_t RX_temp=0;% f! o6 v* r! C% q' a
- uint8_t RX_i=0;
+ S7 w6 F1 u9 p9 O - uint8_t RX2_temp=0;& @1 i7 u9 k% R( H
/ a' e3 {3 w9 E# J' y a8 V$ z- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)) t' T6 [( P7 z/ B4 b8 J7 J' Y" R
- {
s2 g; d' G/ Y - // uint8_t buff[10];% |; S( Q* |; _) ~: C: J" c! B
- if(huart->Instance==USART1)3 M' A7 y+ O$ Z3 S' `
- {% O3 j5 R g- a ~" [, V% Q# q; [
- //HAL_UART_Transmit(&huart1, &RX_temp, 1, 1);
9 u/ s( i* s# e9 r2 g$ x1 U - if(RX_i>=RX_len)
* E! p6 Y: I1 d0 l - {
8 i1 D3 ?3 ^4 P, C; L - RX_i=0;# m4 c( O/ {% {. O. S/ K7 v
- HAL_UART_Transmit(&huart1, send_buff, sizeof(send_buff), 1);
" X- h1 O+ ?4 L( O - memset(RX_buff,0,sizeof(RX_buff));# U0 L6 I8 s% O5 {0 y* ~
- }8 h1 Q0 ^; k! B) ^1 w8 s3 K
- else0 { a3 a5 `9 n" A; h
- {
. d; \7 t( h1 _6 K$ i - RX_buff[RX_i++]=RX_temp;
' V( T( A) A+ T( S% k$ g - if((RX_buff[RX_i-1]=='\n')||(RX_buff[RX_i-2]=='\r'))
! U0 s6 j: Q: g4 q - {
$ ~5 ?0 b' q: N# E4 b) M8 m5 \ - HAL_UART_Transmit(&huart1, RX_buff, strlen(RX_buff), 10);//Timeout 不能太小,也不能太长
2 X6 u7 A9 P2 D ] [4 b3 X0 ` - memset(RX_buff,0,sizeof(RX_buff));: J7 X) _) p2 K6 T0 F
- RX_i=0;$ E. w' h- o. i% U$ e
- }5 G/ ~* _, S7 f- n" P# e
- }
" O; H5 g2 K" ]! ~* H - HAL_UART_Receive_IT(&huart1, &RX_temp, 1);/ r6 T" T1 S- g$ e
- }0 C* N, U# C7 r* q9 J5 f# ~
- ; K- m2 m! o% }/ ]) e
- if(huart->Instance==USART2)
1 y5 U2 O& q% r& O7 p - {
. P/ I. k9 F: [% A* d - HAL_UART_Transmit(&huart2, &RX2_temp, 1, 10);% K# W4 q# R3 g
- HAL_UART_Receive_IT(&huart2, &RX2_temp, 1);
" Y8 s; r9 U$ {: j - }
- {. q9 V/ V- @) k8 P - }
复制代码 (2)TIM3定时器中断
2 g& G/ O i2 a! U. _- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
8 P! o4 h- x1 o0 L( h" O$ V - {
$ t5 W0 {+ j3 b$ f6 { - if(htim->Instance=htim3.Instance)2 P9 r& f) D( m! n G9 |
- {
, P7 Z( g& I0 H, a+ A' b7 Y7 k% P0 t - HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);; `* X8 [" B& c6 a9 o. y
- }
! o3 z- ?6 l$ c7 G% a$ ^9 C - }
复制代码 (3)EXTI中断
1 p( i. ? D" j& k6 E8 x9 Q- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)0 q! a% F. D+ I9 M" c$ m
- {" @$ ]& L/ }& B/ J
- HAL_Delay(100);) A% K# Q9 f3 D' k! `+ Z
- 5 p; A8 }6 K. e; n; _, i: C6 k5 b( R
- switch(GPIO_Pin)
9 S2 L: T6 c$ L+ a$ B. [0 |( T - {+ | H! Y+ V4 i% j) h* [" u
- case WK_UP_Pin:
+ \7 o. P/ m' q( v7 Z0 ]) [ - if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) == 1): Q) p% ^* L [& f
- {* B8 f( B- t; h) v
- HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
2 ?# s5 `2 H& F. e* B' c& a1 Q - DAC_Value=3299;. s5 H7 C8 {) q
- }
% K! a1 M7 ?9 U! h# z! m0 _) N - break;- D9 J `. C# l& e
- " y/ N I! }: E: L; v0 q+ N
- case GPIO_PIN_2:4 Y7 O, E% B/ W; M4 q6 B# Q
- if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == 0)! u% K0 N$ Z* Y# T3 U/ f
- {4 r$ z$ p7 h: w$ X
- HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);& g7 s; z/ ?4 V
- if(DAC_Value<3200) DAC_Value+=100;
. F8 @9 B& X4 D, C8 T- l - 0 b+ F! ^+ P. c& H& w3 F7 ?1 I/ r6 \
- }. b P& ?0 m6 C/ o; P! e! s2 C& t! _( f
- break;
2 u" a( M$ D( n( f
4 a* k/ c- m, b7 |& Z2 ~; p- case GPIO_PIN_3:
7 h- S8 c0 R; s( K D. J( k - if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3) == 0)
# L4 Y+ p3 Z, q# o0 G* S - {
( m9 F0 _- ^+ |& Z - HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin); a/ P8 z+ z8 W9 L0 d
- if(DAC_Value>=100) DAC_Value-=100;
7 V4 h. T/ z4 [ - }
; l4 C( M U. B/ y1 ` b - break;- O; r: v0 U% I/ R9 f; Z2 c
# S. T( u* @( x1 w( g- case GPIO_PIN_4:
" S7 H& R8 x; m4 y - if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) == 0)
7 `! q! [- V2 }; X' \ - {
$ m) e C; E* \5 V( i - HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);; T1 b' D8 P0 @6 @! A
- DAC_Value=0;9 w& _; Y4 u- a3 C& e/ ~
- }. B& u. z ^0 [1 |! m' h
- break;
- b0 Y* r! k1 P) r7 r4 G - }7 F, E( t# r5 {. ?3 w
- }
复制代码 再看一下用SPI往LCD里面写数据的程序
) k$ Y5 P+ W4 o% V; `4 N0 P- uint8_t SPI_WriteByte(uint8_t Byte)* j: r7 b3 e% S
- {/ m" t9 G! o: e7 l& P
- HAL_SPI_Transmit(&hspi2, &Byte, sizeof(Byte), 10);
" T$ }5 Y) Q7 {& Z, L - }
复制代码 下面看一下主函数
, S! G& }- j7 W g; c- int main(void)
" j. A3 D! n8 V4 n1 X- I - {5 V8 c( O8 ]- }& S3 k
- /* USER CODE BEGIN 1 */3 C0 _/ } W, D L
- uint8_t buff[50];: e6 }; ]7 ?5 s
- 8 {& S. B) P) E8 R
- /* USER CODE END 1 */ k$ g8 t/ F% z' F) L9 P) X$ i
- 2 r# d- H) F6 c4 u# S
' X# j0 v ]+ A3 C- /* MCU Configuration--------------------------------------------------------*/
3 U6 o( u7 N+ _ k8 o" O
6 e; e( S5 t3 T% a5 x# e1 H8 }- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */- g2 S+ k& r* ^& ?( u, S
- HAL_Init();' G/ { z1 G( W' _, ~8 t
9 I: K: I* t F1 ?4 F- /* USER CODE BEGIN Init */4 d! F2 a, D# }) I' c
- 0 N4 i2 J1 V. {
- /* USER CODE END Init */, ^2 V6 i2 \ O# g& M! X
- 5 t7 I; d# C/ E2 N, v* @" e6 @
- /* Configure the system clock */! a, A: ~2 I O& J/ ]2 o
- SystemClock_Config();5 j' p# | x6 ^7 R
& E3 L {4 F [1 S( J- /* USER CODE BEGIN SysInit */
- \: u1 h/ i8 @0 Q. N( r - : @# z9 U' q/ |1 Z2 J( e
- /* USER CODE END SysInit */
! I! O; E* T) [% D' W% ^ - $ C I( {% G0 `+ d* X/ P" x
- /* Initialize all configured peripherals */, C' S' J/ T) K6 {. P( G% Y8 r( ^
- MX_GPIO_Init();0 S5 R }( x, G2 R+ M
- MX_DMA_Init();
( N' ]: k y+ Y4 E6 o0 } - MX_USART1_UART_Init();
$ Z$ [% Y2 e& u& R6 D - MX_TIM3_Init();# q/ }* m$ G- \
- MX_ADC1_Init();! q, _- @, F5 U' R [9 B: R& z
- MX_DAC_Init();
! r/ _. M2 D5 Y) H1 A8 A, ~4 L - MX_SPI2_Init();* o4 j9 k! g' u0 F% L( v8 L
- MX_USART2_UART_Init();
" |) z' }/ @1 D8 A2 `# e" J - /* USER CODE BEGIN 2 */& S2 X5 j9 U* A
/ k! P" V1 ~, O! j- K" X- LCD_Init();: V9 V3 @, i( s
- POINT_COLOR=RED;& m3 e& ?3 X! f
- LCD_ShowString(10, 50, 16, "Welcome come to My world",0);
- B6 c* F9 i' f% R' c* W0 n - 6 D% [; |5 A5 S5 Y
- //LCD_BL_SET;
# A8 Z2 S1 {* _; |, d9 Y! b$ ` - memset(RX_buff,0,RX_len);
! l2 ]" x1 g' A$ I5 \5 B. h - HAL_UART_Receive_IT(&huart1, &RX_temp, 1); N9 N; J, Z; e. V, X# @2 E& Y
- HAL_UART_Receive_IT(&huart2, &RX2_temp, 1);" I* x- P' W( e v, @. R1 M
2 z2 {/ E& W4 l4 k1 |- HAL_TIM_Base_Start_IT(&htim3);
/ K, [! \7 k% [* Q5 s" S
; U! J3 H- Y/ H" L- HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
4 J$ `- [- L$ h/ m+ U - HAL_ADC_Start_DMA(&hadc1, ADC_val, ADC_length);- R4 W; e2 W! W9 s2 @3 ?
1 |$ \5 k. L7 @! n0 d: ~" q6 S# c- //HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0x100);+ ]# H8 n5 y" q q$ ^/ i8 T% y. g
- DAC1_Set_Vol(DAC_Value);- F2 X* a. `8 z3 d3 w
- /* USER CODE END 2 */0 Y' [' l7 h; e& V" a6 _
" c9 B* k. @/ a- /* Infinite loop */
! u3 }0 K5 \* A - /* USER CODE BEGIN WHILE */% J3 R: @/ ?+ w% k
- while (1)
$ i5 X8 k9 A2 f) A) y: j- i - {: V! H. q1 x+ `3 B! r
- /* USER CODE END WHILE *// ]7 s8 F/ x" q
- 5 M" A) k! R( J
- /* USER CODE BEGIN 3 */- L+ t; r# m/ ~
- HAL_Delay(500);
3 E6 H! H9 T2 x - DAC1_Set_Vol(DAC_Value);
9 w* [# K/ q* K5 E - sprintf(buff,"S:ADC: %1.2f DAC:%4d\r\n",Get_ADC(),DAC_Value);
0 d: n! G( E5 n5 L - LCD_ShowString(10, 70, 16, buff, 0);; c7 {) i4 h9 z5 T5 _( x; e" ]9 y
% R7 G% d1 ~+ }7 {8 ~7 ]7 l- sprintf(buff,"S:DACG:%5d\r\n",HAL_DAC_GetValue(&hdac,DAC_CHANNEL_1));
( k' l, [8 q+ _/ | x& J - LCD_ShowString(10, 90, 16, buff, 0);
7 [% V4 ]% _ e9 V- d1 w - HAL_UART_Transmit(&huart1, buff, strlen(buff), 10);
* d' L5 W0 m/ |- | - }
% _& p \' c" [+ H) } E - /* USER CODE END 3 */
( J$ X; O6 p4 E - }
复制代码 在STM32CUBEIDE中,想要调用sprintf()和printf()程序的话要在软件里设置一下- r2 k4 r0 Y% o/ c3 Q9 J& R
# Z& V, P3 i6 p. o+ {
(PS:软件里面也要选Debug模式,Release模式好像编译不了这两个函数) D4 q: X8 G2 Z C* l
工程:Pro5.zip1 n8 z& T7 K1 l5 z) b, X& z2 p
$ ~6 ` B- a4 ^# x
|
感谢分享