芯片基本外设配置
8 k1 \) h! w) p; ^/ s& S* y1 n4 h0 F在SYS里面开启Serial Wire调试接口% d$ B7 O% T) q5 \: n
在RCC里面使能HSE (Crystal/Ceramic Resonator)7 a4 q" e" _( A: X
配置时钟树
- r9 K2 `- w3 v1 W+ E选中“HSE”、"PLLCLK",在HCLK(MHz)中输入64,回车,软件会自动配置数值。0 P' s; o# c5 j" r% H' p8 L- |! G% x
' o q/ v" y8 V M" k7 j
/ l$ k7 n2 s B7 G( f8 n) w0 d
3 {% @8 N* ?+ u7 M* ^# g 配置USART1外设7 W' N' ^. |: `- i6 h' S, S
在connectivity选项卡中,选择"USART1",在mode中选择:Asynchronous(异步通讯)+ @, Y2 |, G7 m' Y, [' H
! v& a+ d/ F$ Q: N$ U {在“Parameter Settings”中设置基本参数,参数可以自定义,但是通讯双方一定要相同
% K: c2 [" g3 }9 v4 ~! {( x/ m; i- N3 [( u& ?
Baud Rate(波特率):115200,常用有4800,9600。& _; e2 U& M A9 h
- Z/ J- L; y( { ?5 cWord Length(数据位):8,可选7、8、9
6 |, }: P. \% m) Y) ?2 F7 |" r5 Y4 h4 J4 q$ B/ B; J# B
Parity(校验位):None,可选None、Even、Odd
z" x0 i* \% Y5 r4 n% p& h* L' N0 |4 t/ x' ^
Stop Bits(停止位):1,常用有1、2、0.5、1.5% b% {+ z& G3 v' `+ Q
# B Q0 p; X; |9 N! _
其他参数默认值。
9 x. a/ B6 M+ |! y( `, Q: B3 x- w' Z! w" u0 K; f+ n$ H, g
3 W8 ^. b b* w
0 o) k, V# H) \9 d: M, w, Q9 K 生成代码后,在MDK软件中打开,在debug中设置“Reset and Run”。0 a+ N3 Z; k; r! r! U: j+ }
) U1 j% i5 u+ ]" @( F
使用串口的三种方法(直接调用hal库、printf、中断方式)
6 `1 n1 _4 G# _" Z7 i. Y* H8 f第一种方法(直接调用HAL库)1 Y$ ]' h' W1 ?& ?3 l$ X6 [
在int main()主函数中写入如下代码) c+ F! j. X7 Q8 f% h7 B% {
( t8 {! r* W1 M! k+ H- uint8_t temp_buf[1]="c"; //定义一个数组,这个数组长度可以自定义3 c# p; w3 ^4 K( g& Y: [# X N4 B9 f1 z
- while (1)
- N! q0 B! @- w - {
* S1 T4 A2 [6 d; X* H - /* USER CODE END WHILE */
, j) I7 n" Q4 N; y - /* USER CODE BEGIN 3 */3 ?5 \- k( ?9 `
- HAL_Delay(1000);
2 o- f6 v: f# f - HAL_UART_Transmit(&huart1,temp_buf,1,10); //使用usart1串口每一秒发送字符c
3 j9 K% G) _) d: s% q: [* j" P, K; \ - }
复制代码- uint8_t temp_buf=109; //定义整数,+ Q8 P$ E- N9 ? R2 S
- while (1)2 X) E6 Y* ?2 ]
- {
$ }9 i& F1 g' b1 N8 h - /* USER CODE END WHILE */
: |/ `, A! }' |5 ]5 ?' P D0 T - /* USER CODE BEGIN 3 */( O+ J( F/ g$ ^2 Z$ t+ g' _
- HAL_Delay(1000);
; `, \* {3 b% l; M - HAL_UART_Transmit(&huart1,&temp_buf,1,10); //使用usart1串口每一秒发送字符m. M# ?, J) e1 ^3 v( A
- }
复制代码- 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>
复制代码 A3 T0 m4 e" {! ~; s4 m
UART_HandleTypeDef *huart:指定串口,usart1就是&huart1。usart2就是改为&huart2。
( X6 Q; }8 h+ t+ G$ b+ L) Q) f7 l( N( B' w) {
uint8_t *pData:就是要发送的数据
, O' n3 Z: H, c! ^# y R7 C7 Y
3 r# W& u3 |% f5 {+ x* Auint16_t Size:单位为字节,至少要比发送数据长度要大。' S8 |& D3 R+ R# A
# @ u' F, |+ @' s. T0 ^5 d6 \uint32_t Timeout:超时时间
9 F% \* z$ z- ~/ H( y
- ?9 {- O) {8 i$ a% o第二种方法(printf)9 i: U: z8 u3 c) E" a
在main.c文件中添加头文件" H, S% S: Z" h4 Y
6 o6 R0 O" Y$ _% l- ?2 d3 a' @main.c文件中加入重定向函数 ,代码中添加了#ifdef宏定义进行条件编译,如果使用GUNC编译,则PUTCHAR_PROTOTYPE 定义为int __io_putchar(int ch)函数,否则定义为int fputc(int ch, FILE *f)函数
0 K/ }3 b% o9 }( G/ _" b5 O- /* USER CODE BEGIN 0 */
- w1 m. ^* m% R+ N* {, R - #ifdef __GNUC__
?# b0 K5 z& |5 L2 k. v, ` - /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
2 i9 ?9 h0 O; ?/ ? - set to 'Yes') calls __io_putchar() */: g" f4 |/ Y5 a$ l7 L u
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
, Q* n4 U# V2 u& |/ s3 v/ E - #else
' ^. j `$ S0 i+ f - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
7 ^% T) @$ }6 W - #endif /* __GNUC__ */) m# Y) ~7 D& Z8 ]+ ^6 [: Y+ |2 ]
- /**6 E e5 A) w( L& z
- * @brief Retargets the C library printf function to the USART.4 h! c3 h; O+ v) U
- * @param None
! o' J$ P8 I7 T: H0 f - * @retval None
& u: B$ {( g4 ^+ V) h; G: S, Q* W! f - */
$ W& C) g6 E7 i9 ] - PUTCHAR_PROTOTYPE
% n3 c" Z p& A7 n# Q% X/ Z; B9 D& h - {
4 z2 {9 ?( B* i: e( X+ \ - /* Place your implementation of fputc here */3 ~4 k" p: i, S% f) Y
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
8 {( X, i9 @8 ^/ b; C - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
, x. s. u! t0 q - ) ^4 \6 ~$ j0 N' m' ?
- return ch;+ `: t4 Y' l1 g4 W
- }7 `8 I# K( s1 \$ j" W
- /* USER CODE END 0 */
复制代码
" j% I9 a& i/ v; ^% u在int main主函数while循环中加入代码
4 O" k, c7 T r - while (1). Q* f6 _+ u+ q) k
- {
" H/ s" m8 j" E - /* USER CODE END WHILE */
. V" g: J6 S" A1 l" j( K1 y - /* USER CODE BEGIN 3 */: G3 [" D' v/ o3 I3 M
- HAL_Delay(1000); //延时一秒钟输出字符b
: ^* {5 B* j0 \8 f - printf("b\r\n"); / V( j9 w+ Y& [ e. J
- }$ c6 h8 u% ?+ H5 P; W: [# E
- /* USER CODE END 3 */
复制代码
& Z) r% I7 X7 v2 g6 D第三种方法(使用中断)
5 n8 L/ S3 e- W0 G5 |* E; x0 [在CubeMX中,设置USART1全局中断使能,然后重新生成代码。
+ p( s( |# H0 w$ M, \' Q n: I, B7 ^7 o$ A) g1 g) ^
) B" ?* f+ h2 n+ D+ P% {
' M l% W6 e) u! K4 W" ]在main.c文件中定义变量! E% P) W, p9 ?) T2 y9 T
- uint8_t TX_Buff[]="THIS IS A MESSAGE!\r\n"; //发送缓存
, ?0 b) I" I! ?! E; t2 W' Q - uint8_t RX_Buff[2]; //接收缓存
复制代码
3 U$ V3 _' I. b; x$ N3 w. H 在int main主函数中,MX_USART1_UART_Init();后面写入串口输出函数& x7 F# l1 N2 S2 r# u8 b) S
- HAL_UART_Transmit_IT(&huart1,TX_Buff,sizeof(TX_Buff)); //用于第一的串口输出信息
复制代码 4 [$ j+ S0 [0 J' X* K
在while(1)循环中,加入接收中断函数( t% L S& f1 q4 o; z/ Z
- /*
/ y! |$ u9 u5 n/ s# h6 C* i9 f - *2表示缓冲字节,发送的字节数要于缓冲的一致。如果发送长度小于2,则等到2字节后再显示出来
$ ~6 @! C& `0 K4 m+ c1 g9 x - */. T$ W1 b$ o% M3 L5 h; E. ~
- HAL_UART_Receive_IT(&huart1,RX_Buff,2);
复制代码
) ?; C: m! d5 s7 s再int main函数后面写上中断回调函数
8 M3 |) Z# a& @; D- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- k; Q0 w/ h# K. Y& [3 ^" ]( a+ _; W9 t - {
6 J, z! L5 h" F2 A7 J$ j$ t: R - UNUSED(huart);
. d2 [1 t: Z2 f* w - HAL_UART_Transmit(&huart1,(uint8_t*)RX_Buff,2,100); , z5 i2 [# |9 K0 [/ @. z9 h
- }
复制代码
) I/ X8 a3 B8 @0 D编译,下载到开发板即可
3 F7 q2 d4 f2 ^* k6 g p# U4 J5 s2 y/ }! L
6 U& @4 Y* k h8 x, {" h
& \ B' N I. T0 M+ w+ n4 \
|
每日学习小技巧,提升看得见
谢谢分享,学习一下