USART 串口通信配置步骤

在上面的介绍中,可能有的朋友很不理解,不过没有关系,下面我们讲解如何使用库函数对 USART 进行配置。这个也是在编写程序中必须要了解的。具体步骤如下:(USART 相关库函数在 stm32f10x_usart.c 和 stm32f10x_usart.h文件中)

(1)使能串口时钟及GPIO端口时钟

前面说过 STM32F103ZET6芯片具有 5 个串口,对应不同的引脚,串口1 挂接在 APB2 总线上,串口 2-串口 5 挂接在 APB1 总线上,根据自己所用串口使能总线时钟和端口时钟。例如使用 USART1,其挂接在 APB2 总线上,并且 USART1 对应 STM32F103ZET6 芯片管脚的PA9 和 PA10,因此使能时钟函数如下:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能 GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);// 使 能USART1时钟

(2)GPIO 端口模式设置,设置串口对应的引脚为复用功能

因为使用引脚的串口功能,所以在配置 GPIO 时要将设置为复用功能,这里把串口的 Tx 引脚配置为复用推挽输出, Rx 引脚为浮空输入,数据完全由外部输入决定。如下:

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX //串口输出PA9GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化串口输入IO */GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX //串口输入PA10GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //模拟输入GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化 GPIO */

(3)初始化串口参数,包含波特率、字长、奇偶校验等参数

要使用串口功能,必须对串口通信相关参数初始化,其库函数如下:

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef*USART_InitStruct);

想必不用说,大家也知道第一个参数是什么意思,它是用来选择串口。第二个参数是一个结构体指针变量,结构体类型是 USART_InitTypeDef,其内包含了串口初始化的成员变量。下面我们就来看下这个结构体:

typedef struct{  uint32_t USART_BaudRate; //波特率  uint16_t USART_WordLength; //字长  uint16_t USART_StopBits; //停止位  uint16_t USART_Parity; //校验位  uint16_t USART_Mode; //USART 模式  uint16_t USART_HardwareFlowControl; //硬件流控制} USART_InitTypeDef;

下面就来简单介绍下每个成员变量的功能:

USART_BaudRate:波特率设置。常用的波特率为 4800、9600、115200 等。

标准库 函 数 会 根 据 设 定 值 计 算 得 到 USARTDIV 值 , 并 设 置

USART_BRR 寄存器值。

USART_WordLength:数据帧字长。可以选择为 8 位或者 9 位, 通过 USART_CR1寄存器的 M 位的值决定。如果没有使能奇偶校验控制,一般使用 8 数据位;如果使能了奇偶校验则一般设置为 9 数据位。

USART_StopBits:停止位设置。可选 0.5 个、 1 个、 1.5 个和 2 个停止

位, 它设定 USART_CR2 寄存器的 STOP[1:0]位的值, 一般我们选择 1 个停止位。

USART_Parity:奇偶校验控制选择。可选 USART_Parity_No( 无 校 验 ) 、USART_Parity_Even( 偶 校 验 ) 以 及 USART_Parity_Odd( 奇 校 验 ) ,它设 定USART_CR1 寄存器的 PCE 位和 PS 位的值。

USART_Mode:USART模式选择。可以为 USART_Mode_Rx 和 USART_Mode_Tx,允许使用逻辑或运算选择两个,它设定 USART_CR1 寄存器的 RE 位和 TE 位。

USART_HardwareFlowControl:硬件流控制选择。只有在硬件流控制模式才有效,可以选择无硬件 流 USART_HardwareFlowControl_None、RTS 控制USART_HardwareFlowControl_RTS、CTS 控制USART_HardwareFlowControl_CTS、RTS 和CTS 控制USART_HardwareFlowControl_RTS_CTS。

了解结构体成员功能后,就可以进行配置,例如我们配置 USART1,如下:

USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600;//波特率设置USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1

(5)使能串口

配置好串口后,我们还需要使能它,使能串口库函数如下:

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);

例如我们要使能 USART1,如下:

USART_Cmd(USART1, ENABLE); //使能串口 1

(6)设置串口中断类型并使能

对串口中断类型和使能设置的函数如下:

void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,FunctionalState NewState);

第一个参数用来选择串口,第二个参数用来选择串口中断类型,第三个参数用来使能或者失能对应中断。由于串口中断类型比较多,所以使用哪种中断,我们就需要对它进行配置。比如在接收到数据的时候( RXNE 读数据寄存器非空),我们要产生中断,那么我们开启中断的方法是:

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断

又比如我们发送完数据时,要产生中断,可以配置如下:

USART_ITConfig(USART1,USART_IT_TC, ENABLE);

对应的串口中断类型可在stm32f10x_usart.h 中查找到,如下:

#define USART_IT_PE ((uint16_t)0x0028)#define USART_IT_TXE ((uint16_t)0x0727)#define USART_IT_TC ((uint16_t)0x0626)#define USART_IT_RXNE ((uint16_t)0x0525)#define USART_IT_IDLE ((uint16_t)0x0424)#define USART_IT_LBD ((uint16_t)0x0846)#define USART_IT_CTS ((uint16_t)0x096A)#define USART_IT_ERR ((uint16_t)0x0060)#define USART_IT_ORE ((uint16_t)0x0360)#define USART_IT_NE ((uint16_t)0x0260)#define USART_IT_FE ((uint16_t)0x0160)

(7)设置串口中断优先级,使能串口中断通道

在上一步我们已经使能了串口的接收中断, 只要使用到中断, 就必须对NVIC初始化,NVIC 初始化库函数是 NVIC_Init(),这个在前面讲解 STM32 中断时就已经介绍过,不清楚的可以回过头看下。

(8)编写串口中断服务函数

最后我们还需要编写一个串口中断服务函数, 通过中断函数处理串口产生的相关中断。串口中断服务函数名在 STM32F1 启动文件内就有,USART1 中断函数名如下:

USART1_IRQHandler

因为串口的中断类型有很多,所以进入中断后,我们需要在中断服务函数开头处通过状态寄存器的值判断此次中断是哪种类型,然后做出相应的控制。库函数中用来读取串口中断状态标志位的函数如下:

ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_tUSART_IT);

此函数功能是判断 USARTx的中断类型 USART_IT 是否产生中断, 例如我们要判断 USART1 的接收中断是否产生,可以调用此函数:

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){...//执行 USART1接收中断内控制}

如果产生接收中断,那么调用 USART_GetITStatus 函数后返回值为 1,就会进入到if 函数内执行中断控制功能程序。否则就不会进入中断处理程序。

在编写串口中断服务函数时,最后通常会调用一个清除中断标志位的函数,如下:

void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);

第二个参数为状态标志选项,可选参数可在 stm32f10x_usart.h中查找到,如下:

#define USART_FLAG_CTS#define USART_FLAG_LBD#define USART_FLAG_TXE#define USART_FLAG_TC#define USART_FLAG_RXNE#define USART_FLAG_IDLE#define USART_FLAG_ORE#define USART_FLAG_NE#define USART_FLAG_FE#define USART_FLAG_PE

比如本实验中判断串口进入接收中断后, 我们就会把串口接收寄存器内数据读取出来,然后再通过串口发送至上位机,等待发送完成后我们就会清除发送完成标志位 USART_FLAG_TC。代码如下:

void USART1_IRQHandler(void) //串口 1中断服务程序{  u8 r;  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断  {    r =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据    USART_SendData(USART1,r);    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);  }  USART_ClearFlag(USART1,USART_FLAG_TC);}

串口接收函数是:

uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

串口发送函数是:

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

库函数中还有一个函数用来读取串口状态标志位:

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_tUSART_FLAG);

USART_GetITStatus 与 USART_GetFlagStatus 功 能 类 似 , 区 别 就 是USART_GetITStatus 函数会先判断是否使能串口中断,使能后才读取状态标志,而 USART_GetFlagStatus函数直接读取状态标志。

将以上几步全部配置好后,我们就可以正常使用串口中断了。

硬件设计

在我们开发板上,含有一个 USB 转串口,一个 RS232串口。

通过 CH340 芯片把 STM32F1 的串口 1 与 PC 机的USB 口进行连接,实现串口通信。电路是按照 RS232 接口标准搭建,使用了一个 DB9 的公头和母头,电平转换芯片使用的是 SP3232,与 MAX3232 一样。母头可作为下位机和上位机 PC 进行串口通信,公头可作为上位机和其他母头设备进行串口通信,当然也可以和计算机的公头进行通信,需使用交叉型串口线。

软件设计

本章所要实现的功能是:STM32F1 通过 USART1 实现与 PC 机对话,STM32F1的 USART1 收到 PC 机发来的数据后原封不动的返回给 PC 机显示。同时使用 D1指示灯不断闪烁提示系统正常运行。程序框架如下:

(1)初始化 USART1,并使能串口接收中断等

(2)编写 USART1 中断函数

(3)编写主函数

在前面介绍串口配置步骤时,就已经讲解如何初始化串口。下面我们打开

“USART 串口通信实验”工程,在 Public 工程组中可以看到添加了 usart.c 文件,在 StdPeriph_Driver 工程组中添加了stm32f10x_usart.c 库文件。串口操作的库函数都放在 stm32f10x_usart.c 和stm32f10x_usart.h 文件中,所以使用到串口就必须加入 stm32f10x_usart.c文件,同时还要包含对应的头文件路径。

USART1初始化函数

要使用串口中断,我们必须先对它进行配置。USART1 初始化代码如下:

/***************************************************************** 函 数 名 : USART1_Init* 函数功能 : USART1 初始化函数* 输 入 : bound:波特率* 输 出 : 无******************************************************************/void USART1_Init(u32 bound){//GPIO 端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);/* 配置 GPIO 的模式和IO 口 */GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX //串口输出 PA9GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化串口输入IO */GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX //串口输入 PA10GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //模拟输入GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化 GPIO *//*USART1 初始化设置*/USART_InitStructure.USART_BaudRate = bound;//波特率设置USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8 位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_Cmd(USART1, ENABLE); //使能串口 1USART_ClearFlag(USART1, USART_FLAG_TC);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断/*Usart1 NVIC配置*/NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;// 抢 占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化 VIC 寄存器、}

在USART1_Init()函数中, 首先使能 USART1 串口及端口时钟, 并初始化GPIO为复用功能。其次配置串口结构体 USART_InitTypeDef,使能串口并开启接收中断,为了防止串口发送状态标志位的影响,我们清除下串口状态标志位(TC),最后配置相应的 NVIC 并使能对应中断通道, 我们将 USART1 的抢占优先级设置为3,响应优先级设置为 3。这一过程在前面步骤介绍中已经提了。

USART1_Init()函数有一个参数 bound,用来设置 USART1 串口的波特率,方便大家修改。

USART1中断函数

初始化 USART1 后, 接收中断就已经开启了, 当上位机发送数据过来, STM32F1的串口接收寄存器内即为非空,触发接收中断,具体代码如下:

/***************************************************************** 函 数 名 : USART1_IRQHandler* 函数功能 : USART1 中断函数* 输 入 : 无* 输 出 : 无*****************************************************************/void USART1_IRQHandler(void){  u8 rec_data;  char r2='b';  char r3='c';    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //½ÓÊÕÖÐ¶Ï  {    rec_data =USART_ReceiveData(USART1);//(USART1->DR);  //¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý    if(rec_data == '2')    {      USART_SendData(USART1,r2);      led2=!led2;      delay_ms(3000);      while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);    }    else if(rec_data == '3')    {      USART_SendData(USART1,r3);      led3=!led3;      delay_ms(3000);      while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);    }    LED_Init();  }   USART_ClearFlag(USART1,USART_FLAG_TC);}

为了确认 USART1 是否发生接收中断,调用了读取串口中断状态标志位函数USART_GetITStatus,如果确实产生接收中断事件,那么就会执行if内的语句,将串口接收到的数据保存在变量 r 内,然后有通过串口发送出去,通过USART_GetFlagStatus 函数读取串口状态标志, 如果数据发送完成, 则退出while循环语句,且清除发送完成状态标志位 USART_FLAG_TC。

主函数

编写好串口初始化和中断服务函数后,接下来就可以编写主函数了,代码如

下:

/**************************************************************** 函 数 名 : main* 函数功能 : 主函数* 输 入 : 无* 输 出 : 无****************************************************************/int main(){u8 i=0;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2 组LED_Init();USART1_Init(9600);while(1){i++;if(i%20==0){led1=!led1;}delay_ms(10);}}

主函数实现的功能很简单,首先调用之前编写好的硬件初始化函数,包括

SysTick 系统时钟,中断分组,LED 初始化等。然后调用我们前面编写的USART1初始化函数,这里我们设定串口通信波特率为 9600。最后进入 while 循环语句,不断让 D1 指示间隔 200ms 闪烁。如果发生接收中断事件,即会进入中断执行,执行完后回到主函数内继续运行。

其实如果你学会了 USART1的使用,对于其他的串口都是类似的。

Labview程序

实验现象

将工程程序编译后下载到开发板内,可以看到 D1 指示灯不断闪烁,表示程序正常运行。打开Labview程序,选择FALSE或者TRUE,上位机分别发送‘1’、‘2’到下位机,可以分别看到触发中断发生时D1熄灭,同时D2或者D3闪亮,之后read buffer接受到单片机发送给上位机的‘b’或者‘c’。

windows通信端口初始化失败_STM32实例——USART串口通信实验(二)相关推荐

  1. 【分享】windows通信端口初始化失败

    What happened? 今天清理垃圾的时候不小心清理过度了,关闭了一些不该关闭的项目,结果电脑就生病了,一下子出现了这个问题---"windows通信端口初始化失败",导致上 ...

  2. win10 mysql初始化失败_win10电脑中windows通信端口初始化失败的解决教程

    在电脑汇总,都会存在很多不同的端口,比如通讯端口.网络端口等,然而有不少win10系统用户在使用电脑的时候,却出现了windows通信端口初始化失败的情况,这该怎么办呢,不用担心,接下来随win7之家 ...

  3. 与网络通信相关的服务和应用进程无法加载和启动、windows通信端口初始化失败

    打开任何需要连网的软件,就提示"与网络通信相关的服务和应用进程无法加载和启动"."windows通信端口初始化失败". 在 cmd 运行 NETSH WINSO ...

  4. Windows通信端口初始化失败

    Windows通信端口初始化失败 系统症状: 启动之后出现蓝屏现象,且持续时间较长,在3分钟左右,系统提示"Windows通信端口初始化失败"的对话框,但 QQ等网络应用软件不能正 ...

  5. windows7通信端口初始化失败解决方案

    今天睡得有点迟,洗漱完毕后迅速离开寝室赶公交去.到了公司一打开电脑,360软件跳出了是否要阻止XX进程,我没怎么在意,就随便阻止了.问题来了,不管你开QQ.开IE,只要是跟网络有关的软件,双击后就是弹 ...

  6. 计算机端口丢失,通信端口初始化失败怎么解决 通信端口初始化失败解决方法...

    电脑给我们的日常生活带来了许多方便,也拓宽了我们的视野,也让我们的生活变得丰富多彩起来,现在不管是大家的工作还是生活都处处离不开电脑的.但是我们在平常使用电脑的时候经常会出现一些麻烦和问题,比如说有时 ...

  7. 服务器芯片组初始化失败怎么办,通信端口初始化失败是怎么回事 初始化失败解决方法...

    通信端口初始化失败是怎么回事? 随着计算机网络技术的发展,原来物理上的接口(如键盘.鼠标.网卡.显示卡等输入/输出接口)已不能满足网络通信的要求,TCP/IP协议作为网络通信的标准协议就解决了这个通信 ...

  8. windows通信端口初始化失败_三菱Q系列PLC以太网通信设置方法(内置以太网和外置以太网模块)...

    今天来用三菱PLCQ13UDEH和组态王6.55 开始通信操作,用Melsec_Ethernet.dll(60.3.14.30)驱动.用这个驱动的时候应当注意,选择"允许RUN中写入(FTP ...

  9. windows通信端口初始化失败_【PLC编程入门】西门子S7200PLC之间的PPI通信

    01PPI通信定义 PPI协议是西门子S7-200PLC之间交换信息的专用协议,PPI协议是一种点对点协议,它只定义了一次通信中的主从问题,西门子编程软件与CPU进行通信同样使用PPI协议,同样下载时 ...

最新文章

  1. Maven学习总结(6)——Maven与Eclipse整合
  2. 英国EE:启动TechCity 2.0 首期将部署LTE-Advanced Pro
  3. APM-应用性能管理
  4. 【ABAP】带PDF附件的邮件发送功能
  5. VTK修炼之道23:图像基本操作_灰度图像映射成伪彩色图像(查表法)
  6. Spring学习(24)--- AOP之 Aspect instantiation models(aspect实例模式)特别说明
  7. mysql odbc.ini_ODBC连接mysql
  8. java 泛型 擦除_Java泛型和类型擦除
  9. NodeJS + Lighthouse + Gulp 搭建自动化网站性能测试工具
  10. 不会编程,如何做自动化测试
  11. linux qt读取显示图片,QT学习篇(二) 使用QPixmap显示一张图片
  12. ARM汇编指令MCR/MRC学习
  13. Python初学笔记(4)
  14. w7计算机不显示移动硬盘,Win7移动硬盘在电脑上不显示盘符的解决办法
  15. 【NDN IoT】NDN-ACE: Access Control for Constrained Environments over Named Data Networking 全文翻译
  16. 笔记本电脑上html怎样运行,手提电脑如何进入BIOS|笔记本电脑进入BIOS按哪个键...
  17. Java 最全面的面试题675道
  18. Java 8 Stream流的常见操作
  19. 各大跨境电商卖家不容错过下半年的促销活动安排
  20. ESIM模型的“全能版”!网易易盾实验室研究员解读HIM混合推理模型

热门文章

  1. Android知识点汇总以及常见面试题
  2. python 计算机程序设计-某高校计算机编程教授教你如何快速入门python,一文带你进入编程...
  3. python软件如何下载-python软件怎么样?实际的操作方法来了
  4. python有趣小程序-知道了这个,你也能写出 Python 趣味小程序
  5. python能做什么工作-python能做哪方面的工作
  6. python编程入门视频-带学《Python编程:从入门到实践》
  7. 传统语音识别(GMM+HMM)
  8. 苹果版App开发心得
  9. php生成站点地图,php生成百度站点地图sitemap.xml
  10. python数据科学手册_数据科学的Python