STM32串口通信

STM32串口通信是一种在STM32微控制器中常用的数据传输方式,它允许设备之间通过串行接口进行数据交换。以下是对STM32串口通信知识点的详细讲解:

一、串口通信的基本概念

串口通信(Serial Communication)是一种设备间常用的串行通讯方式,其通信协议可分层为协议层和物理层。物理层规定通信协议中具有机械、电子功能的特性,从而确保原始数据在物理媒体的传播;协议层主要规定通讯逻辑,统一双方的数据打包、解包标准。

二、STM32串口通信的接口

STM32提供了两种串口通信接口:

  1. UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器):UART是一种异步通信协议,它使用起始位、数据位、校验位和停止位来定义一个字符的传输格式。UART不需要时钟信号,通信双方需要约定好波特率(即每秒传输的码元个数),以便对信号进行解码。

  2. USART(Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步异步收发器):USART是一种同步/异步通信协议,它支持全双工通信,并具备更高的数据传输速率和更好的抗干扰能力。USART在UART的基础上增加了同步通信功能,即可以使用时钟信号来同步数据传输。

三、STM32串口通信的分类

根据数据传输的方向,串口通信可以分为单工、半双工和全双工:

  1. 单工:数据传输只支持数据在一个方向上传输。
  2. 半双工:允许数据在两个方向上传输,但在某一时刻,只允许数据在一个方向上传输。
  3. 全双工:允许数据同时在两个方向上传输,要求发送设备和接收设备都有独立的接收和发送能力。

四、STM32串口通信的配置

在进行STM32串口通信之前,需要对串口通信参数进行配置,这些参数包括波特率、数据位、停止位、校验位等。在STM32中,这些参数可以通过配置相应的寄存器来实现,例如通过配置USART_BRR寄存器可以设置波特率,通过配置USART_CR1和USART_CR2寄存器可以设置数据位、停止位和校验位等参数。

五、STM32串口通信的编程实现

在STM32串口通信编程时,通常会使用HAL库或标准外设库等提供的API函数来配置串口通信参数和发送/接收数据。编程步骤大致如下:

  1. 初始化串口通信参数:使用HAL库或标准外设库提供的函数配置串口通信参数,如波特率、数据位、停止位和校验位等。
  2. 发送数据:使用HAL库或标准外设库提供的发送函数将数据写入串口发送缓冲区,然后等待数据发送完成。
  3. 接收数据:使用HAL库或标准外设库提供的接收函数从串口接收缓冲区读取数据。在接收数据时,需要判断接收缓冲区是否有数据可读,并读取相应的数据长度和格式。
  4. 错误处理:在串口通信过程中,可能会出现各种错误情况,如发送超时、接收溢出等。在编程时,需要添加相应的错误处理代码,以处理这些异常情况。

六、STM32串口通信的应用

STM32串口通信广泛应用于各种嵌入式系统中,如机器人控制系统、工业自动化控制系统、智能家居控制系统等。通过串口通信,STM32微控制器可以与其他设备或上位机进行数据交换,实现远程监控、数据传输等功能。

七、注意事项

  1. 在进行STM32串口通信时,需要确保通信双方的参数设置一致,包括波特率、数据位、停止位和校验位等。
  2. 在设计硬件连接时,需要确保TX和RX引脚正确交叉连接,即发送方的TX连接到接收方的RX,反之亦然。
  3. 如果STM32微控制器需要与PC机或其他使用不同电平标准的设备进行通信,可能需要使用电平转换芯片进行电平转换。

串行通信和并行通信

串行通信:速度教并行慢,但是占用的硬件资源少,通常只需要时钟线,一两根数据线还 有片选线即可。

并行通信:速度快,但是需要很多根数据线、地址线等。

同步通信和异步通信(串行通信)

同步通信:

1.同步是指在约定的通信速率下,发送端和接收端的时钟信号相位始终保持一 致,保证通信双方在发送和接收数据时具有完全一致的定时关系。

2.同步通信把许多字符组成一个信息帧,每帧的开始用同步字符来表示。

3.在绝大多数场合下,发送端和接收端,采用的都是同一个时钟,所以在传送数据的同时还要发送时钟信号,以便接收端可以使用时钟信号来确定每一个信息位。

4.同步通信一次通信只能传送一帧信息。

异步通信:

1.数据是以字符为单位组成字符帧传输的。

2.字符帧由发送端一帧一帧的发送,每帧数据均是低位在前,高位在后,通过传输线被接收端一帧一帧的接收。

3.发送端和接收端可以有各自独立的时钟来控制数据的发送和接收,这两个时钟各自独立,互不同步。

4.接收端依靠字符帧格式来判断发送端是何时开始和结束发送的。

5.字符帧也叫做数据帧,由起始位,数据位,奇偶校验位,停止位等部分组成, 是异步通信的一个重要指标。

6.同步通信的另一个重要指标是波特率

常见的通信协议:

电平特性:

TTL与232

接口标准:

串口传输协议:

参数概念:

波特率:一般选波特率都会有9600,19200,115200等选项,其实意思就是每秒传 输这么多个比特数(bit)。 起始位:先发出一个逻辑 ‘0’的信号,表示传输数据的开始。

数据位:可以是5~8位逻辑 “0” 或“1”,先传输Bit0,再传输bit1,以此类推。 校验位:数据位加上这一位之后,使得“1”的位数应为偶数(偶校验)或者奇数(奇校 验),以此来校验数据传送的正确性,校验位是可选的,可以不传输。 停止位:它是一个字符数据的结束标志,数据线变回逻辑“1”。

STM32F103的USART资源

1. STM32103有三个通用同步异步收发器USART,两个通用异步收发器UARTUSART

也可以当作UART使用。

2. 通常使用的是UART功能,USART在某些场合会使用到,选择通信方式使用场合决 定。

3. 可以通过电平转化芯片变为RS232/RS485电平。

STM32F103的UART框图

端口引脚

1. TX:数据发送端口

2. RX:数据接收端口

3. SW_RX:在单线和智能卡模式下接收数据,属于内部端口,没有实际的外部引脚

4. RTS:在硬件流控制下用于指示设备准备好可以接收数据了,低电平表示可以接收数 据。

5. CTS:在硬件流控制下用于指示设备以及发送完数据了,如果是高电平那么在本次数据 发送完成后会阻塞下一次的传输,只有在低电平的时候才允许下一次传输。

6. CK:同步时钟端口,在同步通信模式下使用,用于输出同步时钟信号。

实现串口通信实战

相关函数讲解:

//异步收发器
typedef struct{
uint32_t USART_BaudRate;            //波特率    配置波特率 115200/9600
uint16_t USART_WordLength;          //字长      配置控制数据位的字长: 
                                                //八位/九位
uint16_t USART_WordLenth;           //停止位    配置停止位 0.5,1,1,5,2
uint16_t USART_Parity;              //校验位    配置校验位 无,奇,偶
uint16_t USART_Mode;                //USART模式  配置工作模式  收/发
uint16_t USART_HardwareFlowControl; //硬件流控制    
}USART_InitTypeDef;

//同步收发器
typedef struct{
uint16_t USART_Clock;   //同步时钟          配置是否打开
uint16_t USART_CPOL;    //极性              配置串口空闲为低电平,高电平
uint16_t USART_CPHA;    //相位              配置选择边沿
uint16_t USART_LastBit; //最后一位时钟       配置使能还是关闭
}USART_ClockInitTypeDef;

初始化函数:

void USART_Init                         //初始化函数
(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); 

void USART_Cmd                       //串口使能函数
(USART_TypeDef* USARTx, FunctionalState NewState);

void USART_ITConfig                    //中断配置函数
(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);

void USART_SendData                 //串口发送函数
(USART_TypeDef* USARTx, uint16_t Data);

 uint16_t USART_ReceiveData     //串口接收读取函数
(USART_TypeDef* USARTx);

FlagStatus USART_GetFlagStatus  //获取相应的串口标志位
(USART_TypeDef* USARTx, uint16_t USART_FLAG);

ITStatus USART_GetITStatus              //中断状态位获取
(USART_TypeDef* USARTx, uint16_t USART_IT);

如何配置串口的发送:

1.配置时钟:  GPIO口的时钟,串口的时钟, 引脚复用的时钟

2.配置GPIO的结构体

3.配置串口的结构体

4.串口的发送

USART相关标志位

串口接收字符讲解:

主函数:

配置的串口函数:

成功接收信息:

串口发送字符:
我可以先定义一个发送函数(在串口函数里面)

在主函数里面使用

烧录,查看,达到当我们按下一次复位键就输出一次 OK

串口发送字符串:

主函数调用

成功发送字符串

printf重定向

重定向(Redirection)在计算机科学中,特别是在操作系统和程序设计中,是一个将输出流(如标准输出stdout、标准错误等)或输入流(如标准输入stdin)从一个默认位置或设备改道到另一个位置或设备的过程。这个过程允许程序将其输出发送到除原始默认目标之外的其他地方,或者从非标准源读取输入。比如原先使用print是直接把数据输出到屏幕上,可以通过重定向把它输出到串口上。

将标准C库中的 fputc 函数重定向为通过STM32的USART1发送单个字符。这个函数的作用是将字符 ch(在C语言中,字符通常通过其ASCII码值以整数形式传递)发送到USART1,并等待直到该字符被完全发送出去(TXE标志被设置)。        

在这个特定的重定向实现中,FILE *f 参数没有被使用,因为已经决定将所有输出都发送到USART1。然而,为了保持与标准 fputc 函数的兼容性,应该保留这个参数,即使您不打算使用它。在更复杂的重定向场景中,您可能会根据 FILE *f 的值来决定将数据发送到哪个输出流。

可以使用标准输出printf

我们也需要被调用的头文件中定义标准输出头文件#include  <stdio.h>

成功输出:

成功输入

串口中断接收:

配置串口中断函数的代码:

#include "usart.h"  
#include "stm32f10x.h"  
  
// USART初始化函数  
void usart_init(void)  
{  
    GPIO_InitTypeDef gpioinitStructure; // GPIO初始化结构体  
    USART_InitTypeDef usartinitStructure; // USART初始化结构体  
    NVIC_InitTypeDef nvicinitStructure; // NVIC初始化结构体  
  
    // 配置NVIC的优先级分组为2  
    // NVIC_PriorityGroup_2定义了抢占优先级和子优先级的位数分配  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
  
    // 使能GPIOA、AFIO(复用功能输入输出,但注意在STM32F10x中可能不需要显式启用AFIO)和USART1的时钟  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 在STM32F10x中,如果不需要配置重映射,这行代码可能不是必需的  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);  
  
    // 配置PA9为USART1的TX(发送)引脚,复用推挽输出  
    gpioinitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    gpioinitStructure.GPIO_Pin = GPIO_Pin_9;  
    gpioinitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
    GPIO_Init(GPIOA, &gpioinitStructure);  
  
    // 配置PA10为USART1的RX(接收)引脚,浮空输入  
    gpioinitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
    gpioinitStructure.GPIO_Pin = GPIO_Pin_10;  
    GPIO_Init(GPIOA, &gpioinitStructure);  
  
    // 配置USART1的参数  
    usartinitStructure.USART_BaudRate = 115200; // 波特率  
    usartinitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 禁用硬件流控制  
    usartinitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 设置为接收和发送模式  
    usartinitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验  
    usartinitStructure.USART_StopBits = USART_StopBits_1; // 停止位为1  
    usartinitStructure.USART_WordLength = USART_WordLength_8b; // 数据位为8位  
    USART_Init(USART1, &usartinitStructure); // 应用USART初始化到USART1  
  
    // 使能USART1的接收中断  
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  
  
    // 使能USART1  
    USART_Cmd(USART1, ENABLE);  
  
    // 配置NVIC以响应USART1中断  
    nvicinitStructure.NVIC_IRQChannel = USART1_IRQn; // 设置中断通道为USART1中断  
    nvicinitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能该中断通道  
    nvicinitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 设置抢占优先级为1  
    nvicinitStructure.NVIC_IRQChannelSubPriority = 1; // 设置子优先级为1  
    NVIC_Init(&nvicinitStructure); // 应用NVIC初始化  
}  
  
// 发送一个字节  
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) != '\0'); // 直到字符串结束  
  
    // 等待所有字符发送完成  
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);  
}  
  

主函数代码:
        

成功发送,并控制LED灯

  • 27
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值