STM32学习笔记(十)串口UART

一、串口认知

1.串口基本认知
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢

  • 是设备间接线通信的一种方式
  • 数据一位一位地顺序传送
  • 双向通信,全双工
  • 传送速度相对较慢

2.关于电器标准和协议
串行接口按电气标准及协议来分包括RS-232-C、RS-422、RS485等。RS-232-C、RS-422与RS-485标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议

RS-232

也称标准串口,最常用的一种[串行通讯接口,比如我们的电脑主机的9针串口 ,最高速率为20kb/s
RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其传送距离最大为约15米。所以RS-232适合本地设备之间的通信

在这里插入图片描述

RS-422
由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Slave),从设备之间不能通信,所以RS-422支持点对多的双向通信。
RS-422的最大传输距离为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比

RS-485
从RS-422基础上发展而来的,无论四线还是二线连接方式总线上可多接到32个设备
在这里插入图片描述

3.关于串口的电平

  • 经常听说的UART:

异步串行是指UART(Universal Asynchronous Receiver/Transmitter),通用异步接收/发送。

  • UART包含TTL电平的串口和RS232电平的串口

RS232电平
逻辑1为-3~-15V的电压, 逻辑0为3~15V的电压
笔记本通过RS232电平和单片机通信
在这里插入图片描述
TTL电平
TTL是Transistor-Transistor Logic,即晶体管-晶体管逻辑的简称,它是计算机处理器控制的设备
内部各部分之间通信的标准技术。TTL电平信号应用广泛,是因为其数据表示采用二进制规定,
+5V等价于逻辑”1”,0V等价于逻辑”0”。
数字电路中,由TTL电子元器件组成电路的电平是个电压范围,规定:
输出高电平>=2.4V,输出低电平<=0.4V;
输入高电平>=2.0V,输入低电平<=0.8V
笔记本电脑通过TTL电平与单片机通信
TX发送线(端口)3.1
RX接收线 (端口)3.0
USB转TTL,使用ch340通信
在这里插入图片描述

二、USART 简介

通用同步异步收发器 (Universal Synchronous Asynchronous Receiver and Transmitter) 是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。
UART(Universal Asynchronous Receiver and Transmitter)跟 USART不一样的是:它是在 USART 基础上裁剪掉了同步通信功能,只有异步通信

  • 简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART。

  • 串行通信一般是以帧格式传输数据,即是一帧一帧的传输,每帧包含有起始信号、数据信息、停止信号,可能还有校验信息。USART 就是对这些传输参数有具体规定,当然也不是只有唯一 个参数值,很多参数值都可以自定义设置,只是增强它的兼容性。

  • USART 满足外部设备对工业标准 NRZ 异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率,使得它的应用更加广泛。

  • USART不仅支持同步单向通信半双工单线通信,也支持LIN(局部互连网)智能卡协议IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。 USART 支持使用 DMA,可实现高速数据通信。

  • STM32在硬件设计时一般都会预留一个 USART 通信接口连接电脑,用于在调试程序是可以把一些调试信息“打印”在电脑端的串口调试助手工具上,从而来用串口调试助手来验证自己的程序是否出了问题

USART功能概述
接口通过三个引脚与其他设备连接在一起USART框图。任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。

  • RXD:数据输入引脚,数据接受
  • TXD:数据发送引脚,数据发送
    接线方式:
    在这里插入图片描述
    在这里插入图片描述
    回忆UART是异步串行接口,通信双方使用时钟不同,因为双方硬件配置不同,但是需要约定通信速度,叫做波特率
    除了速度要求,还要有数据格式,双方 暗号 对上了再发数据,所以有起始位,和停止位 的概念

串口发送/接收函数:
HAL_UART_Transmit(); 串口发送数据,使用超时管理机制
HAL_UART_Receive(); 串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT(); 串口中断模式发送
HAL_UART_Receive_IT(); 串口中断模式接收

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart,
uint8_t *pData, uint16_t Size, uint32_t Timeout)

作用:以阻塞的方式发送指定字节的数据
形参 1 :UART_HandleTypeDef 结构体类型指针变量
形参 2:指向要发送的数据地址
形参 3:要发送的数据大小,以字节为单位
形参 4:设置的超时时间,以ms单位

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart,
uint8_t *pData, uint16_t Size)

作用:以中断的方式接收指定字节的数据
形参 1 是 UART_HandleTypeDef 结构体类型指针变量
形参 2 是指向接收数据缓冲区
形参 3 是要接收的数据大小,以字节为单位
此函数执行完后将清除中断,需要再次调用以重新开启中断

串口中断回调函数:
HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //发送中断回调函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //接收中断回调函数

状态标记变量:
USART_RX_STA

  • 从0开始,串口中断接收到一个数据(一个字节)就自增1。当数据读取全部OK时候(回车和换行符号来的时候),那么 USART_RX_STA的最高位置1,表示串口数据接收全部完毕了,然后main函数里面可以处理数据了
    在这里插入图片描述
    串口接收中断流程
    在这里插入图片描述

三、串口实验(非中断)

需求:接受串口工具发送的字符串,并将其发送回串口工具。
STM32F103C8T6有3个串口
硬件接线:
TX – A10
RX – A9
一定要记得交叉接线!!

步骤:
1.选定串口
在这里插入图片描述
2. 选择模式
异步通讯
在这里插入图片描述
3.串口配置
在这里插入图片描述
4. 使用MicroLIB库
重定义printf后,必须在target里面勾选上MicroLIB,调用一下这个微型库,不然一直卡在里面
在这里插入图片描述
编程实现:

HAL_UART_Transmit(); 串口发送数据,使用超时管理机制
HAL_UART_Receive(); 串口接收数据,使用超时管理机制

#include <stdio.h>
#include <string.h>
unsigned char ch[20] = {0};
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}// main函数里:
unsigned char ch[20] = {0};
HAL_UART_Transmit(&huart1, "hello world\n", strlen("hello world\n"), 100);
while(1)
{
HAL_UART_Receive(&huart1, ch, 19, 100);
//HAL_UART_Transmit(&huart1, ch, strlen(ch), 100);
printf(ch);
memset(ch, 0, strlen(ch));
}

重写putc

#include <stdio.h>
int fputc(int ch, FILE *f)//一个字符的发送
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}

四、串口实验(中断)

需求:通过中断的方法接受串口工具发送的字符串,并将其发送回串口工具
硬件接线:
同上
串口配置:
前4步同上
5. 打开中断

在这里插入图片描述
编程实现:

回车\r 十六进制0x0D
换行\n 十六进制0x0A

#include <stdio.h>
//串口接收缓存(1字节)
uint8_t buf=0;
//定义最大接收字节数 200,可根据需求调整
#define UART1_REC_LEN 200
// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];
// 接收状态
// bit15, 接收完成标志
// bit14, 接收到0x0d
// bit13~0, 接收到的有效字节数目
uint16_t UART1_RX_STA=0;
// 接收完成回调函数,收到一个数据后,在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// 判断中断是由哪个串口触发的
if(huart->Instance == USART1)
{
// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
if((UART1_RX_STA & 0x8000) == 0)
{
// 如果已经收到了 0x0d (回车),
if(UART1_RX_STA & 0x4000)
{
// 则接着判断是否收到 0x0a (换行)
if(buf == 0x0a)
// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
UART1_RX_STA |= 0x8000;
else
// 否则认为接收错误,重新开始
UART1_RX_STA = 0;
}else // 如果没有收到了 0x0d (回车)
{
//则先判断收到的这个字符是否是 0x0d (回车)
if(buf == 0x0d)
{
// 是的话则将 bit14 位置为1
UART1_RX_STA |= 0x4000;
}else
{
// 否则将接收到的数据保存在缓存数组里
UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
UART1_RX_STA++;// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
if(UART1_RX_STA > UART1_REC_LEN - 1)
UART1_RX_STA = 0;
}
}
}/
/ 重新开启中断
HAL_UART_Receive_IT(&huart1, &buf, 1);
}
} int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}

//main函数部分
HAL_UART_Receive_IT(&huart1, &buf, 1);
while (1)
{/
* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//判断判断串口是否接收完成
if(UART1_RX_STA & 0x8000)
{
printf("收到数据:");
// 将收到的数据发送到串口
HAL_UART_Transmit(&huart1, UART1_RX_Buffer, UART1_RX_STA & 0x3fff, 0xffff);
// 等待发送完成
while(huart1.gState != HAL_UART_STATE_READY);
printf("\r\n");
// 重新开始下一次接收
UART1_RX_STA = 0;
}printf("hello liangxu\r\n");
HAL_Delay(1000);
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值