本帖最后由 XinLiYF 于 2018-4-14 18:02 编辑
' p ?3 Z$ `' N1 y* N. X a5 |+ W1 I
ARM CMSIS Driver 学习 之 USART
8 A$ A- n/ N( _% Q" O( z 1 p: G; p* q0 F
最近把 MDK 升级到了 V5.25 ,发现 Managing Run-Time Environment 中已经有好多好多的库。相比之前已经好了太多太多,从底层驱动,到上层协议栈,常用的有不常用的也有。发现 ARM 对这套系统的更新速度加快了一些,觉得有必要学习一下。从驱动开始学起,先学 USART API 详细介绍见 CMSIS Driver USART API
( W* G! [! \) K1 N0 e7 x$ o
, m4 z6 [: [; Y9 x0 U7 v2 |. XUSART 把收到的数据再发出去程序' V7 L' B1 x9 \
- /**5 n- E6 C+ c" n {% y" {3 _2 |
- ******************************************************************************
8 u; D/ I* x+ ?# m1 U1 P - * @file main.c
4 E$ I, s+ q% O- V; T4 q - * @author XinLi( y7 w2 E8 O4 ]+ _2 c* y0 M
- * @version v1.0" m4 i0 N! p9 ]+ K
- * @date 20-March-20180 E- s6 D' v" D1 R
- * @brief Main program body.# ^) i0 C T' @- X8 I
- ******************************************************************************
D! ~% O' `, {- d9 c' B - * @attention
( X ?$ s) s, t) ]$ Q3 [* i - *
% e% K/ U2 M2 n4 o* e0 t+ T/ B3 W - * <h2><center>Copyright © 2018 XinLi</center></h2>* T" d5 Q; h- b# q Q5 X
- *
$ w* x: t# t0 a/ |7 k' W1 V. e: z+ M - * This program is free software: you can redistribute it and/or modify
7 H: n7 n2 K6 M% \ - * it under the terms of the GNU General Public License as published by! A; c2 G- W- l6 P" e5 M
- * the Free Software Foundation, either version 3 of the License, or
" E6 d& G: C) i' E R& o% p - * (at your option) any later version. z3 q, G! R% t* p! g
- *, h- J- F' o- G# J& E7 w* m
- * This program is distributed in the hope that it will be useful,- G/ Z* k8 I3 z5 ^- b, V
- * but WITHOUT ANY WARRANTY; without even the implied warranty of- t; B. w, F3 b6 V
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6 O) ]- n* a1 W - * GNU General Public License for more details.6 p# p8 Y; [. H( P; X
- *
2 h* Q- H, h5 n" o5 t5 h9 @' C - * You should have received a copy of the GNU General Public License- I$ B( h V4 Z" U4 h/ i7 E4 G
- * along with this program. If not, see <http://www.gnu.org/licenses/>.. h. f! l/ @0 X: ~' D* ?
- *% M3 |! X2 C9 Z/ U/ k
- ******************************************************************************1 k; n- h! O4 {& Z
- */+ `7 l3 l6 N1 E. h3 O
. K) w% \# ^: m+ z" h1 I) v( i" I- /* Header includes -----------------------------------------------------------*/
( }1 F1 P2 a! _" S% m3 E+ @) i - #include "stm32f4xx.h"$ Z4 k: B% t( q5 I" o. }
- #include "Driver_USART.h"" j! H) L4 c$ G! j7 T2 F# b, [
- #include <string.h>
! Z% F2 n" F1 c* H
9 K' y( v$ K1 Q5 a4 o5 v- /* Macro definitions ---------------------------------------------------------*/3 R6 k" e! M' }! ^: C. I5 V" l9 `
- /* Type definitions ----------------------------------------------------------*/
# J5 s. d* l4 X& Z# p: r - /* Variable declarations -----------------------------------------------------*/
& `) B6 H& Y9 ~; \# }- p( Z& I+ @ - extern ARM_DRIVER_USART Driver_USART1;$ ]5 R/ s, _3 A: B7 e9 j5 |: @3 `
- 5 G ~8 b7 e1 A Z) |+ A0 ?4 d
- /* Variable definitions ------------------------------------------------------*/( o; i' f" n: p
- static uint8_t rxBuffer[1024] = {0};: z& U( ?* `1 `# c; D% }
- static uint8_t txBuffer[1024] = {0};+ p F0 X6 E" @4 @1 ]0 z% b' ^$ y
- m! i5 o% Z% \, }( f, _- /* Function declarations -----------------------------------------------------*/
# c) {, u# W- q* H! |7 r% d - static void USART1_Callback(uint32_t event);( E- T4 B2 ^$ {4 J' f# j% M6 C0 `
- static void SystemClock_Config(void);3 u Y5 k @% H( s) r1 c( L4 G
* \- | I( P- Y! p/ l. y- V- /* Function definitions ------------------------------------------------------*/
% g# k0 D/ r* I7 o; J
4 S0 z) S) S7 R8 E- /**& o: i, Y# f) V. o1 H
- * @brief Main program.9 V9 B) [6 P' N# {8 Z( o# c
- * @param None." d" Z5 v' W; P" q4 Q3 ]% G9 o
- * @return None.3 v5 d; O9 v# {3 k, U" I; P( A
- */
) y6 |- K7 o* c( _/ u2 e" z" ~8 w - int main(void)
' r1 r3 |! I& ~0 I( z8 B5 p - {" q+ {' S2 y1 \) p( c6 g
- /* STM32F4xx HAL library initialization:
3 v i, ]' C1 V3 L - - Configure the Flash prefetch, instruction and Data caches2 {$ U: J: g! S4 H5 e, _
- - Configure the Systick to generate an interrupt each 1 msec; K4 ?' X0 Q: R$ J& o! q. ?
- - Set NVIC Group Priority to 4
$ o, B2 U, V4 T, `1 B: C$ f6 H - - Global MSP (MCU Support Package) initialization% Q& Y9 f; i5 C+ ?4 U' L
- */2 z8 b" S! i: V
- HAL_Init();5 |' a$ l% z! Z
- 3 N5 M$ I6 z S! z) j
- /* Configure the system clock to 168 MHz */+ n* H P* `4 @; f/ l
- SystemClock_Config();
+ p- O/ e& G3 |8 C -
9 z) K; \- R8 n" l - Driver_USART1.Initialize(USART1_Callback);
; s$ |# c' @' w( O; c - Driver_USART1.PowerControl(ARM_POWER_FULL);6 z9 w! a6 y. v8 B" e' H
- Driver_USART1.Control(ARM_USART_MODE_ASYNCHRONOUS |7 d4 S& V: [9 t$ y. {5 V& @
- ARM_USART_DATA_BITS_8 |
8 x& Z0 F; M8 T, A% P5 k. F9 J - ARM_USART_PARITY_NONE |
' w i" H& U- D# L' T8 K - ARM_USART_STOP_BITS_1 |
! d, z' W' G: L9 n; M5 Q, K - ARM_USART_FLOW_CONTROL_NONE, 115200);
2 B" i6 V- L' V" `* r( V% q$ t' O - Driver_USART1.Control(ARM_USART_CONTROL_TX, 1);! C* a$ ]( b/ M$ q; r; T' v
- Driver_USART1.Control(ARM_USART_CONTROL_RX, 1);
5 p% n- F. d7 F% S2 k$ c - . t. U9 n5 {& Y9 n! b s& ]9 _
- Driver_USART1.Receive(rxBuffer, sizeof(rxBuffer));
% i+ h+ c: C, F" ~) D -
; r2 ]4 u- M3 g+ d& N/ R* K/ J - for(;;)
8 `3 [) f# i- j( d - {* d" q. Z# V# |; ^ K! w
-
0 z5 W8 A; y3 ?8 g4 m V& x$ Q - }
* ?( w5 K# x' [ - }
9 V2 m3 y! f- x, ~+ V+ j. A7 b2 w
5 ~' s$ H `5 s4 ?/ Q+ Z& h- /**% f5 n4 `; c: n3 k
- * @brief USART1 callback function.# h1 Q! N3 g. @4 x2 B. w3 p# C/ i2 [
- * @param event: USART events notification mask.
% E$ y5 o$ D" u1 `3 K2 W' K - * @return None.
* Q7 |# X0 K$ t; u8 Y+ o+ d - */7 I( [1 `1 Z+ P6 q3 a; @
- static void USART1_Callback(uint32_t event)
! ?* ~! L9 h) J - {
6 O1 D! N3 [. Y, U, @$ ?* b - if(event & ARM_USART_EVENT_RX_TIMEOUT)1 f E: M# ?' p* R! }
- {" r% s6 D; `( f, q
- Driver_USART1.Control(ARM_USART_ABORT_RECEIVE, 1);: M {9 k) {$ C. _# c V
-
) x( _# ^$ D! e& D - uint32_t length = Driver_USART1.GetRxCount();
' F% N/ t" u: ^- z -
* j4 f, o% e1 N% @: A& [ O" R. B - memcpy(txBuffer, rxBuffer, length);
* o0 T$ w: n! [$ g" \ -
: P; d1 v% r3 f* v- O- G/ ] - Driver_USART1.Send(txBuffer, length);
& q0 t/ j; G4 N; s8 _ R0 f6 n) ~ - Driver_USART1.Receive(rxBuffer, sizeof(rxBuffer));. ]& c, }9 @ F% m
- }
' z* b: l7 w+ } - }/ ~: G% [! i0 y% |( s7 L$ W5 }1 k
- 4 I: G3 d' S' |* q
- /**
1 Y: h% y/ }8 D; X! F/ ~ - * @brief System Clock Configuration
! C. e5 i* W3 U, i K - * The system Clock is configured as follow : ( z: y7 `5 M9 K' ~
- * System Clock source = PLL (HSE)0 o% |9 s4 v g+ W; X) y% [
- * SYSCLK(Hz) = 1680000001 ?' k q7 {0 o- ]( }
- * HCLK(Hz) = 168000000
M) s6 o$ M" q - * AHB Prescaler = 1
0 D7 X; a$ {" S! y. [( { - * APB1 Prescaler = 40 w3 n; ?# ~' J. L
- * APB2 Prescaler = 2
9 L% l, k. ^$ k' r2 a: @9 p - * HSE Frequency(Hz) = 8000000
' ^6 c! }+ v q7 B+ [6 m - * PLL_M = 8
% @7 ^! A, L1 t, C/ x! g - * PLL_N = 336
5 w2 H; |% }5 n/ P0 T/ E7 d - * PLL_P = 25 m3 r$ C+ c0 G3 G! p. u9 |$ s0 M0 y
- * PLL_Q = 7! ~' k8 X* G$ w; ~; i
- * VDD(V) = 3.3$ i8 O! K T& ^
- * Main regulator output voltage = Scale1 mode
: J: x! e, ?1 Q - * Flash Latency(WS) = 52 X* O5 g: x2 E$ r9 k' d
- * @param None2 h2 c& M. l( I$ h3 E
- * @retval None1 _2 f) A; E2 L+ Q6 y- L
- */
* w' m& K4 I* m- { - static void SystemClock_Config(void)
5 c, W' ^7 D/ E& t - {# ]' f0 |! j+ S6 p& {
- RCC_ClkInitTypeDef RCC_ClkInitStruct;: ^9 F7 R. k! ?) I$ B. a
- RCC_OscInitTypeDef RCC_OscInitStruct;
0 G: D, Q, E- I3 l/ e - , @) W6 V6 P! _ Z4 D# }* h
- /* Enable Power Control clock */
( x( O2 R! _7 l t - __HAL_RCC_PWR_CLK_ENABLE();# [/ V- m' R! X4 }! r
- $ [$ N( j. w* y6 i
- /* The voltage scaling allows optimizing the power consumption when the device is
. W6 A" I" m9 s# q. C9 @) |* t$ n, z - clocked below the maximum system frequency, to update the voltage scaling value 3 W" ` }9 z4 W8 i. x- p& O8 E
- regarding system frequency refer to product datasheet. */
' b* I: p& }% Y - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
: z) q, P- I9 ?6 o. K6 T - * d4 ~" c$ ^) A7 t
- /* Enable HSE Oscillator and activate PLL with HSE as source */
A8 ]: t8 d3 V6 m5 v - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
' |) h7 ]$ z/ u% b - RCC_OscInitStruct.HSEState = RCC_HSE_ON;
7 W$ M: X% L7 m( j1 q; C - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;/ h, t7 j1 x5 C+ K2 H5 O- k8 m
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;6 M5 F: i3 C$ t6 n8 C
- RCC_OscInitStruct.PLL.PLLM = 8;
! b( O' R0 _" J* m; X* n - RCC_OscInitStruct.PLL.PLLN = 336;! \9 }5 A' e, g$ ~
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
3 {" ~5 n" ^5 e; B' D! @ - RCC_OscInitStruct.PLL.PLLQ = 7;
) {( p1 X3 u* B: ` - HAL_RCC_OscConfig(&RCC_OscInitStruct);
+ s# k3 G, D$ p/ M* ~3 B -
* ?# Z8 d" n' Y! X5 j2 P, v2 @ - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
a4 u2 P" h8 b/ |4 ` - clocks dividers */ [: h- e7 Y2 f: v8 u% B$ |
- RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
1 R. H4 N* S6 y2 g - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;4 |! i9 R5 K# G
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;+ G: _( d: m6 ]- e
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
1 R1 ?. U; ]3 k8 r1 i- u - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
; h: j; k+ X2 h8 I& h Y - HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
' N2 z7 U( a1 s - # W3 q4 i, R# u
- /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */- \3 J3 c% M2 m3 h6 N" X; n" T8 x
- if (HAL_GetREVID() == 0x1001)- z# j4 J) Y$ b
- {
# S* z* c, y/ q3 r+ b- g K - /* Enable the Flash prefetch */( o/ N% a& |' I
- __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
2 n" K1 v% t3 B* V: a% K( q3 j - }
9 H/ C. ^. M8 c - }
3 b* @; w, W& J* X" Q
复制代码
k6 {) m) q: i$ B6 t3 f) M归档链接
( S: G; h2 ~' J5 ?0 pARM CMSIS Driver 学习 之 SPI
" C% }3 c& L+ T% A, M* j' B/ w) o* ?! s: \( R
|
这个出来有几年了,只不过之前没有现在全,现在可以用到项目里了,底层驱动 ARM 已经实现了跨平台,之后产品换 MCU 也比较方便。
这个趋势很好啊,避免碎片化,抽空看看
是啊,MCU 开发就是缺少这样大一统的框架啊
https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html
{
// UART1_Comm_Init(115200);# a9 L' i4 o5 l. i
UART2_Comm_Init(9600);# E5 a/ Y0 _$ r+ z
( |0 ?4 l$ E0 T
Driver_USART2.Send("http://www.cmsoft.cn", sizeof("http://www.cmsoft.cn"));4 l8 i, x+ M6 y; p
while(1);
}
程序运行到Driver_USART2.Send就卡在这一行 无法运行到while那里 同时发送的内容也没发出去
不知道咋回事????
{% e! a6 s" a [ t& C3 M% w
if(event & ARM_USART_EVENT_RX_TIMEOUT)
{
Driver_USART2.Control(ARM_USART_ABORT_RECEIVE, 1);( ^% M- C, D; b$ d7 @- V
uint32_t length = Driver_USART2.GetRxCount();; R4 I2 [$ S9 h
; a% S( [4 z1 i7 A2 U
// memcpy(txBuffer, rxBuffer, length);
// 0 H6 E2 Y0 Q0 W1 x; A) {, q
// Driver_USART1.Send(txBuffer, length);
Driver_USART2.Receive(USART2_RxBfr, sizeof(USART2_RxBfr));& R- l7 `! k0 z$ }8 s& l% J
}
else if(event & ARM_USART_EVENT_SEND_COMPLETE)0 P4 {' z4 o% ` n! p* x2 F/ j
{9 h* ^; V2 B, S% L
__NOP();. G0 K5 ^9 G4 q& y6 N
}" x9 H) O6 h7 z% g
else if(event & ARM_USART_EVENT_RECEIVE_COMPLETE)
{& z' y$ E, J: j7 {8 ?& Q9 _
__NOP();! s4 ^, s: e! q
}- W4 h$ S. F5 o( j
}
从电脑端的串口工具发送内容 也没产生串口回调事件 不知道咋回事?????
{//usb
4 A" Y4 Z% m! t. u# X4 u6 L! P
Driver_USART2.Initialize(USART2_Callback);
Driver_USART2.PowerControl(ARM_POWER_FULL);) {7 ^# v* t$ T( C" B
Driver_USART2.Control(ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_DATA_BITS_8 |& @6 z* B& Q$ x5 p2 i
ARM_USART_PARITY_NONE |
ARM_USART_STOP_BITS_1 |! l" M ^: n |4 X; F! M5 y: v2 f" S
ARM_USART_FLOW_CONTROL_NONE, Brate
);$ I$ u' N/ e; s/ X* B
/* Enable Receiver and Transmitter lines */- f. I: m1 _5 o3 D$ j
Driver_USART2.Control(ARM_USART_CONTROL_TX, 1);* r! a6 o/ U1 Y8 a. H# g5 K4 u
Driver_USART2.Control(ARM_USART_CONTROL_RX, 1);+ `( _/ N, @% `: P
/* Begin to receive */' N& f# Z1 B+ A. W, \& U
Driver_USART2.Receive(USART2_RxBfr, sizeof(USART2_RxBfr));. S7 g/ E( ^/ W6 k) _
}" w( n& S' y, ?
这是串口初始化