本帖最后由 XinLiYF 于 2018-4-14 18:02 编辑
) F, U) d. j; Z& H' ^( A3 y) T: O% t/ n# j) L9 i
ARM CMSIS Driver 学习 之 USART! X9 c1 a. ~9 `2 n! |9 i9 O6 a
- O- r" X }$ H3 D' {6 K' O, x
最近把 MDK 升级到了 V5.25 ,发现 Managing Run-Time Environment 中已经有好多好多的库。相比之前已经好了太多太多,从底层驱动,到上层协议栈,常用的有不常用的也有。发现 ARM 对这套系统的更新速度加快了一些,觉得有必要学习一下。从驱动开始学起,先学 USART API 详细介绍见 CMSIS Driver USART API
) e) ~4 m0 C- o9 x
: y: I+ F1 A1 jUSART 把收到的数据再发出去程序- D$ o4 y- D- X- ^: g$ }) S r! U
- /**/ l6 q, p( T, n7 _
- ******************************************************************************% O8 d5 ~+ P8 h0 y1 V- P: {. N9 [# f
- * @file main.c
6 ]5 ^$ W& t2 X! f - * @author XinLi
2 m0 P! i6 A* K& S2 {- O$ R$ ] - * @version v1.0
4 G3 Z; Q& Z, Y' Q% ?7 v i. x - * @date 20-March-20180 l. ]& D v0 e, h
- * @brief Main program body.
$ Q$ o3 w- Z( P- u; r+ j - ******************************************************************************2 D. g' p$ ?% [ T1 |& B- s: W
- * @attention" V% f/ ^6 [( C% T `: u
- *
5 C) h, `! ?( R5 x - * <h2><center>Copyright © 2018 XinLi</center></h2>( T9 S7 ?# a' A1 S; K9 x8 y2 H0 {
- *3 t2 V+ F/ n* \* B
- * This program is free software: you can redistribute it and/or modify1 \4 R( g* o6 X, r- E; z, Y7 Z
- * it under the terms of the GNU General Public License as published by- u9 y9 X& I1 v* G6 b/ l* h n" X3 }
- * the Free Software Foundation, either version 3 of the License, or
0 ^4 d/ J/ D8 z+ J) m' | - * (at your option) any later version.
; S5 U3 f5 Y* M7 b. H, Y - *
9 V4 z* z& L$ `4 K/ z - * This program is distributed in the hope that it will be useful, d/ H% @7 _6 a# E) v, l8 D
- * but WITHOUT ANY WARRANTY; without even the implied warranty of/ O1 E7 [) i& a3 P3 y0 Z
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
, N6 a$ N+ b9 ]: ], W6 Y - * GNU General Public License for more details. @) F' t$ V' o& e( }
- */ a% V: p" h1 U% V8 j. Z; J7 ~1 C
- * You should have received a copy of the GNU General Public License4 h; F" X, E; a7 D) G" F
- * along with this program. If not, see <http://www.gnu.org/licenses/>.. `$ I6 i. Z( O. c d. i
- * N7 y8 h1 b# y) }5 O
- ******************************************************************************
o' x3 }2 Z$ j( l - */4 i: Q$ @8 a8 C, ^ @7 [0 f% e
- V" w& y* y0 P6 ?, ^5 }9 |2 d
- /* Header includes -----------------------------------------------------------*/
* @3 N6 i# S' F/ _ - #include "stm32f4xx.h"* Z0 \. K; Z/ o" A( ~7 R7 ]( I
- #include "Driver_USART.h"
+ R! B: N2 B( K* o9 U3 o: Y - #include <string.h>
5 k6 P& E4 v& o% K - 4 a/ I7 f# H m, y# t
- /* Macro definitions ---------------------------------------------------------*/
- g) |# n0 B8 u% y) i7 p - /* Type definitions ----------------------------------------------------------*/
5 `3 W- Z4 A% k# i# f `0 L - /* Variable declarations -----------------------------------------------------*/
8 u. ?. r: Q& R( y - extern ARM_DRIVER_USART Driver_USART1;5 }6 t) H4 g3 U4 s
; Z |- T- G5 o' _; g- /* Variable definitions ------------------------------------------------------*/# y& L9 M. P+ f" Y, g/ Z
- static uint8_t rxBuffer[1024] = {0};
: C; y1 z z: [0 k - static uint8_t txBuffer[1024] = {0};: Q0 v Z2 M* Q7 K* G! I2 ~
* b; e2 v6 d5 z' C- /* Function declarations -----------------------------------------------------*/8 K9 u# H O: j/ G6 m( X L
- static void USART1_Callback(uint32_t event);8 f; O' \; H% N9 C4 Y1 d
- static void SystemClock_Config(void);- e! o: q4 y3 N5 N
- 2 C# |2 g2 {8 J- `
- /* Function definitions ------------------------------------------------------*/
~: t. I' } ]4 h - # S( \7 `9 ~7 p- b5 L
- /**. y7 c$ x2 Z, `2 q% `/ A& t1 e
- * @brief Main program.8 [7 v! r- t; x% ]9 i
- * @param None.2 Z' ?5 M; l, ?$ A5 Z0 o
- * @return None.
/ O; K0 {# l2 D1 o8 }- Q9 e - */5 u/ Z; I& H! b" f) R$ q& n3 s
- int main(void)/ v* Z# v0 a- B3 k" K9 m
- {
" ?, n& v7 N) u8 K1 h& L - /* STM32F4xx HAL library initialization:+ V3 W: @7 m }" b+ c4 Y
- - Configure the Flash prefetch, instruction and Data caches
" z% j% Z& m" v/ t0 J8 U" }. L0 B6 P - - Configure the Systick to generate an interrupt each 1 msec) V4 |! E+ W8 O/ ]6 A; F$ q
- - Set NVIC Group Priority to 4
. ~ _# ]) y3 d. R" U% ^$ i( C - - Global MSP (MCU Support Package) initialization
K8 x; t; [" c/ k7 t' B! f! k, r - */
0 T0 V2 @" ]: P, X6 f' V - HAL_Init();8 \, h( J7 o) `, p2 Q( l; E! A
- : e& l0 l; }9 W. L/ U
- /* Configure the system clock to 168 MHz */
( r) r% C' E3 F( A% L - SystemClock_Config();
+ G5 a/ i, V7 |, |, p2 w - . {1 v5 h6 ^: c& n
- Driver_USART1.Initialize(USART1_Callback);
* _* C; G2 y$ m' {" f - Driver_USART1.PowerControl(ARM_POWER_FULL);
" m2 |3 B# m% [5 w |( c - Driver_USART1.Control(ARM_USART_MODE_ASYNCHRONOUS |
1 R4 K p% p( L* f, b - ARM_USART_DATA_BITS_8 |: ^/ u4 a$ m$ p& Y, }! ^8 M6 E
- ARM_USART_PARITY_NONE |
- E# L4 K' `5 s- b# p - ARM_USART_STOP_BITS_1 |' M- c; }5 t/ |( E
- ARM_USART_FLOW_CONTROL_NONE, 115200);5 R) ?" l9 B& K" v' h3 [
- Driver_USART1.Control(ARM_USART_CONTROL_TX, 1);
+ y; N+ W1 N# r" G1 W - Driver_USART1.Control(ARM_USART_CONTROL_RX, 1);& _0 K* D/ _& t0 l
-
- c6 N3 W% y8 B' z - Driver_USART1.Receive(rxBuffer, sizeof(rxBuffer));
' n* ^# b6 E2 `4 W% y/ A$ { - " J$ W- I& t9 B. R5 `- e9 i) ?
- for(;;)
* I6 q) ^8 m; c3 `/ i8 T - {$ `7 H) y/ Q. t" q. m U. R) J. P
-
5 u) `; r! U r) R% i - }; |$ M) I" x; ~. y2 h9 Q* r! V: K/ A
- } ~3 G, F" F4 t( q9 d
' J0 P$ ~5 K& ^' ^6 U$ l3 g6 _- /**
p$ V+ Z& F" _. Y" C5 Z - * @brief USART1 callback function.9 I. w* n( K! c1 N& W
- * @param event: USART events notification mask.8 ?3 o' C; B% |8 x5 V9 Z
- * @return None.
7 q2 K# j; C9 w5 ~% G: U2 L% L' B& ? - */
6 j. w8 u- z- h' J8 R - static void USART1_Callback(uint32_t event)6 \5 }7 T2 s9 E L1 A$ i. C1 I
- {
. C/ C. Q7 T2 ? - if(event & ARM_USART_EVENT_RX_TIMEOUT)4 U5 H; B* v1 c: N( r9 g& Y* J
- {
2 H0 T+ z2 J! e3 p - Driver_USART1.Control(ARM_USART_ABORT_RECEIVE, 1);4 s9 @# ?% ?1 X
-
9 f0 v! e2 ?0 u) {2 @8 g - uint32_t length = Driver_USART1.GetRxCount();4 }, u$ X! p1 k( {
- Q. r, d2 d2 H, g
- memcpy(txBuffer, rxBuffer, length);) m; j- `7 {9 }3 A
- 7 q/ n" ~7 W1 z3 m2 j
- Driver_USART1.Send(txBuffer, length);
, z9 [, k; v) T5 ^/ `$ Y - Driver_USART1.Receive(rxBuffer, sizeof(rxBuffer));3 a B' i/ }2 @4 ~) x7 N, }
- }7 z1 o @2 C) M7 I( ~5 e5 F8 I
- }- f" t2 I2 y- k6 c
+ K) _8 g; O9 O) q {8 ~0 R- /**' ~4 i( H R/ |+ Q3 J+ e7 C
- * @brief System Clock Configuration
; [* R# Z8 l/ t5 m - * The system Clock is configured as follow : ! H. S, M; t$ \. l& ^( g
- * System Clock source = PLL (HSE)
8 e; Y' t3 y& n |* ]. A - * SYSCLK(Hz) = 168000000
; [' k. _, J9 L' S - * HCLK(Hz) = 168000000
0 N% i0 v# ~/ s2 v$ s/ R/ | - * AHB Prescaler = 1, @$ u: d. J& s3 e6 G0 p, a
- * APB1 Prescaler = 4$ g" _& h! D0 |8 \
- * APB2 Prescaler = 2
! v: x2 C I/ x F, o6 G( p - * HSE Frequency(Hz) = 8000000
4 g# m% w ?+ \' O - * PLL_M = 83 h- z8 u, z8 c
- * PLL_N = 336
) h0 l3 n9 h5 F3 A& A6 k - * PLL_P = 2. Z3 V- r: C% N" E9 B; @% j
- * PLL_Q = 7' H8 a2 X; z+ i2 v" j, L
- * VDD(V) = 3.3' z) Y& w5 C$ H3 \; T
- * Main regulator output voltage = Scale1 mode0 {) p: ^2 I5 j* ^
- * Flash Latency(WS) = 5
. y& [) l7 v( ?) J6 Y/ A* w A - * @param None
# d; o/ Y: [' x) U - * @retval None
; D# G. G6 P3 k- I7 c, M! g - */. P6 H4 Z' U2 G* `/ _9 c9 I/ D
- static void SystemClock_Config(void)
D$ O% X% u( G0 @( C! U5 D - {
. F5 h3 k0 ~! w% M - RCC_ClkInitTypeDef RCC_ClkInitStruct;
3 }7 T% e# d$ G, h - RCC_OscInitTypeDef RCC_OscInitStruct;* W8 m1 y i/ }4 ^2 {* K
- 8 m" M% ^( _7 d3 y; i
- /* Enable Power Control clock */
- i' A5 P! S5 P - __HAL_RCC_PWR_CLK_ENABLE();
1 i: A! s7 k8 Z6 T8 P( F
) [1 y' ]" |9 s8 v- /* The voltage scaling allows optimizing the power consumption when the device is ; `( u/ n( G" x7 K% }* W
- clocked below the maximum system frequency, to update the voltage scaling value
3 `6 I3 S& N, r/ \ B7 d# ?& h$ ? - regarding system frequency refer to product datasheet. */3 W; q) p1 A/ ]7 J& B3 y
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
9 @8 u. U1 _6 D9 b* a; I - + i$ m0 ^3 V* ~9 P R9 y) W
- /* Enable HSE Oscillator and activate PLL with HSE as source */) t4 ^3 g$ E* L" Q# B
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
( K# |4 t/ {! a5 F! s; _4 }; j - RCC_OscInitStruct.HSEState = RCC_HSE_ON;
% e) g+ Z6 v' y. X9 q! T, p - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;- ]$ {/ H' J1 }; _9 J
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
# K0 Q* P' I: x - RCC_OscInitStruct.PLL.PLLM = 8;
, B2 t# f& [* ?9 @ - RCC_OscInitStruct.PLL.PLLN = 336;
6 c: D' a: @" ]9 L' G+ t - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+ f, K* h% _8 L$ {' v6 _: W - RCC_OscInitStruct.PLL.PLLQ = 7;* T7 S/ Z. ]' i: P$ }
- HAL_RCC_OscConfig(&RCC_OscInitStruct);. |0 d6 ~& ]+ \+ O& l! Z
- 5 W3 m8 y& e% N; ^
- /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 . w$ I/ n$ a t
- clocks dividers */
+ G1 }+ {3 R+ {" `7 L* T% l - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); u" Q" F- C w
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ G' o3 F; U: o8 X& @ - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;& K) b% w" m3 r) k* m$ L
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; ( t% Y4 f" \6 f- I
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; . d4 T7 r3 {' y; S6 S' H8 p5 f/ U7 T
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);3 _0 j$ Z* h9 x3 h; K# a
1 P# N7 ~' i' Z7 @2 a- /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
3 e* u1 M+ |2 R# ]1 m - if (HAL_GetREVID() == 0x1001)
3 Z9 S; ^( \$ d/ k/ ]' ` - {
6 A% T* d! M4 E - /* Enable the Flash prefetch */
0 n; O. e7 h# K: B5 s0 { z9 t - __HAL_FLASH_PREFETCH_BUFFER_ENABLE();) S; F& X) e3 a( V- Y" k
- }
" [: \# Z0 ^8 |8 {8 l$ @7 @ - }% w1 ]9 G1 t- _9 J; J( E$ ^
复制代码 6 U" c( o- o( {
归档链接
, K0 Z8 \' ?3 r- I2 K/ BARM CMSIS Driver 学习 之 SPI
0 q# ~8 p5 l( B. q
$ P+ G+ C: |- G) `9 t4 B( l3 q" s |
这个出来有几年了,只不过之前没有现在全,现在可以用到项目里了,底层驱动 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"));6 u" o+ |5 [* B/ _
while(1);& ~: C: p T+ `9 `) B7 G ~3 z
}/ A4 ^' ~) q; @5 A7 g; A* v: j
程序运行到Driver_USART2.Send就卡在这一行 无法运行到while那里 同时发送的内容也没发出去
不知道咋回事????
{ v1 N; M4 c2 W. j% `3 C3 s7 I
if(event & ARM_USART_EVENT_RX_TIMEOUT)
{" J: F7 f( Q6 j7 c) b1 o! t
Driver_USART2.Control(ARM_USART_ABORT_RECEIVE, 1);
) y" s3 v( e0 P- E
uint32_t length = Driver_USART2.GetRxCount();7 @: M d& H0 [( C5 g+ u/ @# x
// memcpy(txBuffer, rxBuffer, length);7 T$ ~7 B+ O7 i/ X! I _& E: _% T
// , Z! P: A _! b" `2 e
// Driver_USART1.Send(txBuffer, length);
Driver_USART2.Receive(USART2_RxBfr, sizeof(USART2_RxBfr));# J d8 A, {( c8 w2 [
}
else if(event & ARM_USART_EVENT_SEND_COMPLETE). C& t( P. u6 m4 S( s
{
__NOP();
}+ k' D) L% Y9 [3 m% @$ C* M3 a
else if(event & ARM_USART_EVENT_RECEIVE_COMPLETE)/ D2 p2 ]1 v# x1 m4 P% K1 }8 j
{
__NOP();! K. X; `( C: o M
}$ g$ a' R3 B" i; P
}9 l1 E: K& M/ z7 c
从电脑端的串口工具发送内容 也没产生串口回调事件 不知道咋回事?????
{//usb- n0 s7 e/ N9 P
Driver_USART2.Initialize(USART2_Callback);0 `: P# A0 V3 L3 w" D4 A$ \; u8 O
Driver_USART2.PowerControl(ARM_POWER_FULL);
Driver_USART2.Control(ARM_USART_MODE_ASYNCHRONOUS |5 x) a: J8 C, J$ }' I
ARM_USART_DATA_BITS_8 |4 q [1 y: ]. j* w V
ARM_USART_PARITY_NONE |2 D* O' F7 w1 v8 }1 x. B9 ~" ^ m
ARM_USART_STOP_BITS_1 |
ARM_USART_FLOW_CONTROL_NONE, Brate9 _5 g# ], O$ U) m
);
/* Enable Receiver and Transmitter lines */& D5 e+ h# ]: [7 |
Driver_USART2.Control(ARM_USART_CONTROL_TX, 1);
Driver_USART2.Control(ARM_USART_CONTROL_RX, 1);$ J! I9 b0 J) e! {6 ^- y- d
/* Begin to receive */
Driver_USART2.Receive(USART2_RxBfr, sizeof(USART2_RxBfr)); F: ^2 _1 _1 v& M/ u3 Y
}9 ~$ J0 y$ d' C q8 Z
这是串口初始化