串口通信深度剖析(二)

-回复 -浏览
楼主 2018-06-27 01:44:16
举报 只看此人 收藏本贴 楼主

串口通信深度剖析二



串口通信深度剖析一小马哥讲解了串口通信的基础知识、通信协议等,串口通信深度剖析二开始将基于STM32单片机对相关干货实例化,包括单片机端串口通信开发,PC端串口通信开发、Android端、iOS端蓝牙串口通信开发等

其实对于STM32等32位单片机开发初期来说,串口通信更多的是作为一种调试手段,借助于PC端串口上位机可以很方便,直观化对代码进行调试本文将基于此对STM32单片机的USART进行很简单的配置,从而使用printf和scanf进行串口通信交互

对于STM32单片机来说,串口资源是非常丰富的,本文基于STM32F4单片机进行测试,其他系列单片机甚至其他单片机类似;详情可以查看《STM32F4XX中文参考手册》第26单元。

不管是使用库函数方法,亦或寄存器方法配置起来都是非常简单的,这里两者兼提供,首先是库函数模板核心代码:

usart.h头文件

 1#ifndef?__USART_H
2#define?__USART_H
3
4#include?"stm32f4xx.h"
5#include?"stdio.h"
6
7void?USART1_Init(u32?bound);
8
9#endif
10
11/**
12??*?@}
13??*/

14
15/**
16??*?@}
17??*/

18
19/***************?(H)?Chen?Bing?*****END?OF?FILE****/
20


usart.c源文件

 1/******************************************************************************
2*?@?File?name?-->?usart.c
3*?@?Author????-->?By@?Bing?Chen
4*?@?E-mail????-->?chen2725878184@outlook.com
5*?@?Version???-->?V1.0
6*?@?Date??????-->?6?-?20?-?2018
7*?@?Brief?????-->?MCU串口简单配置
8*
9
*?@?Copyright?(C)?20**
10*?@?All?rights?reserved
11*******************************************************************************
12??*???????????????????????????????????Update
13??*
14******************************************************************************/
15
16/*?Includes?------------------------------------------------------------------*/
17#include?"usart.h"
18
19/******************************Code?area************************************/
20
21/*******************************************************************************
22*?@Name?????:?USART1_Init
23*?@brief????:?USART1初始化配置
24*?@Input????:?bound:?串口波特率
25*?@Output???:?None
26*?@retval???:?None
27*******************************************************************************/
28void?USART1_Init(u32?bound)
29{
30????GPIO_InitTypeDef????GPIO_InitStructure;
31????USART_InitTypeDef???USART_InitStructure;
32
33????RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);????????????//使能GPIOA时钟
34????RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);???????????//使能USART1时钟
35
36????GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);?????????//PA9复用为USART1
37????GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);????????//PA10复用为USART1
38
39????GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;??????????????????????//复用功能
40????GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;????????????????????//推挽复用输出
41????GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9?|?GPIO_Pin_10;??? ? ? ? ?//选择USART1对应的管脚:PA9->USART1_TX,PA10->USART1_RX
42????GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;??????????????????????//上拉
43????GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;???????????? ? ?//端口速度100MHz
44????GPIO_Init(GPIOA,&GPIO_InitStructure);???????????????????????????//GPIO端口初始化
45
46????USART_InitStructure.USART_BaudRate=bound;?????????????????????????????????????//串口波特率设置:115200
47????USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;?//设置有无硬件流控制:无
48????USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;???????????????????//模式设置:接收&发送使能
49????USART_InitStructure.USART_Parity=USART_Parity_No;?????????????????????????????//设置有无奇偶校验:无
50????USART_InitStructure.USART_StopBits=USART_StopBits_1;??????????????????????????//设置停止位:1位
51????USART_InitStructure.USART_WordLength=USART_WordLength_8b;?????????????????????//设置数据位:8位
52????USART_Init(USART1,&USART_InitStructure);??????????????????????????????????????//USART1初始化
53
54????USART_Cmd(USART1,?ENABLE);??????//USART1使能
55}
56
57/*******************************************************************************
58*?@Name?????:?fputc
59*?@brief????:?内部调用函数,注意要勾选OPTIONS中的USE?Micro?LIB选项
60*?????????????由于printf执行是调用fputc函数,所以相当于重新定义printf函数
61*?????????????,支持printf()发送数据。
62*?@Input????:?None
63*?@Output???:?None
64*?@retval???:?None
65*******************************************************************************/
66int?fputc(int?ch,FILE?*f)
67{
68????USART_SendData(USART1,(u8)ch);
69????while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);???????//获取串口状态
70????return?ch;
71}
72
73/*******************************************************************************
74*?@Name?????:?fgetc
75*?@brief????:?内部调用函数,注意要勾选OPTIONS中的USE?Micro?LIB选项
76*??????????? ?由于scanf执行是调用fgetc函数,所以相当于重新定义scanf函数
77*?????????????,支持printf()发送数据。
78*?@Input????:?None
79*?@Output???:?None
80*?@retval???:?None
81*******************************************************************************/
82int?fgetc(FILE?*f)
83{
84??while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)?==?RESET);????????//获取串口状态
85??return?(USART_ReceiveData(USART1));
86}
87
88/**
89??*?@}
90??*/
91
92/**
93??*?@}
94??*/
95
96/************************?(C)?Chen?Bing?*****END?OF?FILE****/


main.c源文件

 1/******************************************************************************
2*?@?File?name?-->?main.c
3*?@?Author????-->?By@?Bing?Chen
4*?@?E-mail????-->?chen2725878184@outlook.com
5*?@?Version???-->?V1.0
6*?@?Date??????-->?06?-?20?-?2018
7*?@?Brief?????-->?STM32串口通信交互简单测试
8*
9
*?@?Copyright?(C)?20**
10*?@?All?rights?reserved
11*******************************************************************************
12??*???????????????????????????????????Update
13??*
14******************************************************************************/
15
16/*?Includes?------------------------------------------------------------------*/
17#include
18#include?"delay.h"
19#include?"nvic.h"
20#include?"usart.h"
21#include?"led.h"
22
23int?main(void)
24{
25????u8?s[100];
26
27?? ?delay_init();
28????NVIC_Priority_Init();
29????USART1_Init(115200);
30????LED_Init();
31
32??while(1)
33??{
34????????printf("请随便给我输入点什么:?");
35????????scanf("%s",s);
36????????LED1?=?!LED1;
37????????delay_ms(300);
38????????printf("%s\r\n",s);
39??}
40}
41
42/**
43??*?@}
44??*/
45
46/**
47??*?@}
48??*/
49
50/************************?(C)?Chen?Bing?*****END?OF?FILE****/




下载之后效果如下:

以上是库函数配置核心源码,下面是寄存器配置核心源码:

usart.h头文件

 1#ifndef?__USART_H
2#define?__USART_H
3
4#include?"stm32f4xx.h"
5#include?"stdio.h"
6
7void?USART1_Init(u32?pclk2,u32?bound);
8
9#endif
10
11/**
12??*?@}
13??*/

14
15/**
16??*?@}
17??*/

18
19/************************?(H)?Chen?Bing?*****END?OF?FILE****/


usart.c源文件

 ?1/******************************************************************************
?2*?@?File?name?-->?usart.c
?3*?@?Author????-->?By@?Bing?Chen
?4*?@?E-mail????-->?chen2725878184@outlook.com
?5*?@?Version???-->?V1.0
?6*?@?Date??????-->?06?-?20?-?2018
?7*?@?Brief?????-->?MCU串口简单配置
?8*
?9
*?@?Copyright?(C)?20**
10*?@?All?rights?reserved
11*******************************************************************************
12??*???????????????????????????????????Update
13??*
14******************************************************************************/
15
16/*?Includes?------------------------------------------------------------------*/
17#include?"usart.h"
18
19/******************************Code?area************************************/
20
21/*******************************************************************************
22*?@Name?????:?USART1_Init
23*?@brief????:?USART1初始化配置
24*?@Input????:?pclk2:PCLK2时钟频率(Mhz)????bound:?串口波特率
25*?@Output???:?None
26*?@retval???:?None
27*******************************************************************************/
28void?USART1_Init(u32?pclk2,u32?bound)
29{
30????float?temp;
31????u16?mantissa;
32????u16?fraction;??????
33????temp?=?(float)(pclk2?*?1000000)?/?(bound?*?16);?????//得到USARTDIV@OVER8=0
34????mantissa?=?temp;????????????????????????????????????????????????????????????????????//得到整数部分
35????fraction?=?(temp?-?mantissa)?*?16;??????????????????????????????//得到小数部分@OVER8=0?
36????mantissa?<<=?4;
37????mantissa?+=?fraction;?
38
39????RCC->
AHB1ENR?|=?1?<0;???//使能PORTA口时钟??
40????RCC->
APB2ENR?|=?1?<4;?????//使能串口1时钟?
41
42????/********************************************************************/
43????//PA9->
USART_TX端口初始化配置
44????GPIOA->MODER?&=?~(3?<9?*?2));????//先清除原来的设置
45????GPIOA->
MODER?|=??(2?<9?*?2));????//设置新的模式:复用功能模式
46
47????GPIOA->
OTYPER?&=?~(1?<9)?;????????//清除原来的设置
48????GPIOA->
OTYPER?|=????(0?<9);???????//设置新的输出模式:输出推挽模式
49
50????GPIOA->
OSPEEDR?&=?~(3?<9?*?2)); ?//清除原来的设置
51????GPIOA->
OSPEEDR?|=??(3?<9?*?2)); ?//设置新的速度值:100MHz
52
53????GPIOA->
PUPDR?&=?~(3?<9?*?2));????//先清除原来的设置
54????GPIOA->
PUPDR?|=??(1?<9?*?2));????//设置新的上下拉:上拉模式
55
56????GPIOA->
AFR[1]?|=?0x00000070;????????//复用为AF7->USART1_TX
57
58????//PA10->USART_RX端口初始化配置
59????GPIOA->MODER?&=?~(3?<10?*?2));???//先清除原来的设置
60????GPIOA->
MODER?|=??(2?<10?*?2));???//设置新的模式:复用功能模式
61
62????GPIOA->
OTYPER?&=?~(1?<10)?;???????//清除原来的设置
63????GPIOA->
OTYPER?|=????(0?<10);??????//设置新的输出模式:输出推挽模式
64
65????GPIOA->
OSPEEDR?&=?~(3?<10?*?2)); //清除原来的设置
66????GPIOA->
OSPEEDR?|=??(3?<10?*?2)); //设置新的速度值:100MHz
67
68????GPIOA->
PUPDR?&=?~(3?<10?*?2));???//先清除原来的设置
69????GPIOA->
PUPDR?|=??(1?<10?*?2));???//设置新的上下拉:上拉模式
70
71????GPIOA->
AFR[1]?|=?0x00000700;????????//复用为AF7->USART1_RX
72????/********************************************************************/
73
74????/********************************************************************/
75????//USART1初始化配置
76????USART1->BRR?=?mantissa;?????//波特率设置
77
78????USART1->CR1?&=?~(1?<15);??//设置OVER8=0
79
80????USART1->
CR1?|=?1?<3;??????//串口发送使能
81
82????USART1->
CR1?|=?1?<2;??????//串口接收使能????
83
84????USART1->
CR1?|=?1?<13;?????//串口使能
85????/********************************************************************/
86}
87
88/*******************************************************************************
89*?@Name?????:?fputc
90*?@brief????:?内部调用函数,注意要勾选OPTIONS中的USE?Micro?LIB选项
91*??????????? ?由于printf执行是调用fputc函数,所以相当于重新定义printf函数
92*?????????????,支持printf()发送数据。
93*?@Input????:?None
94*?@Output???:?None
95*?@retval???:?None
96*******************************************************************************/
97int?fputc(int?ch,FILE?*f)
98{
99????while((USART1->
SR?&?0X40)?==?0);
100????USART1->DR?=?(u8)ch;
101
102????return?ch;
103}
104
105/*******************************************************************************
106*?@Name?????:?fgetc
107*?@brief????:?内部调用函数,注意要勾选OPTIONS中的USE?Micro?LIB选项
108*???????????? 由于scanf执行是调用fgetc函数,所以相当于重新定义scanf函数
109*??????????????,支持printf()发送数据。
110*?@Input????:?None
111*?@Output???:?None
112*?@retval???:?None
113*******************************************************************************/
114int?fgetc(FILE?*f)
115{
116 ? ?while((USART1->SR?&?0x20)?==?0);??
117????return?((int)(USART1->DR?&?0X1FF));?
118}
119
120/**
121??*?@}
122??*/
123
124/**
125??*?@}
126??*/
127
128/************************?(C)?Chen?Bing?*****END?OF?FILE****/
129


main.c源文件

 1/******************************************************************************
2*?@?File?name?-->?main.c
3*?@?Author????-->?By@?Bing?Chen
4*?@?E-mail????-->?chen2725878184@outlook.com
5*?@?Version???-->?V1.0
6*?@?Date??????-->?06?-?20?-?2018
7*?@?Brief?????-->?STM32串口通信交互简单测试
8*
9
*?@?Copyright?(C)?20**
10*?@?All?rights?reserved
11*******************************************************************************
12??*???????????????????????????????????Update
13??*
14******************************************************************************/
15
16/*?Includes?------------------------------------------------------------------*/
17#include
18#include?"delay.h"
19#include?"nvic.h"
20#include?"sys.h"
21#include?"usart.h"
22#include?"led.h"
23
24int?main(void)
25{
26????u8?s[100];
27
28????delay_init();???????//初始化延时函数
29????NVIC_Priority_Init();
30????USART1_Init(84,115200);
31????LED_Init();
32
33??while(1)
34??{
35????????printf("请随便给我输入点什么:?");
36????????scanf("%s",s);
37????????LED1?=?!LED1;
38????????delay_ms(300);
39????????printf("%s\r\n",s);
40??}
41}
42
43/**
44??*?@}
45??*/
46
47/**
48??*?@}
49??*/
50
51/************************?(C)?Chen?Bing?*****END?OF?FILE****/
52



寄存器版本下载之后的效果和库函数是一样的


本文相关手册源码工程会打包到串口通信深度剖析三




以上资料仅供学习使用,更多信息请关注微信公众号:

热爱科技 ? ????享受生活

作者:若者

长按二维码关注


往期文章推荐:


硬件设计 | 小马哥DragonFly四轴硬件视频01讲

硬件设计|小马哥DragonFly四轴硬件视频02讲上

硬件设计|小马哥DragonFly四轴硬件视频02讲下

硬件设计|小马哥DragonFly四轴硬件视频03讲上

硬件设计|小马哥DragonFly四轴硬件视频03讲下

硬件设计|小马哥DragonFly四轴硬件视频04讲上

硬件设计|小马哥DragonFly四轴硬件视频04讲下

硬件设计|小马哥DragonFly四轴硬件视频05讲

串口通信深度剖析一(和小马哥聊天记录)

STM32学习教程分享

有奖征稿(初版方案)

关于小芯





合作伙伴同步更新公号内容,欢迎关注:

公号名

步步惊芯

微信号

bubujxin

联系人

小芯


如需帮助,请在下方留言或微信公众号内回复消息





我要推荐
转发到