本帖最后由 XinLiYF 于 2018-4-14 18:02 编辑 + V6 [1 e ^) d7 }! ]; _
" i" ^. V C% J/ I: K- Q: F% L. ?ARM CMSIS Driver 学习 之 USART
' I1 N3 z9 l1 t+ f9 } / T: m: ?9 s, X# e
最近把 MDK 升级到了 V5.25 ,发现 Managing Run-Time Environment 中已经有好多好多的库。相比之前已经好了太多太多,从底层驱动,到上层协议栈,常用的有不常用的也有。发现 ARM 对这套系统的更新速度加快了一些,觉得有必要学习一下。从驱动开始学起,先学 USART API 详细介绍见 CMSIS Driver USART API
* Y9 t" O. \% |( _& x _4 `1 I2 K6 V2 M2 ]
USART 把收到的数据再发出去程序* o4 {, `& \1 m6 I+ q
- /**# T, j* y( A; _' `8 N, w
- ******************************************************************************: p5 _" {" `1 s, w3 X7 Y
- * @file main.c2 i9 t9 s7 v! z/ a' Z& n
- * @author XinLi
% P0 v2 B9 J- t6 r6 N8 R - * @version v1.0$ H9 t, x P3 V7 z* n6 Z
- * @date 20-March-2018
7 E5 y0 S7 C# k$ f: a! @+ P - * @brief Main program body.1 b3 @) G, E0 @6 T$ j1 p5 E
- ******************************************************************************: @* W4 P9 s" f; g2 b
- * @attention9 y+ B/ `! X# _9 L2 D
- *. u- e" D" ~( ` Q8 z
- * <h2><center>Copyright © 2018 XinLi</center></h2>7 x& P, g# ?& m0 x4 Q* Y
- *% c9 f( D( N+ }- v+ F
- * This program is free software: you can redistribute it and/or modify
$ x% |) U6 r. u) K0 s! x8 P - * it under the terms of the GNU General Public License as published by
# b* e/ h- T5 s1 z - * the Free Software Foundation, either version 3 of the License, or" ]" q; M* n. ~ @7 B
- * (at your option) any later version.0 R- k% H1 M: z9 Q
- *5 I `2 Y5 j! F7 ^; P' ^1 z) N
- * This program is distributed in the hope that it will be useful,4 o+ ]: N y; |( r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
/ [9 d* ~4 |1 s: T: @ - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the4 D; q/ ~& ^! L" c5 ] B2 V
- * GNU General Public License for more details.6 M7 {6 V' p9 a- U' [4 ]" C4 z
- *
; b/ S) o6 ]3 ?" F7 @ - * You should have received a copy of the GNU General Public License2 z/ u" ?, L: F
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ F- i( B7 J2 h - *6 t9 x; C5 p; r/ `; O) ?
- ******************************************************************************- n; V; A0 g: |# U1 L( j
- */3 B' x8 ~! A1 N- W- C
# \- G9 Y! n% {0 k& p( w& d- /* Header includes -----------------------------------------------------------*/
2 C7 H; E- A6 d - #include "stm32f4xx.h"6 M- m0 J0 G% c) _% j# e" \
- #include "Driver_USART.h"' n; U0 W; I# Q- C% ~5 Q7 L4 ]
- #include <string.h>
4 L. D* G# @5 x6 B2 z
! S; l4 d( h5 Z2 N/ ^8 _. O1 V- /* Macro definitions ---------------------------------------------------------*/
7 O6 B5 ]# L! B& g$ h- e4 x7 L - /* Type definitions ----------------------------------------------------------*// s% S& G( e7 h6 F' [
- /* Variable declarations -----------------------------------------------------*/+ g$ f: x) L4 S! A% @
- extern ARM_DRIVER_USART Driver_USART1;( N# v2 v9 h8 {; f! ~( e
- 9 i3 e4 p9 ~% z# @+ ^$ G
- /* Variable definitions ------------------------------------------------------*/+ n& V6 V# c9 A) a
- static uint8_t rxBuffer[1024] = {0}; U+ C& a' H/ L$ m# c. h7 c
- static uint8_t txBuffer[1024] = {0};- E' A3 ^) l0 F! f* g. c7 h* \
) H+ \( W" G7 X( u- /* Function declarations -----------------------------------------------------*/ z* r" U& t$ R/ g7 S& D" j
- static void USART1_Callback(uint32_t event);+ D8 w0 r* X& C
- static void SystemClock_Config(void);
+ [! `6 S6 F* `8 E8 A
, K1 h# n$ m6 M) a5 G% n' Q- /* Function definitions ------------------------------------------------------*/
7 v8 G- W- Y: B# u$ i
" o* K9 V3 T3 w4 R! |9 x- /**! _% c0 W B; ~2 ?
- * @brief Main program.
( e0 n( @2 \2 D9 S2 _+ W! w% Y - * @param None.
+ d5 |0 M5 D, i/ k0 a. ?' r0 C6 F - * @return None.$ y, t4 a+ i8 M; X7 @) x6 R
- */
4 R: _" _9 O! D8 Z4 [8 e% A! U' U - int main(void)
. M! r/ a: Z- G& Z- H" C& b4 L; L - {2 G6 f4 j+ d( B6 c+ G
- /* STM32F4xx HAL library initialization:
$ t# {8 v0 ]) V; q. y% q2 A' | - - Configure the Flash prefetch, instruction and Data caches: ^ d' G5 o+ M5 N* w/ Q* m
- - Configure the Systick to generate an interrupt each 1 msec# Z+ C& J8 F% A1 b: N9 ^
- - Set NVIC Group Priority to 4
8 j3 b4 D: ?) _- a6 \7 |9 W6 ]" m - - Global MSP (MCU Support Package) initialization8 U/ f7 J7 v* S, v( h2 T9 a1 [5 R; g
- */
! |% W. Q3 P+ A7 j - HAL_Init();! M0 r6 z5 M0 v% g3 G) B. r
-
/ @! L" s/ C( i8 h9 K2 ?* B - /* Configure the system clock to 168 MHz */
9 Q/ U+ t7 E' Z: a9 } - SystemClock_Config();
- s! o* j& b- ~, T. ~4 Q - 3 T2 e: [) \% a
- Driver_USART1.Initialize(USART1_Callback);+ f2 i( c9 I; h" @( Q# y7 O4 l/ @
- Driver_USART1.PowerControl(ARM_POWER_FULL);
! v+ N2 R$ p1 x) s7 A9 q - Driver_USART1.Control(ARM_USART_MODE_ASYNCHRONOUS |
: o" C/ J+ K5 i- q3 @. m3 i - ARM_USART_DATA_BITS_8 |& z$ }( V( N% E8 l
- ARM_USART_PARITY_NONE |( U1 ^" z$ F0 w% k
- ARM_USART_STOP_BITS_1 |
: P' L; l G0 a; D6 @0 D) ~2 t3 _ - ARM_USART_FLOW_CONTROL_NONE, 115200);8 G1 r/ X/ S* `2 O
- Driver_USART1.Control(ARM_USART_CONTROL_TX, 1);
8 U+ \7 m0 c# |" T - Driver_USART1.Control(ARM_USART_CONTROL_RX, 1);; M8 V" L, C9 X& P
- * ]- n1 ?% m; S" h
- Driver_USART1.Receive(rxBuffer, sizeof(rxBuffer));
. _6 Y6 }) J2 @6 c - ! ? W# m( r. n1 d- E3 P2 T4 r
- for(;;)6 Q7 u" [$ M5 C z) Q
- {
9 k$ F) h5 X$ s/ p* v - 7 y, m! T K/ k1 |/ `& L2 B
- }2 @0 J$ n. I" A: M
- }8 ^% X7 A: s" m+ \
# [# n" s+ J( } y8 Z3 F' o" P4 K3 {- /**
4 F4 B; @$ @ i% } - * @brief USART1 callback function./ j, V0 U2 t% @' @* B2 I
- * @param event: USART events notification mask.
4 p- i; G2 D" H - * @return None.
C# [3 A' ~! i$ N - */3 D8 ?! P8 C" I+ h
- static void USART1_Callback(uint32_t event)
& ~: U% D2 Y& e6 T - {3 Y) y& r( A$ I4 A4 o+ c
- if(event & ARM_USART_EVENT_RX_TIMEOUT) q2 n& a4 E8 Z5 e
- {
: ^) ^& Y6 I) d$ W* \; Q. X) m - Driver_USART1.Control(ARM_USART_ABORT_RECEIVE, 1);
9 Q/ i( P- i1 Y' v' U; [8 S( [ -
- h5 }, a& m) g - uint32_t length = Driver_USART1.GetRxCount();
/ U( m- ]' W7 ]7 X! y( f! q -
9 S- i* Z; [2 t0 I ` - memcpy(txBuffer, rxBuffer, length);
/ x* P: s$ _0 p -
* ?& \# D& e f4 t. e* M! O - Driver_USART1.Send(txBuffer, length);& _0 O5 B3 @. D2 B( N
- Driver_USART1.Receive(rxBuffer, sizeof(rxBuffer));; r3 y3 ?- p: b2 q' m
- }3 K+ G V) Y! l# `4 W# L5 G: c
- }/ z$ Z) L3 x$ `/ S0 b
- ) f5 U) G+ S8 d2 u( X2 ~$ z8 M
- /**( j$ s/ N( x7 [7 f9 l- I I
- * @brief System Clock Configuration
' n, {! w2 d1 s/ w c1 n0 a - * The system Clock is configured as follow : & I* W/ h5 C& V. Q
- * System Clock source = PLL (HSE)# q/ I6 G, |2 m+ N+ M
- * SYSCLK(Hz) = 168000000' w8 N5 |# [9 c. U* o; z- I& G
- * HCLK(Hz) = 168000000$ m8 f: S& o8 @0 H0 Z! ?& Y+ w8 ?8 J
- * AHB Prescaler = 1
% E+ @; x" b/ c$ V - * APB1 Prescaler = 4
3 f( m2 X. a! w* z- x# g - * APB2 Prescaler = 29 v* f2 h0 {7 s
- * HSE Frequency(Hz) = 8000000' R) p6 x0 D) j v7 d1 ^
- * PLL_M = 8
7 q& [, N' Y- R - * PLL_N = 3368 D: T# o3 x, q1 l2 b" j+ k
- * PLL_P = 2; Q0 E) H8 F; i9 X5 Z; W- h
- * PLL_Q = 7
0 ]& X' G" v+ ^% n. F6 U7 j - * VDD(V) = 3.3
8 V% H+ q2 K! N* w( z - * Main regulator output voltage = Scale1 mode
7 X4 Y1 o1 {/ J+ |; Q7 M0 y( v - * Flash Latency(WS) = 5
- K3 D/ ?' l: `" R2 X5 t7 b7 ^ - * @param None
9 I6 X2 y5 u) k6 k - * @retval None' c+ A+ K# K1 W
- */
3 c5 s3 i: I& Z$ _ - static void SystemClock_Config(void)/ A5 j- c* y/ d5 {
- {2 y' g! ^' s" F/ e3 {+ z6 q
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
& c4 c; Y" l0 {' ^5 S; i - RCC_OscInitTypeDef RCC_OscInitStruct;
$ F$ l8 e: A9 o& e) v8 H2 B
8 q* y2 u# j' U( u1 W- @. A- /* Enable Power Control clock */) y! j0 C3 Z5 I( H
- __HAL_RCC_PWR_CLK_ENABLE();7 o' S( J; M9 z. u: S* p6 B4 r
- 9 }7 _, l0 ?; M% P
- /* The voltage scaling allows optimizing the power consumption when the device is
# A y0 Q5 M1 L0 z. R5 U. ^ - clocked below the maximum system frequency, to update the voltage scaling value
! J6 n7 d* [- v. b- X! L' a - regarding system frequency refer to product datasheet. */
7 D& `8 g+ O. i - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);2 Y, U! ?8 R5 E4 g2 Y
- , r# o K* |* O! Y
- /* Enable HSE Oscillator and activate PLL with HSE as source */
/ Q: L( k$ k9 I) Y7 R: \ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;8 x3 i M7 K4 z! |" M9 C; [
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;+ U/ l2 I% P7 Z: J
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
2 c- W4 i! J) X: z c* P - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
1 L# l7 l( A8 p+ A2 Z - RCC_OscInitStruct.PLL.PLLM = 8;, ]/ d* U5 f9 E& W
- RCC_OscInitStruct.PLL.PLLN = 336;
3 k) R/ P* F, G - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
: _5 A. _7 |4 ^, R5 y - RCC_OscInitStruct.PLL.PLLQ = 7;, x2 f' Q, \* n
- HAL_RCC_OscConfig(&RCC_OscInitStruct);
5 y# d+ {3 o! n, ~+ \7 o9 N -
# o, D2 d9 o- _; {2 y$ B - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 5 B5 ^0 P; n" ]3 R
- clocks dividers */
' K% `4 _& X; @2 `! w5 V- R& C8 t - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
0 m5 c' _5 d4 H( z; r7 w- i - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;; ^/ `& _% m" D) z# n
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
3 Y8 j" X2 h3 E) u8 e/ n - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; & G1 C% |& _2 D( G" ^/ Q
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
1 @& O c8 n5 T - HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);0 }) c0 Q/ B+ M2 ~6 Q
* J. @ a p: p- /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
' T* J l3 j$ M$ _8 C1 |& {9 z% |4 O - if (HAL_GetREVID() == 0x1001), w) `; y" H% `) u/ g2 @: X) r J
- {) Y k( k! S. x5 ^; @
- /* Enable the Flash prefetch */4 a9 d0 A" V7 c, {. G" u% _4 M* A
- __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
0 y! ?4 u" \, E; w5 A8 o# g - }
3 \% g' i. T9 ^6 F) F( b - }, M& l3 l* |) J- |
复制代码
9 {) r) X9 y" H1 _, I归档链接
9 l" @1 a( T# |1 @6 Z' v# |0 XARM CMSIS Driver 学习 之 SPI
# s! I/ H7 G" f
A& K5 M" Z! t9 n, o( X5 @& j |
这个出来有几年了,只不过之前没有现在全,现在可以用到项目里了,底层驱动 ARM 已经实现了跨平台,之后产品换 MCU 也比较方便。
这个趋势很好啊,避免碎片化,抽空看看
是啊,MCU 开发就是缺少这样大一统的框架啊
https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html
{
// UART1_Comm_Init(115200);
UART2_Comm_Init(9600);
Driver_USART2.Send("http://www.cmsoft.cn", sizeof("http://www.cmsoft.cn"));
while(1);% [0 f8 p0 d/ e) M. ]: o
}
程序运行到Driver_USART2.Send就卡在这一行 无法运行到while那里 同时发送的内容也没发出去: |6 A4 c% D5 @( `1 h5 p+ i
不知道咋回事????
{: F3 f7 Q4 a$ s8 j6 Z
if(event & ARM_USART_EVENT_RX_TIMEOUT)
{ v K5 T0 `: ~, z
Driver_USART2.Control(ARM_USART_ABORT_RECEIVE, 1);
3 B: U: ~2 J0 W3 A- {- g W) u
uint32_t length = Driver_USART2.GetRxCount();
) ` S) O/ o3 C' a
// memcpy(txBuffer, rxBuffer, length);
//
// Driver_USART1.Send(txBuffer, length);# X! F- B; N3 M/ Q0 |0 C
Driver_USART2.Receive(USART2_RxBfr, sizeof(USART2_RxBfr));0 {9 C! M& w+ T$ m/ b
} 6 t! J6 j0 z3 K. U+ [: ~
else if(event & ARM_USART_EVENT_SEND_COMPLETE)
{
__NOP();
}6 r/ X' P# _0 P, F) p& O6 J
else if(event & ARM_USART_EVENT_RECEIVE_COMPLETE)
{. ]% G) @3 A5 F3 k
__NOP();' z9 P+ R: C4 ]( {! R: y |# l: @
}# a& W/ M! Z# m) C4 p9 @1 i* K
}
从电脑端的串口工具发送内容 也没产生串口回调事件 不知道咋回事?????
{//usb
0 `/ B- }" d! l, g
Driver_USART2.Initialize(USART2_Callback);
Driver_USART2.PowerControl(ARM_POWER_FULL);* b7 K: ^' h# r& k+ [: I. m1 B# b
Driver_USART2.Control(ARM_USART_MODE_ASYNCHRONOUS |% `4 P' e% v$ r/ J5 s
ARM_USART_DATA_BITS_8 |' e1 g4 |7 G \. `- [3 n8 a
ARM_USART_PARITY_NONE |4 D% `* S1 @9 b9 L n A
ARM_USART_STOP_BITS_1 |6 l }- D- e8 H3 F
ARM_USART_FLOW_CONTROL_NONE, Brate
);
/* Enable Receiver and Transmitter lines */
Driver_USART2.Control(ARM_USART_CONTROL_TX, 1);
Driver_USART2.Control(ARM_USART_CONTROL_RX, 1);
/* Begin to receive */" P9 T7 n6 p' U- l8 j4 F9 y
Driver_USART2.Receive(USART2_RxBfr, sizeof(USART2_RxBfr));
}
这是串口初始化