芯片基本外设配置
+ Y) m6 I; e, w& \在SYS里面开启Serial Wire调试接口
& S( {0 O0 u( o9 O在RCC里面使能HSE (Crystal/Ceramic Resonator)
; J3 Z! U N8 y4 G1 ^) k配置时钟树( e' g' P+ O7 R3 H: p: | Z
选中“HSE”、"PLLCLK",在HCLK(MHz)中输入64,回车,软件会自动配置数值。
9 I2 v c9 i+ M/ w; @& a5 Z" b* A! `7 N" R
1 f; E9 C: T1 J, w5 F" [' `, y& t: u- \- k, D( @; N! C2 h7 i
配置USART1外设
" [; Y) H( I b; H0 t在connectivity选项卡中,选择"USART1",在mode中选择:Asynchronous(异步通讯)7 I# y% W; l U9 l& |- u% P
) v$ P8 p9 Z# |* \在“Parameter Settings”中设置基本参数,参数可以自定义,但是通讯双方一定要相同
7 Q2 P' j% G$ D* |) Q( {) e& f
5 q h, y* c; [ ]2 @# `) p2 dBaud Rate(波特率):115200,常用有4800,9600。
# I' H% |# s) ]* k. z' Q9 }: u* \
1 |$ A/ V* g0 p2 m4 n" ?Word Length(数据位):8,可选7、8、9
* ^: s# {, x. e: D
( L4 E1 K) l. A% L0 W HParity(校验位):None,可选None、Even、Odd
! w5 o+ ?4 }: S& ~& }% n; w& {" m
) l7 `% T7 a8 S: W; {Stop Bits(停止位):1,常用有1、2、0.5、1.50 P; K& f9 }: U3 i! J% r U' B& |
& o. i% z$ A, p6 j" X# T/ Q% T其他参数默认值。
3 o" @2 S' g: r( {) l
+ T i {+ u5 O
2 G& U2 C+ P5 j3 p0 L8 x: Y% J1 y7 {$ k( ?' s5 V" ^
生成代码后,在MDK软件中打开,在debug中设置“Reset and Run”。. s( y, c+ V2 Z* p0 y% Q6 }
3 ?- K) a" `! ?2 \9 d. `
使用串口的三种方法(直接调用hal库、printf、中断方式)! o+ G& \7 [ z1 \
第一种方法(直接调用HAL库)9 ^( M e2 E, I. L8 K9 i
在int main()主函数中写入如下代码
8 \' J( G% \2 f/ q
9 @* [. K; E3 g% `2 Z1 g- uint8_t temp_buf[1]="c"; //定义一个数组,这个数组长度可以自定义7 b% a8 a: g- N# L) o) C
- while (1)
" k- u) P% g2 Z5 A/ |4 {# ?1 \) c$ B - {' y, g: @: E: W3 R
- /* USER CODE END WHILE */
9 [1 K- W9 |( V+ \+ h! i - /* USER CODE BEGIN 3 */
U% S4 U/ p. W4 ~) V+ u3 ] - HAL_Delay(1000);
+ x! t1 p9 G7 t; x m( V* g - HAL_UART_Transmit(&huart1,temp_buf,1,10); //使用usart1串口每一秒发送字符c3 o. ~) ^2 b8 D0 i) F/ E
- }
复制代码- uint8_t temp_buf=109; //定义整数,' \ ~- j3 T, C z
- while (1)) P- O. k) o; w9 t
- {0 U# i, V6 j5 C
- /* USER CODE END WHILE */; \6 Q4 ?8 K) g# q8 R7 y
- /* USER CODE BEGIN 3 */5 j1 b: k6 R$ _6 f( F6 P) @. Y( F; d& |
- HAL_Delay(1000);
: t# C, {$ H% U1 {5 v3 j - HAL_UART_Transmit(&huart1,&temp_buf,1,10); //使用usart1串口每一秒发送字符m
, b( |6 d% C4 o6 F - }
复制代码- 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>
复制代码
6 |3 |. f# i; p y/ d" UUART_HandleTypeDef *huart:指定串口,usart1就是&huart1。usart2就是改为&huart2。
1 g$ E" ?/ {* v+ j. C! z; `6 Z
1 ]! {! G5 @- Huint8_t *pData:就是要发送的数据. e0 p, u* G8 n9 _. T/ u7 [
: {7 N: r0 j7 \! a$ Q( y
uint16_t Size:单位为字节,至少要比发送数据长度要大。
' y7 a; E/ y/ s+ C0 a c! w" ?
2 Z+ O; \1 r& m4 nuint32_t Timeout:超时时间$ |! `) D6 T' F1 M# i/ t
8 E+ S6 V8 ?* V) e. q2 \; V' Y( }
第二种方法(printf)/ I( ]. i6 L0 e0 `
在main.c文件中添加头文件
; x: E4 M* D! z/ `. V/ V6 {3 @4 I; @/ Y: I
main.c文件中加入重定向函数 ,代码中添加了#ifdef宏定义进行条件编译,如果使用GUNC编译,则PUTCHAR_PROTOTYPE 定义为int __io_putchar(int ch)函数,否则定义为int fputc(int ch, FILE *f)函数1 v; _* x+ }+ a% j
- /* USER CODE BEGIN 0 */* s/ ?) S) v5 t. Z
- #ifdef __GNUC__& a8 k6 v Q6 Q) u! `& B0 V I- Y
- /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf1 p) C: ]* J% ~0 f# v
- set to 'Yes') calls __io_putchar() */7 V( u$ ^- P+ m. n
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)$ n. E& H3 s, {; N
- #else
) j8 v) k+ x. W. V- g5 l1 C - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
1 y6 F- T3 f0 b2 t1 a7 b8 x - #endif /* __GNUC__ */
6 U( q' _ E q; Y4 p- |- X - /**
8 n" t( M2 }. x r - * @brief Retargets the C library printf function to the USART.4 O {; j$ h2 u: v$ @
- * @param None" L# p6 s! c/ G. i6 n+ x% G
- * @retval None$ w4 B+ y' e5 x' {9 L
- */
* B$ x( D: N) A! S$ w% @ - PUTCHAR_PROTOTYPE
* e, B& V5 b m) ? - {, R8 T; Z5 a8 b9 P4 w
- /* Place your implementation of fputc here */
$ C4 Q) s# F1 b0 r - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */& M5 {. M' \! H* w2 n( ~: L# c
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);4 _6 M% w7 y4 B; h) T$ E- t$ ]& S
8 [" o# F) D# p- return ch;) ]! P# C* r0 x5 V
- } u) |+ R/ d6 S' m* W
- /* USER CODE END 0 */
复制代码 8 b) k3 O! O4 G. d& l
在int main主函数while循环中加入代码
4 D6 }/ }3 w& C+ i3 f - while (1)
# F2 ~) H Q( G4 ]' r) A - {
4 c* v& n% K% p M - /* USER CODE END WHILE */7 c6 r w3 H ^% y% k
- /* USER CODE BEGIN 3 */5 b. K0 h. f2 Y, P
- HAL_Delay(1000); //延时一秒钟输出字符b
8 y) n7 I3 ^4 ~: C2 q/ l$ x - printf("b\r\n"); + |, u3 A8 ^- Q/ m. I
- }
( [& e& ?- @ B8 r. t# M - /* USER CODE END 3 */
复制代码
" e( ~) {4 T0 {) j7 n3 h% v( g/ J- _ R第三种方法(使用中断)
$ f. V* Z- r4 [% A: {在CubeMX中,设置USART1全局中断使能,然后重新生成代码。$ Q1 S9 x* G; y- R7 k5 k. }
9 _( f& r# \: e) y! I2 H
. f: ^: k+ o j9 p! i3 d6 ?5 {7 K2 }, ^( F" t+ ~
在main.c文件中定义变量
1 n% G" L- v* _1 V3 A% m- uint8_t TX_Buff[]="THIS IS A MESSAGE!\r\n"; //发送缓存6 s3 J3 m$ A/ |) h$ F3 i5 [6 U
- uint8_t RX_Buff[2]; //接收缓存
复制代码
; h& v5 C& { k9 G 在int main主函数中,MX_USART1_UART_Init();后面写入串口输出函数' w) B7 s0 U, n6 P; v' g% e7 b& o# E
- HAL_UART_Transmit_IT(&huart1,TX_Buff,sizeof(TX_Buff)); //用于第一的串口输出信息
复制代码 , m. u; D0 M+ f
在while(1)循环中,加入接收中断函数
6 r# x8 O8 Y2 Y+ q+ J" I- /*8 i% S* n8 k4 w9 P
- *2表示缓冲字节,发送的字节数要于缓冲的一致。如果发送长度小于2,则等到2字节后再显示出来
, [+ D( l; r9 M6 i, e9 | - */
$ r3 \) t" t) t - HAL_UART_Receive_IT(&huart1,RX_Buff,2);
复制代码
& W: P3 o& l9 f* H0 [再int main函数后面写上中断回调函数
: x. C' s! ~5 s# D; }- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
6 ?2 g/ c& I# f& V$ c! ? V( S( a - {8 S/ A) O+ e) r, n2 q0 `3 `8 P
- UNUSED(huart);
" G9 z9 k5 B- i2 b2 A - HAL_UART_Transmit(&huart1,(uint8_t*)RX_Buff,2,100); 5 g4 _( J) z* o9 }) z2 F; ^+ e, p
- }
复制代码
, O) I( z1 q& S( s: ]编译,下载到开发板即可. }2 o6 I f( u" ~
" p4 H' f# c! _7 P% L
6 R. }. Q0 t( p6 M y" j4 M: X! N; b; c
|
每日学习小技巧,提升看得见
谢谢分享,学习一下