《STM32的USART串口》

目录

1.什么是串口?

2.串口通信的接口标准

3.基于Stm32的USART串口的使用

①USART引脚资源

②串口重要参数

(1)波特率

(2)硬件流控制

(3)模式

(4)校验位

(4)停止位

(5)数据位

(6)配置结构体

③串口函数的常规写法(江协版)

④梳理USART串口函数写法思路

⑤接收|发送代码写法

接收代码

发送代码

⑥最重要的标准位问题

USART_FLAG_TXE:

USART_FLAG_TC:

总结:


1.什么是串口?

(1)串口,即串行通信端口,与并行接口不同之处在于,传输一个字节(8位数据)时,串口是将8个位排好队,逐个的在1条连接线上传输,而并口则将8个位一字排开,分别在8条连接线上同时传输 。

只要进行串行通讯的应该都属于串口。

2.串口通信的接口标准

(1)正常而言,常用的串口通信的接口标准有RS-232C、RS-232、RS-422A、RS-485、USB等等。RS-232-C、RS-422与RS-485标准只对接口的电气特性做出规定,不涉及接外挂程式、电缆或协议。USB是近几年发展起来的新型接口标准,主要应用于高速数据传输领域。

其中,需要注意的是以上标准只是一种电平标准,而COM口肯定使用RS-232标准,UART口一般使用TTL标准。PC机一般有两个串行口COM1和COM2。通常COM1使用的是9 针D 形连接器,也称之为RS-232接口,而COM2有的使用的是老式的DB25针连接器,也称之为RS-422接口,不过已经很少使用。

常用于电脑的标准串口RS-232的D型9针连接器

1、载波检测(CD)

2、接受数据(RXD)

3、发出数据(TXD)

4、数据终端准备好(DTR)

5、信号地线(SG)

6、数据准备好(DSR)

7、请求发送(RTS)

8、清除发送(CTS)

9、振铃指示(RI)

(2)除了标准串口RS-232代表的COM口的串口外,还分为USB口、SATA接口,对于嵌入式而言,嵌入式里面说的串口,一般是指UART口。而UART串口一般用的是TTL电平,所以就要用CH340芯片进行转换,需要注意的是RS-232与TTL只是一种电平标准,而COM口和UART口是物理接口,只是COM口肯定使用RS-232标准,而UART一般使用TTL标准,可是电脑上的USB接口的输出电压为直流5V,输出电流不大于500毫安 并且与TTL电平不兼容,所以信号传输时需要电平转换电路。

   所以电脑USB通过CH430芯片输出TTL电平 给单片机 ,这便是USB转TTL

这四个,就是常用的USB转TTL串口模块。

3.基于Stm32的USART串口的使用

USART引脚资源

在STM32里,串口通信是USART,STM32可以通过串口和其他设备进行传输并行数据,是全双工,异步时钟控制,设备之间是点对点的传输。对应的STM32引脚分别是RX和TX端。STM32的串口资源有USART1、USART2、USART3。但在最小系统版STM32F103C8T6中只有USART1和USART2串口引脚资源,如下图:

1、接受数据(RX)

2发出数据(TX)

3、请求发送(RTS)

4、清除发送(CTS)

串口重要参数

(1)波特率

串口通信的速率USART_BaudRate: 波特率设置。一般设置为2400、9600、19200、115200。标准库函数会根据设定值计算得到USARTDIV值,从而设置USART_BRR寄存器值。

USART_InitStruct.USART_BaudRate=9600;

(2)硬件流控制

USART_HardwareFlowControl: 硬件流控制选择,只有在硬件流控制模式才有效,可选有⑴使能RTS、⑵使能CTS、⑶同时使能RTS和CTS、⑷不使能硬件流。一般选择第四个

USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

(3)模式

USART_Mode: USART模式选择,有USART_Mode_Rx和USART_Mode_Tx,允许使用逻辑或运算选择两个,它设定USART_CR1寄存器的RE位和TE位。此处发送模式和接收模式均选择

USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;

(4)校验位

USART_Parity: 奇偶校验控制选择,可选USART_Parity_No(无校验)、USART_Parity_Even(偶校验)以及USART_Parity_Odd(奇校验),它设定USART_CR1寄存器的PCE位和PS位的值。用于数据验证,根据数据位的计算得来。奇偶校验,一般不需要

USART_InitStruct.USART_Parity=USART_Parity_No; //不选择校验

(4)停止位

USART_StopBits: 停止位设置,可选0.5个、1个、1.5个和2个停止位,它设定USART_CR2寄存器的STOP[1:0]位的值,一般我们选择1个停止位。

USART_InitStruct.USART_StopBits=USART_StopBits_1; //停止位1位

(5)数据位

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

USART_InitStruct.USART_WordLength=USART_WordLength_8b; //数据位8位

(6)配置结构体

当使用同步模式时需要配置SCLK引脚输出脉冲的属性,标准库使用一个时钟初始化结构体USART_ClockInitTypeDef来设置,该结构体内容也只有在同步模式才需要设置。

USART_InitTypeDef USART_InitStructure; //定义结构体变量

串口函数的常规写法(江协版)

void Serial_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开启USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟

/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA9引脚初始化为复用推挽输出

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA10引脚初始化为上拉输入

/*USART初始化*/
USART_InitTypeDef USART_InitStructure; //定义结构体变量
USART_InitStructure.USART_BaudRate = 9600; //波特率
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制,不需要
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //模式,发送模式和接收模式均选择
USART_InitStructure.USART_Parity = USART_Parity_No; //奇偶校验,不需要
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位,选择1位
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长,选择8位
USART_Init(USART1, &USART_InitStructure); //将结构体变量交给USART_Init,配置USART1
/*中断输出配置*/
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接收数据的中断
/*NVIC中断分组*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC为分组2
/*NVIC配置*/
NVIC_InitTypeDef NVIC_InitStructure; //定义结构体变量
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //选择配置NVIC的USART1线
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC线路使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定NVIC线路的抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC线路的响应优先级为1
NVIC_Init(&NVIC_InitStructure); //将结构体变量交给NVIC_Init,配置NVIC外设

/*USART使能*/
USART_Cmd(USART1, ENABLE); //使能USART1,串口开始运行
}

④梳理USART串口函数写法思路

首先开启USART的RCC时钟,顺便将RX,TX所需的RCC时钟GPIO开启

之后将RX,TX所需的引脚资源进行定义,RX的Mode模式为上拉输入或浮空输入,TX的Mode模式为复用推挽输出。

然后将USART初始化,进行初步定义

最后配置串口接收中断,设置中断函数,使能USART1。

⑤接收|发送代码写法

然后就可以接收和发送了

接收代码

/**

  * 函    数:获取串口接收标志位

  * 参    数:无

  * 返 回 值:串口接收标志位,范围:0~1,接收到数据后,标志位置1,读取后标志位自动清零

  */

uint8_t Serial_GetRxFlag(void)

{

if (Serial_RxFlag == 1) //如果标志位为1

{

Serial_RxFlag = 0;

return 1; //则返回1,并自动清零标志位

}

return 0; //如果标志位为0,则返回0

}


发送代码

/**

  * 函    数:串口发送一个字节

  * 参    数:Byte 要发送的一个字节

  * 返 回 值:无

  */

void Serial_SendByte(uint8_t Byte)

{

USART_SendData(USART1, Byte); //将字节数据写入数据寄存器,写入后USART自动生成时序波形

while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完成

/*下次写入数据寄存器会自动清除发送完成标志位,故此循环后,无需清除标志位*/

}

⑥最重要的标准位问题

考虑标志位的问题,如下文

USART_FLAG_TXE:

注意左上角紫色的框,以及发送数据的流程,当我们去调用函数**USART_SendData(pUSARTx,ch);的时候,一个字节的数据就会被写入发送数据寄存器(TDR),注意USART_FLAG_TXE这个标志位,不发送数据的时候,闲着的时候都是0,当检测到数据写入发送数据寄存器TDR的时候,就会立刻将USART_FLAG_TXE置1,然后数据移位寄存器(TSR)就开始从TDR寄存器中取数据,一位一位的取走发送出去,当被取完的时候,发送数据寄存器TDR也就为空了,所以此时USART_FLAG_TXE**标志位就会被置0 ,所以也是我们while检测这个标志的原因

USART_FLAG_TC:

我们来假设一个过程,当我们调用**USART_SendData(pUSARTx,ch)发送一个字节的数据的时候,此时数据移位寄存器(TSR)就会立刻从数据发送寄存器(TDR)中开始搬运数据并一位一位发送出去,但是受限于波特率,搬运的速度会远大于发送的速率,而只要搬运完了,USART_FLAG_TXE这个标志位就会立刻被置0,我们while循环检测这个标志,此时就会被唤醒,看我上面发送字符串的函数就能看出来,下一个数据立刻又被写入发送数据寄存器(TDR),然后移位数据寄存器又开始搬运了,注意注意:此时移位数据寄存器中,上一个字节的数据还不一定发送完成呢,所以会为空吗?不会,所以所以:USART_FLAG_TC**这个标志位的作用是:检测数据移位寄存器是否为空,当开始发送数据,数据移位寄存器从数据发送寄存器中搬运数据,这个标志位就会被置1,当所有数据发送完成,移位寄存器为空时,就会被置0,所以通过这个标志位,可以实现在字节流的传输方式中实现帧传输

总结:

对于嵌入式而言,串口是必不可少的一环,以上的文字是我总结我所见到的博客和我自己的一些学习心得。认真了解串口之后,才发现串口应用之广泛,我所学所写的还有很多不足。

一起前进吧各位,加油!加油!加油!

  • 28
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是关于STM32 USART发送和接收使用DMA的回答: DMA (Direct Memory Access)是一种在不占用CPU的情况下直接进行数据传输的技术。对于STM32USART模块,使用DMA可以大大减轻CPU的负担,提高数据传输效率。 首先,需要配置USART和DMA。可以使用STM32的CubeMX工具来快速生成初始化代码。在配置USART时,需要设置USART的波特率、数据位、停止位和校验位等参数。在配置DMA时,需要设置DMA的传输方向、数据长度、传输模式、优先级和中断等参数。 接下来,可以使用HAL库提供的函数来启动DMA传输。在发送数据时,可以使用函数HAL_UART_Transmit_DMA()启动DMA传输,该函数会将数据存储在指定的缓冲区中,并将缓冲区的地址传递给DMA进行传输。在接收数据时,可以使用函数HAL_UART_Receive_DMA()启动DMA传输,该函数会将接收到的数据存储在指定的缓冲区中,并将缓冲区的地址传递给DMA进行传输。 在DMA传输完成后,可以使用HAL库提供的回调函数来进行处理。对于发送完成,可以使用函数HAL_UART_TxCpltCallback();对于接收完成,可以使用函数HAL_UART_RxCpltCallback()。 需要注意的是,在使用DMA进行数据传输时,需要确保缓冲区的大小足够大,以便存储需要传输的数据。 希望这个回答能够帮助你了解STM32 USART发送和接收使用DMA的相关知识。如果你有任何其他问题,可以随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值