我是靠谱客的博主 激动大山,这篇文章主要介绍STM32串口数据收发 相关配置+点灯控制,现在分享给大家,希望可以做个参考。

目录

    • 1.串口通信
    • 2.串口的结构体
    • 3.如何配置串口的发送
    • 4.通过串口向电脑发送ok字符
    • 5.封装发送字符串函数
    • 6.重定向printf串口发送
    • 7.串口输入控制LED灯开关

1.串口通信

在这里插入图片描述
我用的32是stm32f10x最小系统没有UART4和UART5
USART : 通用同步异步收发器
UART : 通用异步收发器
nRTS : 请求发送
nCTS : 请求接收
区别:USART指单片机的一个IO端口模块,可以根据需要配置成同步模式(SPI,IIC),也可以配置成异步模式(UART).可以理解为USART为SPI,IIC对等的”协议”。 UART则不是一个协议,为一个实体。

2.串口的结构体

在这里插入图片描述
在这里插入图片描述
Fck : 串口的时钟(APB1 36M / APB2 72M )
USARTDIV : 无符号的定点数

115200= 72 * 1000000/16 * USARTDIV

3.如何配置串口的发送

1.配置时钟: GPIO口的时钟,串口的时钟, 引脚复用的时钟
2.配置GPIO的结构体
3.配置串口的结构体
4.串口的发送
在这里插入图片描述

4.通过串口向电脑发送ok字符

在这里插入图片描述

按照上面的四个步骤进行编写
我们会发现只能一个一个发送字符,比较麻烦,所以后面封装了一个可以发送字符串的函数。
usart.c文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "usart.h" #include "stm32f10x.h" void usart_init(void) { GPIO_InitTypeDef gpio_init; USART_InitTypeDef usartStruct; //1.初始化相关时钟以及 IO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //2.1 TX gpio_init.GPIO_Mode = GPIO_Mode_AF_PP; gpio_init.GPIO_Pin = GPIO_Pin_9|; gpio_init.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA,&gpio_init); //2.2 RX gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING; gpio_init.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA,&gpio_init); //3.串口工作模式设置 usartStruct.USART_BaudRate = 115200; usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; usartStruct.USART_Parity = USART_Parity_No; usartStruct.USART_StopBits = USART_StopBits_1; usartStruct.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&usartStruct); USART_Cmd(USART1, ENABLE ); }

usart.h文件

复制代码
1
2
3
4
#include "stm32f10x.h" void usart_init(void);

main.c文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stm32f10x.h" #include "led.h" #include "delay.h" #include "exti.h" #include "usart.h" int main() { usart_init(); while(1) { USART_SendData(USART1,'n'); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1,'t'); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1,'n'); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); delay_ms(1000); } }

5.封装发送字符串函数

注意:在封装发送字符串函数时,while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);是为了把数据发送完
usart.c文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "usart.h" #include "stm32f10x.h" void usart_init(void) { GPIO_InitTypeDef gpio_init; USART_InitTypeDef usartStruct; // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //2.1 TX gpio_init.GPIO_Mode = GPIO_Mode_AF_PP; gpio_init.GPIO_Pin = GPIO_Pin_9; gpio_init.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA,&gpio_init); //2.2 RX gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING; gpio_init.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA,&gpio_init); usartStruct.USART_BaudRate = 115200; usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; usartStruct.USART_Parity = USART_Parity_No; usartStruct.USART_StopBits = USART_StopBits_1; usartStruct.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&usartStruct); USART_Cmd(USART1, ENABLE ); } //·发送单个字节 void usartSendByte(USART_TypeDef* USARTx, uint16_t Data) { USART_SendData(USARTx,Data); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } //发送字符串 void usartSendStr(USART_TypeDef* USARTx,char *str) { uint16_t i = 0; do{ usartSendByte(USARTx,*(str+i)); i++; }while(*(str+i) != ''); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); }

usart.h

复制代码
1
2
3
4
5
6
7
#include "stm32f10x.h" void usart_init(void); void usartSendByte(USART_TypeDef* USARTx, uint16_t Data); void usartSendStr(USART_TypeDef* USARTx,char *str);

main.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stm32f10x.h" #include "led.h" #include "delay.h" #include "exti.h" #include "usart.h" int main() { usart_init(); while(1) { usartSendStr(USART1,"nice !rn"); delay_ms(1000); } }

6.重定向printf串口发送

要使用printf,我们需要添加#include <stdio.h>头文件(学过c的都应该知道吧)

记得要给下图框住的内容打勾哦
在这里插入图片描述

stdio.h文件中有一个宏定义fputc,我们需要使用printf只需要重定向fputc就可以使用啦
在这里插入图片描述

usart.h

复制代码
1
2
3
4
5
6
7
8
#include "stm32f10x.h" #include <stdio.h> void usart_init(void); void usartSendByte(USART_TypeDef* USARTx, uint16_t Data); void usartSendStr(USART_TypeDef* USARTx,char *str);

usart.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "usart.h" #include "stm32f10x.h" void usart_init(void) { GPIO_InitTypeDef gpio_init; USART_InitTypeDef usartStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //2.1 TX gpio_init.GPIO_Mode = GPIO_Mode_AF_PP; gpio_init.GPIO_Pin = GPIO_Pin_9; gpio_init.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA,&gpio_init); //2.2 RX gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING; gpio_init.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA,&gpio_init); usartStruct.USART_BaudRate = 115200; usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; usartStruct.USART_Parity = USART_Parity_No; usartStruct.USART_StopBits = USART_StopBits_1; usartStruct.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&usartStruct); USART_Cmd(USART1, ENABLE ); } void usartSendByte(USART_TypeDef* USARTx, uint16_t Data) { USART_SendData(USARTx,Data); while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); } void usartSendStr(USART_TypeDef* USARTx,char *str) { uint16_t i = 0; do{ usartSendByte(USARTx,*(str+i)); i++; }while(*(str+i) != ''); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET); } int fputc(int ch,FILE *f) { USART_SendData(USART1,(uint8_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch); }

main.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "stm32f10x.h" #include "led.h" #include "delay.h" #include "exti.h" #include "usart.h" #include "stdio.h" int main() { usart_init(); GPIO_SetBits(GPIOA, GPIO_Pin_3); GPIO_SetBits(GPIOC, GPIO_Pin_13); while(1) { int i = printf("Finnyrn"); printf("%drn",i); delay_ms(1000); } }

图下为什么i不是5而是7呢,因为rn各占了1
重定向fputc不只可以使用printf还可以使用putchar,大伙可以试试呀

7.串口输入控制LED灯开关

输入o让led灯打开并输出Open LED light success,输入c让led灯关闭并输出Close LED light success
提示: main.c中会看见有外部中断的代码,这是之前做震动感应灯的点此进入 STM32 EXTI(外部中断)

led.h

复制代码
1
2
3
4
#include "stm32f10x.h" void Led_init(void);

led.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "stm32f10x.h" #include "led.h" void Led_init(void) { GPIO_InitTypeDef Led_init; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); Led_init.GPIO_Mode = GPIO_Mode_Out_PP; Led_init.GPIO_Pin = GPIO_Pin_13; Led_init.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &Led_init); }

usart.h

复制代码
1
2
3
4
5
6
7
8
#include "stm32f10x.h" #include <stdio.h> void usart_init(void); void usartSendByte(USART_TypeDef* USARTx, uint16_t Data); void usartSendStr(USART_TypeDef* USARTx,char *str);

usart.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "usart.h" #include "stm32f10x.h" void usart_init(void) { GPIO_InitTypeDef gpio_init; USART_InitTypeDef usartStruct; NVIC_InitTypeDef nvic_initStruct; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //2.1 TX gpio_init.GPIO_Mode = GPIO_Mode_AF_PP; gpio_init.GPIO_Pin = GPIO_Pin_9; gpio_init.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA,&gpio_init); //2.2 RX gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING; gpio_init.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA,&gpio_init); usartStruct.USART_BaudRate = 115200; usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; usartStruct.USART_Parity = USART_Parity_No; usartStruct.USART_StopBits = USART_StopBits_1; usartStruct.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&usartStruct); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); USART_Cmd(USART1, ENABLE ); nvic_initStruct.NVIC_IRQChannel = USART1_IRQn; nvic_initStruct.NVIC_IRQChannelPreemptionPriority = 1; nvic_initStruct.NVIC_IRQChannelSubPriority = 1; nvic_initStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_initStruct); } void usartSendByte(USART_TypeDef* USARTx, uint16_t Data) { USART_SendData(USARTx,Data); while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); } void usartSendStr(USART_TypeDef* USARTx,char *str) { uint16_t i = 0; do{ usartSendByte(USARTx,*(str+i)); i++; }while(*(str+i) != ''); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET); } int fputc(int ch,FILE *f) { USART_SendData(USART1,(uint8_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch); } int fgetc(FILE *f) { while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int) USART_ReceiveData(USART1); }

main.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "stm32f10x.h" #include "led.h" #include "relay.h" #include "exti.h" #include "usart.h" #include "stdio.h" int main() { Led_init(); Relay_Init(); exti_init(); usart_init(); GPIO_SetBits(GPIOA, GPIO_Pin_3); GPIO_SetBits(GPIOC, GPIO_Pin_13); } void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus( EXTI_Line1 ) != RESET) { GPIO_ResetBits(GPIOA, GPIO_Pin_3); usartSendStr(USART1,"Open light successrn"); delay(1000); GPIO_SetBits(GPIOA, GPIO_Pin_3); usartSendStr(USART1,"Close light successrn"); } EXTI_ClearFlag(EXTI_Line1); } void USART1_IRQHandler(void) { char temp; if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET){ temp = USART_ReceiveData(USART1); if(temp == 'o'){ GPIO_ResetBits(GPIOC, GPIO_Pin_13); usartSendStr(USART1,"Open LED light successrn"); } if(temp == 'c'){ GPIO_SetBits(GPIOC, GPIO_Pin_13); usartSendStr(USART1,"Close LED light successrn"); } } }

看原文 点这里
请添加图片描述

最后

以上就是激动大山最近收集整理的关于STM32串口数据收发 相关配置+点灯控制的全部内容,更多相关STM32串口数据收发内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(93)

评论列表共有 0 条评论

立即
投稿
返回
顶部