芯片基本外设配置& S2 i) F0 b1 ]& S# V7 P3 s
在SYS里面开启Serial Wire调试接口
- T) Q O8 C" M' F9 t在RCC里面使能HSE (Crystal/Ceramic Resonator)* [2 ]- u+ q0 Q6 _# K
配置时钟树6 |2 u/ e" D* T: n6 G
选中“HSE”、"PLLCLK",在HCLK(MHz)中输入64,回车,软件会自动配置数值。
* g/ _5 ?& f+ k: N5 \
8 x R. `7 D7 W9 c6 w, B) d/ g, Q" m0 F
" a2 A! O1 l1 g4 ?/ l0 J
配置USART1外设/ v$ E x5 J$ ?' i! R. i! @
在connectivity选项卡中,选择"USART1",在mode中选择:Asynchronous(异步通讯)/ t. Y. x8 @+ m% R) s
1 w' R$ _0 k( q% _5 }) f
在“Parameter Settings”中设置基本参数,参数可以自定义,但是通讯双方一定要相同
% I! g. o+ N3 u$ ^ N" n: q& ?* g
* m1 Q" R& ?, ]' k7 k, y. |7 q# `# CBaud Rate(波特率):115200,常用有4800,9600。
8 Z; U, s( o8 p% K8 K( b
/ U9 c( K. K5 v( \( [/ |Word Length(数据位):8,可选7、8、9
~) Q& o1 ~3 ]6 F1 N% y. U5 D8 c7 {
; c& W9 h& _* r. nParity(校验位):None,可选None、Even、Odd+ m$ _) w% f! G* V8 |" `3 u
- s8 {6 A; z% w8 h0 _ x' @4 g& mStop Bits(停止位):1,常用有1、2、0.5、1.5
8 b, o7 \ K$ Z- `) @3 z8 k) f
. Z$ r6 V. l; }0 _+ ^其他参数默认值。6 H* [9 Q5 i; P! B, Y4 M2 B) g# g
' K8 y4 \3 H) \( Q# M$ i" B7 t
0 u. X* j5 S: s# x! n+ m+ R7 m
3 c! P( N* r/ k' Q9 C8 a
生成代码后,在MDK软件中打开,在debug中设置“Reset and Run”。6 ~) o& d. k4 Q) O3 H' [8 }5 K
% H6 u2 u- B. W( a+ I3 b2 A
使用串口的三种方法(直接调用hal库、printf、中断方式)- {: H) d, R/ o$ V
第一种方法(直接调用HAL库) L6 i1 T2 e# z3 s, x, ]
在int main()主函数中写入如下代码
% w; @# [4 L5 l6 w6 H2 u% M* [
" h f$ c j0 b- p1 |, S- uint8_t temp_buf[1]="c"; //定义一个数组,这个数组长度可以自定义
* Z# g2 I% {2 q) C; z- n5 T6 b - while (1)
2 k2 N7 X! u. X% U. X | - {
' c% A3 z1 O% {% f - /* USER CODE END WHILE */: v+ Z4 u, O$ r
- /* USER CODE BEGIN 3 */
0 j: A8 J, Y; D' i8 u2 B T9 ? - HAL_Delay(1000);2 ^, P5 z; h" c: m0 m+ X @+ p
- HAL_UART_Transmit(&huart1,temp_buf,1,10); //使用usart1串口每一秒发送字符c) [4 e& k K* H: ]
- }
复制代码- uint8_t temp_buf=109; //定义整数,! g' i) r7 s% G% L Q/ F
- while (1)
8 K9 Q. \) s$ S% J9 s. U; [1 X - {4 H1 {, t* T1 q# Z# C( k& \
- /* USER CODE END WHILE */1 D8 j# Z! H- {4 \
- /* USER CODE BEGIN 3 */
3 I7 b6 y' x. Q% L: Z8 ^1 S+ V - HAL_Delay(1000);
0 f4 v& F8 i% \ - HAL_UART_Transmit(&huart1,&temp_buf,1,10); //使用usart1串口每一秒发送字符m
+ Y. z i" a+ k" M- u1 Q# { - }
复制代码- 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>
复制代码 ( ^. O% o( B' Q
UART_HandleTypeDef *huart:指定串口,usart1就是&huart1。usart2就是改为&huart2。% a6 n5 A( I7 k; A
. a; ~/ ]& j& _3 I; t l
uint8_t *pData:就是要发送的数据
9 m: |4 w$ a7 E7 C2 @: L6 m! L+ {! l; U3 Y R# B
uint16_t Size:单位为字节,至少要比发送数据长度要大。
8 L" a% H; S: D W1 Z
: P+ F3 j( v/ u5 Juint32_t Timeout:超时时间
( Q7 |& c W1 k3 z# Z' r5 D+ Y% i0 \2 P/ ]* O; |' }
第二种方法(printf)! b' ~# b$ b" E) i* v
在main.c文件中添加头文件0 r( W& r& j, W- D. @: M+ e
% ~2 s1 T6 q# Dmain.c文件中加入重定向函数 ,代码中添加了#ifdef宏定义进行条件编译,如果使用GUNC编译,则PUTCHAR_PROTOTYPE 定义为int __io_putchar(int ch)函数,否则定义为int fputc(int ch, FILE *f)函数7 Z7 M) n K/ J
- /* USER CODE BEGIN 0 */) a e- d, m9 F6 w& e+ X
- #ifdef __GNUC__
: a# E2 U4 o' i' Z! @, I - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf, m4 \4 n. c7 k' z b( a0 \5 ]
- set to 'Yes') calls __io_putchar() *// t& e4 ^. a/ F4 G
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
2 ?( }, ~0 T7 T1 U- \4 B) e3 X - #else
' R9 V4 f5 e! r - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
0 s9 R+ |& O" K, h9 O8 Y1 F: a) r, @ - #endif /* __GNUC__ */
" o, E8 q4 R' L5 b, ^5 k - /**7 A9 e. ^8 Y7 U7 M
- * @brief Retargets the C library printf function to the USART.
, ~1 ^5 V0 b2 b4 W; n - * @param None3 ] p2 J6 m3 Y1 B
- * @retval None- ?6 t) G7 j4 [! A; P2 x
- */
1 ] Y' K# p2 h, R- s3 n - PUTCHAR_PROTOTYPE
* i3 U+ O3 u2 P& G# x* p [ - {
% X7 I! `% v: `; B Z* s5 V2 o! _$ ] - /* Place your implementation of fputc here */# L8 |& `9 e, x7 Y$ A. K, F k# z
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */4 V. E! b$ b' Z* X2 \
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);1 ^3 J8 M' d, {( v. a0 Q
- + t4 e: B0 u0 Y* r4 a
- return ch;
! [" q, f, Z2 s- ~- } - }! W1 ]2 U, s3 x& M* E' f, A
- /* USER CODE END 0 */
复制代码
3 J# K0 I: L& Q, v4 v在int main主函数while循环中加入代码
& h. X; v' n- X) H - while (1)8 S1 c) ^* H/ `( P& q: |7 f
- {
# s6 N; B: s; c - /* USER CODE END WHILE */+ _2 i6 }# }0 h( \0 O3 c* R
- /* USER CODE BEGIN 3 */
' {: X5 `( T' z: T& B - HAL_Delay(1000); //延时一秒钟输出字符b
F# s+ w, U/ t, Q. T1 | - printf("b\r\n"); * ]* R1 ~$ H' u1 T5 i8 ]
- }
% ?3 K9 Z1 v; E2 ~8 s5 R+ b - /* USER CODE END 3 */
复制代码
3 d2 k& \ y: l% n. t& D3 v; |第三种方法(使用中断) 2 y" b0 u" Y1 Z
在CubeMX中,设置USART1全局中断使能,然后重新生成代码。 ]5 T% N( g/ d, M! N% ^, x' }# m
6 y$ }* H4 @' f9 W' u) o
, H# L4 G# O: `! P. k$ M2 B' O4 F: f6 w2 @; ~& k
在main.c文件中定义变量- [- `: I" S) I
- uint8_t TX_Buff[]="THIS IS A MESSAGE!\r\n"; //发送缓存
' H% Y3 q2 J9 n+ F P - uint8_t RX_Buff[2]; //接收缓存
复制代码
0 u4 v( L( R4 d) H* H1 k/ p 在int main主函数中,MX_USART1_UART_Init();后面写入串口输出函数
. U, K' K2 E6 j3 y- a( y/ p- HAL_UART_Transmit_IT(&huart1,TX_Buff,sizeof(TX_Buff)); //用于第一的串口输出信息
复制代码 , P. l8 n R# X
在while(1)循环中,加入接收中断函数8 U: G7 G) O' k( `, H
- /*: v5 | j$ F$ l! `9 ]* L
- *2表示缓冲字节,发送的字节数要于缓冲的一致。如果发送长度小于2,则等到2字节后再显示出来+ H- l: f! ^+ p- w- a; |$ J
- */
: `; \5 c: t& F, W$ b e( U8 w/ K - HAL_UART_Receive_IT(&huart1,RX_Buff,2);
复制代码
% @6 p3 M3 c* {" t! [+ o% H6 Y再int main函数后面写上中断回调函数
- J0 d. o! S3 f& f" s3 p" a# _6 F- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart). v! E' Z% a( I- c- |; ~/ p: P
- { y/ Z8 ?. {. z
- UNUSED(huart);" L: b. g& `( C. q w* J6 i
- HAL_UART_Transmit(&huart1,(uint8_t*)RX_Buff,2,100); % ~# e, D6 d2 }2 u- r% p1 U' A& q
- }
复制代码
, ?6 N* W7 M5 r编译,下载到开发板即可: B, s& Y$ E: |: f
" L& G; X7 b' z
# U8 c6 ?9 q- J& Z
/ {# |0 u( t4 u9 V7 d& X |
每日学习小技巧,提升看得见
谢谢分享,学习一下