STM32学习(三)串口实验

5 篇文章 0 订阅
5 篇文章 0 订阅

STM32学习(三)串口实验

串口简介

UART:全双工、异步、串行通信方式

  • 经常用来打印调试信息

物理层

串口物理层有很多标准及变种:TTL、RS232、RS422、RS485等;

RS232 标准

在这里插入图片描述上图中,设备A 与 设备B 的 DB9接口 通过串口线连接,串口信号线中使用 RS232电平标准 传输数据信号。由于 RS232电平标准不能直接被控制器识别,所以需要通过一个 “电平转换芯片(如MA3232)” 来将 RS232电平 和 TTL电平进行转换(发送数据时,将TTL电平转换成RS232电平;接收数据时,将RS232电平转换成TTL电平)。

TTL电平标准 VS RS232电平标准

逻辑0逻辑1
TTL0 ~ 0.5V2.4V ~ 5V
RS232+3V ~ +15V-15V ~ -3V

电子电路中常用的是 TTL标准,理想状态下,用 0V 表示逻辑0,用 5V 表示逻辑1,而实际情况允许一定的误差,采用的是一个范围。

RS232标准,为了增加串口通讯传输距离和提高抗干扰能力,使用 -15V 表示逻辑1,+15V 表示逻辑0,下图是表示同一信号的 TTL电平 和 RS232电平:
在这里插入图片描述

物理连接

DB9接口的信号线有9根,目前一般只使用 RXD、TXD、GND这3条信号线就可以了。

设备A	  设备B
TXD  --  RXD
RXD  --  TXD
GND  --  GND
VCC  --  VCC

硬件电路

以 USART1 为例,使用 PA9 和 PA10 引脚(也可以使用其他引脚组合,详见引脚复用)
在这里插入图片描述

编程指南

串口初始化指南

主要步骤如下:

1)GPIO 时钟使能

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

2)USART1 时钟使能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

3)GPIO 复用模式初始化

  • 使用 DEBUG_USART_RX_GPIO_PORT 和 DEBUG_USART_RX_PIN 是为了方便代码移植和书写,后续代码都是类似风格,不再单独说明。
#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_PIN                    	 GPIO_Pin_10
#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_PIN                      GPIO_Pin_9

	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

4)引脚复用配置

GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);

5)UART 参数配置

主要设置如下参数:

  • 波特率 115200
  • 字长 8位
  • 奇偶校验 无校验
  • 不使用硬件流控
	USART_InitTypeDef USART_InitStructure;

	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	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);

6)使能串口

USART_Cmd(USART1, ENABLE);

串口接收中断配置

7)配置 NVIC 嵌套中断向量控制器

中断优先级分组设置,一般是在 main() 函数中设置,后续默认已经配置,不再单独说明。

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC 参数配置

void uart1_nvic_config(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

8)串口接收中断使能

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

串口收发数据接口

串口发送数据

如下是发送单个数据的接口,Data 最多是9位

// Transmits single data through the USARTx peripheral.
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
	USARTx->DR = (Data & (uint16_t)0x01FF);
}

串口接收数据

// Returns the most recent received data by the USARTx peripheral.
uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
{
	return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
}

重定向 printf() 和 scanf() 函数

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);
}

主要代码

#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_PIN                    	 GPIO_Pin_10
#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_PIN                      GPIO_Pin_9

void uart1_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

	// 引脚复用配置
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);

	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	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);

	uart1_nvic_config();
	USART_Cmd(USART1, ENABLE);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}

uint16_t uart1_send(USART_TypeDef* USARTx, char *data)
{
	unsigned int k = 0;

	do
	{
		USART_SendData(USARTx, *(data+ k));
		while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
		k++;
	} while (*(data+ k) != '\0');

	/* 等待发送完成 */
	while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
	{
	}
}

RS232、RS422、RS485 的区别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供相关的信息。 首先,为了实现 STM32 与 RS422 设备之间的串口通信,您需要选择一个可以支持 RS422 的 STM32 开发板。常见的选择包括 STM32F4 和 STM32F7 系列。 接下来,您需要了解 RS422 串口通信的基本原理和协议。RS422 是一种差分信号通信协议,使用两个信号线传输数据,分别为 A+ 和 A-,B+ 和 B-。在 RS422 串口通信中,数据的传输速率可以达到非常高的速度,并且可以支持长距离传输。 使用 STM32 实现 RS422 串口通信需要使用相应的库函数或者编写相关的驱动程序。在 STM32 中,串口通信可以使用 USART 或者 UART 模块。您需要根据具体的需求选择合适的模块,并且配置相应的参数,例如波特率、数据位、停止位等。 下面是一个简单的示例代码,可以帮助您了解如何在 STM32 中实现 RS422 串口通信: ```c #include "stm32f4xx.h" void RS422_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; // 使能 GPIO 时钟和 USART 时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 配置 GPIO 引脚为复用功能 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStruct); // 配置 USART2 为异步模式 USART_InitStruct.USART_BaudRate = 9600; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStruct); // 使能 USART2 USART_Cmd(USART2, ENABLE); } void RS422_SendByte(uint8_t byte) { while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, byte); } uint8_t RS422_ReceiveByte(void) { while (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET); return USART_ReceiveData(USART2); } ``` 在上面的代码中,我们使用了 USART2 模块来实现 RS422 串口通信。我们首先初始化了 GPIO 引脚和 USART 模块,然后定义了发送和接收函数来发送和接收数据。 希望以上信息能够帮助您实现 STM32 与 RS422 设备之间的串口通信。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值