芯片基本外设配置; q. Z; C9 M* `9 H! Z! Z, }
在SYS里面开启Serial Wire调试接口
( i: O$ v2 g, m在RCC里面使能HSE (Crystal/Ceramic Resonator)
+ m. t% |) G# |+ S/ e配置时钟树
, R& |% E- s, F" [4 g2 x4 H- v+ a选中“HSE”、"PLLCLK",在HCLK(MHz)中输入64,回车,软件会自动配置数值。
! B6 e/ T9 C0 ~4 A$ D, h0 Q
3 C8 q$ ]2 t+ l7 @* V. l: c* \ x9 c4 A7 S0 T
: o' S5 H% S/ c/ _4 F$ D, {" i
配置USART1外设% A/ P8 E( C0 F* z% g2 K
在connectivity选项卡中,选择"USART1",在mode中选择:Asynchronous(异步通讯)9 z% X- g$ s9 t( G
' X# |9 T7 b5 f8 J在“Parameter Settings”中设置基本参数,参数可以自定义,但是通讯双方一定要相同
E6 U& x( H. V( K S
" Q: g' m# u( L0 |3 ZBaud Rate(波特率):115200,常用有4800,9600。1 F s V: W) C% I( \0 {: s4 p
; Q. U" r: O d" \; L4 @. j
Word Length(数据位):8,可选7、8、9, f. O1 c9 u, |9 r+ v2 n m8 i
- X, ^$ C6 {# J1 s8 UParity(校验位):None,可选None、Even、Odd8 P; u# S5 t- {4 y
6 l4 R+ R! s, h& OStop Bits(停止位):1,常用有1、2、0.5、1.5
$ _+ Y$ q( ~* y4 I. ^9 O% i Z) P' u9 ]( R6 Z$ Z# J r6 b6 h$ Y/ K
其他参数默认值。8 c+ |4 ?0 l8 _" O# l
2 M5 n) r- r$ b4 h& T; C
0 q8 h4 I) {( u6 T& J. P0 W0 Z! z* g8 b, F
生成代码后,在MDK软件中打开,在debug中设置“Reset and Run”。 T1 t) V( o% ]
0 u5 t; g: H7 l& w3 r' E* z' o f `使用串口的三种方法(直接调用hal库、printf、中断方式); b! _/ H) p& X; X* }& l/ @) }
第一种方法(直接调用HAL库). B' ~0 L* w1 r" Q
在int main()主函数中写入如下代码
/ {' t& ~8 o6 S& J3 |, ~/ N0 [- S. s. R+ ~& ?
- uint8_t temp_buf[1]="c"; //定义一个数组,这个数组长度可以自定义
, g( Z% i$ @0 H" y0 c7 Z - while (1)
( L0 h: {. ?$ X4 h! s* M. g9 A - {
0 r) R6 s' r+ u - /* USER CODE END WHILE */
0 r! u. ~ ? {5 Y2 Z1 U - /* USER CODE BEGIN 3 */
* Z: _' T; v2 Q, s0 O/ n - HAL_Delay(1000);
4 ?) K3 h0 m$ a! q- g9 b - HAL_UART_Transmit(&huart1,temp_buf,1,10); //使用usart1串口每一秒发送字符c
2 l% S: j" ]# }5 e$ w - }
复制代码- uint8_t temp_buf=109; //定义整数,( @# X- ?3 H' e/ A; ^: d L
- while (1)5 _0 U2 t% G9 i1 Q. H
- {" ~( v5 v; _1 p' [# u+ J
- /* USER CODE END WHILE */
7 r" k* f; O6 z5 ~% d1 A @ - /* USER CODE BEGIN 3 */
. E* ]/ a/ i* U: B- }& [7 X. ^ - HAL_Delay(1000);
$ U6 P" f, e- v/ z+ y! A - HAL_UART_Transmit(&huart1,&temp_buf,1,10); //使用usart1串口每一秒发送字符m3 w" ?' D3 f- n1 z3 {( L, w/ _7 E
- }
复制代码- HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout<span style="background-color: rgb(255, 255, 255);">)</span>
复制代码
/ B/ w I7 _' _UART_HandleTypeDef *huart:指定串口,usart1就是&huart1。usart2就是改为&huart2。
7 b c% W& |& e$ O2 F: l# @6 ]4 y2 r+ v# b/ x
uint8_t *pData:就是要发送的数据
) t7 \, ?! |8 V2 l. Z+ \* `! ]! ^" q! b; B
uint16_t Size:单位为字节,至少要比发送数据长度要大。
6 _. m: k7 h" p9 o) Y- L1 d# c9 |6 n
uint32_t Timeout:超时时间
+ ~& E u _0 i' I% w9 H. Z4 y& X3 \
第二种方法(printf)
' M% y7 a; _, B在main.c文件中添加头文件
; B9 m, F i& a# L. [
& ]3 L6 _5 k5 g0 ?0 ?8 f& ~# Tmain.c文件中加入重定向函数 ,代码中添加了#ifdef宏定义进行条件编译,如果使用GUNC编译,则PUTCHAR_PROTOTYPE 定义为int __io_putchar(int ch)函数,否则定义为int fputc(int ch, FILE *f)函数
5 L& b; t8 Q$ P0 b/ D Q( w- /* USER CODE BEGIN 0 */
1 t) k$ m- Z0 g: i, ] - #ifdef __GNUC__
3 [! S/ H8 z& }- q7 k( _% Q - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf( o4 O9 P& K z7 H, r
- set to 'Yes') calls __io_putchar() */
3 G d$ M. g5 ?/ z - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)% c, I( _# o% o1 B* @5 M
- #else
3 ^5 b9 O5 k* r, K8 t2 K4 Q - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
[, E6 e {$ t# v - #endif /* __GNUC__ */& ]0 }) r9 l: g; _9 n+ l( l( F
- /**0 C3 w3 z6 u: e$ ~1 R
- * @brief Retargets the C library printf function to the USART.. a: Z: e; ~1 o- P5 O
- * @param None
9 t0 d% I# `0 _! l, B x - * @retval None" G$ I, o) S8 n" W$ u) a5 R
- */8 k) n# `7 I! c9 [
- PUTCHAR_PROTOTYPE* m( W( {$ M; u1 ^7 P
- {! {0 X/ d$ ^; K3 e* b! _
- /* Place your implementation of fputc here */
2 O8 c' K: M6 H( V - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
# X2 [+ ^: f8 }. e - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
$ Q. z7 Y* H, q6 p
, a$ ]; k: k8 _) E2 S- return ch;1 H7 M) q, v% r+ P* y; H3 |" U
- }" `/ u- B5 |# P) r7 @) J% e, \" q
- /* USER CODE END 0 */
复制代码 : ]$ b# _2 z& H7 C' ?- {: T7 n+ }
在int main主函数while循环中加入代码 $ U2 T) Y( t) N1 j* J. ?4 l9 n" g
- while (1)
$ {$ V5 v/ j% w) J- D$ ^2 O - { V" P" a( E+ S" x1 ~1 `9 E
- /* USER CODE END WHILE */
3 K2 B) W' G; { - /* USER CODE BEGIN 3 */) j1 V+ B, l1 T+ M. l
- HAL_Delay(1000); //延时一秒钟输出字符b: T2 i! ?9 o! ~) }' t1 E9 @0 R
- printf("b\r\n");
5 c+ L& N; \% [) C- L: z - }
( Y5 j2 U, s) p' m E- F - /* USER CODE END 3 */
复制代码 $ M! z3 B. a4 Z
第三种方法(使用中断) - l8 Z5 r2 s3 c2 ?! Z) L7 t9 t
在CubeMX中,设置USART1全局中断使能,然后重新生成代码。
: }7 j4 r0 P ~* S8 x1 t5 H6 K
3 i/ {8 _4 o* x( s* G& p3 r
6 C7 I ]9 J- W) a
! z6 X# n3 ?5 h. H! J+ p在main.c文件中定义变量
}& T1 g4 n" i- uint8_t TX_Buff[]="THIS IS A MESSAGE!\r\n"; //发送缓存+ q7 w; ~: h6 ^8 I
- uint8_t RX_Buff[2]; //接收缓存
复制代码
8 g$ h. f4 e/ `) ] 在int main主函数中,MX_USART1_UART_Init();后面写入串口输出函数
/ E7 h, {5 b* b7 P- HAL_UART_Transmit_IT(&huart1,TX_Buff,sizeof(TX_Buff)); //用于第一的串口输出信息
复制代码 / S- w- Z1 v5 o( a4 g9 v
在while(1)循环中,加入接收中断函数 y: i! N" @8 z: K3 _
- /*7 A; _# k: i7 W. V- G8 U
- *2表示缓冲字节,发送的字节数要于缓冲的一致。如果发送长度小于2,则等到2字节后再显示出来
* E/ E# }7 l" h; } - */% o$ V8 j) `8 h! t
- HAL_UART_Receive_IT(&huart1,RX_Buff,2);
复制代码
- I9 K4 K6 Y; ^' O再int main函数后面写上中断回调函数
4 H ~$ S( z0 h* Y) e, Y; H4 Y- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
' G7 i. Z Z: i! r* ? `1 u - {
6 d. t# o a i+ a0 v! x - UNUSED(huart);, z$ r) o* K( O. p' @, f3 f& N
- HAL_UART_Transmit(&huart1,(uint8_t*)RX_Buff,2,100); # v# N2 @2 O* K6 R
- }
复制代码 4 s$ e8 f0 F/ J
编译,下载到开发板即可
( ?; @4 R+ x: `7 x# F7 H) a2 q0 d" f0 l4 o% u
& L h. n4 e; {5 P! w. C& _
- @! K: ~2 g3 `% a$ O1 P |
每日学习小技巧,提升看得见
谢谢分享,学习一下