串口通讯 (Serial Communication) 是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。
8 Z; P# f4 T" a. C, X! {( |
' O6 L3 {" c& c8 ~" S& k6 g一.物理层
5 h: g0 J- C8 n6 r1.标准- p3 W7 l9 U; U8 o1 M6 U L4 S* I
根据通讯使用的电平标准不同,串口通讯可分为 TTL 标准及 RS-232 标准,RS-232相对TTL有更强的抗干扰能力和传输距离。STM32 的 USART 输出的是 TTL 电平信号,若需要 RS-232 标准的信号可使用 MAX3232 芯片进
5 K6 z0 N: G: @/ {$ W行转换。7 `, s# X/ w& r1 U b1 w
6 v5 \9 W9 v' m% e1 |
! x$ d3 o- E, }+ F
2 L! s4 M; S0 n! \: [* V3 f4 f2.波特率
/ a2 v8 J9 s, ^% c+ J9 r) \" v A串口通讯是异步通信,异步通讯中没有时钟信号,所以两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码。
: p4 x& l$ F# M; X- t6 F8 k/ X( \
- E, ~* m, E" S& d3.引脚
2 ~- W- A+ {( }6 hTX:发送数据输出引脚。
6 f2 m% [$ p1 Y* b2 yRX:接收数据输入引脚。9 k) U$ I$ @ l( H- C1 V
(与单片机相连接时,TX----RX,RX------TX)
* `# X- o! u' f9 k6 O
, n& c1 W- Q2 j% P' ]/ a5 Q6 X% a: W7 T$ G4 O* k
二.代码层- HAL_UART_Transmit();串口发送数据,使用超时管理机制
* x( Q- d/ ~% R' Z - HAL_UART_Receive();串口接收数据,使用超时管理机制 O* ^' p% Q# k) |
- HAL_UART_Transmit_IT();串口中断模式发送 & r4 D/ N9 i4 R7 Y; ` ?
- HAL_UART_Receive_IT();串口中断模式接收
- A* w: |7 b5 d - HAL_UART_Transmit_DMA();串口DMA模式发送
4 H/ c0 b( o9 Z+ S! U) q - HAL_UART_Transmit_DMA();串口DMA模式接收
. z- N6 Z& m+ b5 Z6 P( z
复制代码
5 I, _" b! K6 D) n9 O6 T6 b9 H/ D+ B: _. x1.发送函数/ v4 u9 I, n3 \0 |* c" z3 C
- HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
复制代码 7 X" N" d! Q5 k) ]7 E6 ]/ {
; z* l- A! Q- d. l5 S1 b3 g9 v# p
, O, ^8 X1 u# }- C# F这里图片引自Z小旋博主的文章
' X, K4 `4 x7 D* u0 d7 N4 h% f8 p. E* |) V% B9 T4 \
: T$ B; ~0 Y& a1 ^7 t! E2.中断接收
8 L, G8 o4 p- {# e S0 y- HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)6 M2 I3 x7 q) @4 D. L
复制代码- 举例: HAL_UART_Receive_IT(&huart1,(uint8_t *)&value,1); //中断接收一个字符,存储到value中5 w+ }0 t6 e- I$ }
复制代码
- [# j+ w# S' s3.回调函数
! V( G) j+ m, K! W, m) q' C* f- HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); 4 i* F' f4 F. K5 u; `
复制代码
( J3 c( H- j1 z- i+ Q4 ?在程序发生中断后,并不会立即结束,会先完成回调函数里面的内容,所以这里可以将想要执行的代码放入回调函数中
, u# k+ T8 H# }4 y5 y. z! L6 M( R" c
4.重定义- r$ ]" L# |" Z' k5 y0 R7 l+ y. I
在代码中可直接使用printf打印数据来检测数据5 P6 b& l( R+ J: P
- /**, z: |1 O1 @2 `. c
- * 函数功能: 重定向c库函数printf到DEBUG_USARTx9 V1 c1 v" g. y
- * 输入参数: 无
0 L$ I6 Z. t) N1 o' S6 f& l - * 返 回 值: 无& y& I* ~1 [4 s! [, |
- * 说 明:无
0 [+ h* B% a+ ?5 J$ ?0 m - */* T3 K% r4 N ^. |! N
- int fputc(int ch, FILE *f)/ D# X4 |4 E3 A2 y+ v
- {. l8 y# S' }2 y
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);8 D+ C1 a& p c, }8 _0 C$ O7 h
- return ch;- O2 v! y1 @1 E/ D. i2 m, z
- }/ t I' G7 N4 V8 J$ J: i
- ! w4 G O! \( |+ h. V- K
- /**
# z x- d% V( r9 i: } - * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx6 d4 H j3 y p( r' b% A
- * 输入参数: 无8 q9 }+ g, B! o7 {/ {) k
- * 返 回 值: 无- c K3 d4 K1 e$ n- O' |# n
- * 说 明:无1 G3 [$ @/ E Z9 I
- */) U7 `6 a" O- E8 K8 W5 J8 G
- int fgetc(FILE *f)
9 H, w3 L( x+ x. J# h7 B3 q - {
" H' U9 j1 @0 @# P - uint8_t ch = 0;
2 g& _8 @2 G+ C: K: o2 E8 G - HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
0 J1 q2 l% S& z; O - return ch;. T9 ?# Q' {, b6 _: }, x
- } @7 f) {5 \- {; g% {0 `
复制代码
. s( B7 l( X( J* d5.上位机: S) {3 W3 }5 ]
常用上位机就是串口调试助手,有vofa+,等各种方便的软件,波特率一定要和配置里面的对应
3 R# t8 k# m* K4 b* O
3 a0 U! M6 Y1 i) i5 ]+ t4 F7 @6.串口中断8 Q, b I) w1 f( e2 W+ C4 e
在cubemx中配置好中断之后,声明. X: I6 y8 }: {' c. [* W8 l
HAL_UART_Receive_IT(&huart1,usart1_rx,6);$ @* O( S1 Q ~: u
在main函数下添加回调函数* [) ~. ?) R( f! M8 ~
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) e0 j5 g3 | [1 ~+ W
- {
. Z0 r0 x6 ~( f! H7 i, G - if(huart->Instance == USART1) // 判断是由哪个串口触发的中断, @) ~+ n& L2 w* P* q+ \
- {
) G0 P( b* l" Q- X - HAL_UART_Transmit(&huart1,usart1_tx,6,100); //发送 指针 数组 字节 时长
1 a0 O* Q# i4 {9 C - HAL_UART_Receive_IT(&huart1,usart1_rx,6);6 W$ Y% X3 f) b* V3 B
- }
4 q0 E& |8 z+ x- P9 o* A; [ - }
* c6 U5 a" Z& M# x) q- |, w) n
复制代码
# E t Q& D0 `4 N2 R4 I. w串口打印
2 F$ h5 }) j. M+ q
! D: P8 V. i4 r |4 r, A% J
: S# E+ M6 G7 J9 i# |: q2 y) r! O7 Q! D
! ^. x" N) y5 E每次中断结束都要在回调函数重新开启中断,否则中断里的内容只执行一次
8 u6 L: d6 _. k- W; K————————————————& y$ c2 E# m+ t2 W5 H3 ?
版权声明:地球先生_
x B5 N5 O) N$ R1 \; _7 W. J: v, V8 E: \8 G
8 q6 o/ L; E) E; o; p
|