USART的标准库编程

使用USART与计算机通信
在这里插入图片描述
电脑上只有usb端口 没有TX 和RX需要一个USB转TTL电平模块来实现通信
在这里插入图片描述
芯片C8T6中只有三个UASRT 选其中一个UASRT来通信即可 那么如何定位那个USART的TX 和RX引脚呢?
方式1 查找最小系统板引脚分布图
在这里插入图片描述
查找USART1的引脚 RTS CTS是硬件流控 CK引脚是同步时钟 (因为串口用的是异步通信所以不用到) 紫色绿圈圈起来的是复用 当有IO冲突时就可以重映射到别的引脚上
方式2 查找“复用功能重映射表”
在这里插入图片描述
当没有被重映射的时候 TX和RX的引脚分别为PA9
PA10 当被重映射后 TX和 RX引脚为PB6 PB7
这次我们使用了重映射
在这里插入图片描述
安装USB转TTL驱动
在这里插入图片描述
在这里插入图片描述
双击打开安装
安装串口调试助手软件

UASRT标准库编程接口

在这里插入图片描述
初始化 总开关 发送数据 接收数据 读取标志位
USART_Init
在这里插入图片描述
调用这个函数是对 CR寄存器的M STOP PE PS bit位进行操作 M是设置数据帧数据位 STOP是设置停止位的长度 PE是是否使用(使能)校验 PS是使用奇校验还是偶校验
还是声明一个结构体 然后填表对应的值 完成初始化
在这里插入图片描述
对应的成员 world…是设置数据帧的数据位的 Parity是设置是否使能校验 是使用奇校验还是偶校验 STopb是设置停止位的长度的 MODE是设置UASRT的模式 是要接收数据还是要发送数据的 (是打开TX
还是RX开关 还是都打开) BaudRate是设置波特率的 Hardwar 是设置硬件流控的
回忆流控的知识点 当数据发送过快时有可能会造成数据的丢失 这时加入一个流控信号 当一个数据传输完成 且接收方接收完成就发送一个流控信号 即可进行下一数据的发送
在这里插入图片描述
如图是两个单片机间进行通信 上面的两个单片机左边的只需要使能GTS接收流控信号 而右边的只需要使能RTS发送流控信号 对于下面两个单片机 皆有发送和接收所以需要两个单片机同时使能RTS 和CTS
USART——Cmd (Cmd通常是开关的意思)
在这里插入图片描述
这个函数的第一个参数是选择USART的 例如选择USART1就填 USART1 第二个是是否打开总开关
USART_SendData
在这里插入图片描述
第一个任然是USART1 第二个就是要发送的数据
USART_GetFlagStatus
在这里插入图片描述
如图 第一个为要读取的串口USART1
在这里插入图片描述
在这里插入图片描述
调用这个函数就可以查询标志位是否为1或0了 如第一个示例代码 就可以判断TXE(SR状态寄存器)是否为1 为1才可以写入新的数据 如果为0就表示还有数据在TDR寄存器中

USART的初始化

在这里插入图片描述
本次实验不需要用到流控信号(硬件流控)所以不需要RTS CTS引脚 串口通信是异步的也不需要时钟引脚 然后为了增加难度就使用重映射 映射到PB7 PB6
在这里插入图片描述
IO引脚初始化
在这里插入图片描述
这里直接查表 F1系列的芯片手册
在这里插入图片描述
输出是复用(通过USART控制IO引脚)
在这里插入图片描述
全双工和半双工的概念 就是全双工就是既可以发送数据也可以接收数据 二者能同时进行 半双工就是当你发送数据的时候就不能接收数据 当你接受数据的时候就不能发送数据 (半双工极少用到)
注意上表的CTS引脚最好为上拉输入 因为当空闲时给CTS一个高电平就默认为空闲模式 当CTS接收到高电平时就TX引脚就不会发送数据 处于空闲状态
RX引脚选择为上拉输入模式
完整的参数表格
在这里插入图片描述
复用功能重映射
在这里插入图片描述
设置USART的参数
在这里插入图片描述
闭合总开关
在这里插入图片描述USART的初始化总代码

#include "stm32f10x.h"
#include "stm32f10x_pal.h"

int main(void)
{
	GPIO_InitTypeDef  GPIOBInitStruct;
	
	
	PAL_Init();
	//初始化 TX PB6 AF_PP 10MHZ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB的时钟
	GPIOBInitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIOBInitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //配置PB6为复用推挽输出
	GPIOBInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB,&GPIOBInitStruct);//	配置PB6(RTX)为复用推挽模式
	
	//初始化 RX PB7 IPU 
	GPIOBInitStruct.GPIO_Pin =GPIO_Pin_7;//引脚配置
	GPIOBInitStruct.GPIO_Mode = GPIO_Mode_IPU;//配置PB7为输入上拉模式
	GPIO_Init(GPIOB,&GPIOBInitStruct);
	
	//重映射USART1的TX RX引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO的时钟
	GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE); 
	
	//使能USART的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//设置USART1的参数
	USART_InitTypeDef USARTInitStruct;
	USARTInitStruct.USART_BaudRate = 9600; //设置USART1的波特率为9600
	USARTInitStruct.USART_WordLength = USART_WordLength_8b; //设置数据帧的数据位为8位
	USARTInitStruct.USART_StopBits = USART_StopBits_1; //设置数据帧的停止位为1位
	USARTInitStruct.USART_Parity = USART_Parity_No; //不使用校验位 不需要使能 不使用奇偶校验
	USARTInitStruct.USART_Mode = USART_Mode_Rx |USART_Mode_Tx;// 初始化USART1的模式是接收和发送
	USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None ; //不使用硬件流控

	USART_Init(USART1,&USARTInitStruct); 	
	
	//闭合总开关
	USART_Cmd(USART1,ENABLE);
	
	
	
	
	while(1)
	{
	}
}

使用串口来发送数据
实验的简介
在这里插入图片描述
串口调试助手参数设置
在这里插入图片描述
如何用串口去发送单个字节
在这里插入图片描述
左边的代码是对寄存器的直接操作 右边是标准库的库函数操作
在这里插入图片描述
发送一个字节的代码

#include "stm32f10x.h"
#include "stm32f10x_pal.h"

int main(void)
{
	GPIO_InitTypeDef  GPIOBInitStruct;
	
	
	PAL_Init();
	//初始化 TX PB6 AF_PP 10MHZ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB的时钟
	GPIOBInitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIOBInitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //配置PB6为复用推挽输出
	GPIOBInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB,&GPIOBInitStruct);//	配置PB6(RTX)为复用推挽模式
	
	//初始化 RX PB7 IPU 
	GPIOBInitStruct.GPIO_Pin =GPIO_Pin_7;//引脚配置
	GPIOBInitStruct.GPIO_Mode = GPIO_Mode_IPU;//配置PB7为输入上拉模式
	GPIO_Init(GPIOB,&GPIOBInitStruct);
	
	//重映射USART1的TX RX引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO的时钟
	GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE); 
	
	//使能USART的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//设置USART1的参数
	USART_InitTypeDef USARTInitStruct;
	USARTInitStruct.USART_BaudRate = 9600; //设置USART1的波特率为9600
	USARTInitStruct.USART_WordLength = USART_WordLength_8b; //设置数据帧的数据位为8位
	USARTInitStruct.USART_StopBits = USART_StopBits_1; //设置数据帧的停止位为1位
	USARTInitStruct.USART_Parity = USART_Parity_No; //不使用校验位 不需要使能 不使用奇偶校验
	USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;// 初始化USART1的模式是接收和发送
	USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None ; //不使用硬件流控

	USART_Init(USART1,&USARTInitStruct); 	
	
	//闭合总开关
	USART_Cmd(USART1,ENABLE);
	
	//1.等待寄存器TDR清空
	 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET){}; //TXE为0表示TDR寄存器中仍有数据
	 
	// 2.写入要发送的数据
		USART_SendData(USART1, 0x5a);
	
	//3/等待数据发送完成
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET){};

	
	
	
	while(1)
	{
	}
}

发送字节数组
在这里插入图片描述
发送一个数组

		uint8_t a[] = {0,1,2,3,4,5};
		uint32_t i;
		for(i=0;i<sizeof(a)/sizeof (uint8_t);i++)
		{
			//1.等待TXE置位
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET){}; //TXE为0表示TDR寄存器中仍有数据
			//2.把数据写入TDR
				USART_SendData(USART1, a[i]);
		}
	
			//3/等待数据发送完成
		while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET){};

发送字符

const char *str = "Hello world";
	uint32_t i;
	for(i=0; i<strlen(str);i++)
	{
		// 1. 等待TXE置位
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		// 2. TDR
		USART_SendData(USART1, str[i]);	}	// 3. TC置位
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

串口接收数据
![在这里插入图片描述在这里插入图片描述![](https://img-blog.csdnimg.cn/98551df9699a4894bb7ee5ceef14b001.png)
在这里插入图片描述
在这里插入图片描述
发送1就灯亮 发送0灯就灭

#include "stm32f10x.h"
#include "stm32f10x_pal.h"

int main(void)
{
	GPIO_InitTypeDef  GPIOBInitStruct;
	
	
	PAL_Init();
	//初始化 TX PB6 AF_PP 10MHZ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB的时钟
	GPIOBInitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIOBInitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //配置PB6为复用推挽输出
	GPIOBInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB,&GPIOBInitStruct);//	配置PB6(RTX)为复用推挽模式
	
	//初始化 RX PB7 IPU 
	GPIOBInitStruct.GPIO_Pin =GPIO_Pin_7;//引脚配置
	GPIOBInitStruct.GPIO_Mode = GPIO_Mode_IPU;//配置PB7为输入上拉模式
	GPIO_Init(GPIOB,&GPIOBInitStruct);
	
	//重映射USART1的TX RX引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO的时钟
	GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE); 
	
	//使能USART的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//设置USART1的参数
	USART_InitTypeDef USARTInitStruct;
	USARTInitStruct.USART_BaudRate = 9600; //设置USART1的波特率为9600
	USARTInitStruct.USART_WordLength = USART_WordLength_8b; //设置数据帧的数据位为8位
	USARTInitStruct.USART_StopBits = USART_StopBits_1; //设置数据帧的停止位为1位
	USARTInitStruct.USART_Parity = USART_Parity_No; //不使用校验位 不需要使能 不使用奇偶校验
	USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;// 初始化USART1的模式是接收和发送
	USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None ; //不使用硬件流控

	USART_Init(USART1,&USARTInitStruct); 	
	
	//闭合总开关
	USART_Cmd(USART1,ENABLE);
	
//	//1.等待寄存器TDR清空
//	 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET){}; //TXE为0表示TDR寄存器中仍有数据
//	 
//	// 2.写入要发送的数据
//		USART_SendData(USART1, 0x5a);
//	
//	//3/等待数据发送完成
//	while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET){};
//		uint8_t a[] = {0,1,2,3,4,5};
//		uint32_t i;
//		for(i=0;i<sizeof(a)/sizeof (uint8_t);i++)
//		{
//			//1.等待TXE置位
//			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET){}; //TXE为0表示TDR寄存器中仍有数据
//			//2.把数据写入TDR
//				USART_SendData(USART1, a[i]);
//		}
//	
//			//3/等待数据发送完成
//		while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET){};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIOBInitStruct.GPIO_Pin = GPIO_Pin_13; 
	GPIOBInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIOBInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC, &GPIOBInitStruct);
	
	GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // 熄灭LED

  uint8_t c;
	
	while(1)
	{
		// 1. RXNE
		while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
		c = USART_ReceiveData(USART1);
		
		if(c == '0')
		{
			 // 熄灭
			GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);
		}
		else if(c=='1')
		{
			 //点亮
			GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET);
		}
		else
		{
		}
	}
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/174604.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5 个适用于 Linux 的开源日志监控和管理工具

当Linux等操作系统运行时&#xff0c;会发生许多事件和在后台运行的进程&#xff0c;以实现系统资源的高效可靠的使用。这些事件可能发生在系统软件中&#xff0c;例如 init 或 systemd 进程或用户应用程序&#xff0c;例如 Apache、MySQL、FTP 等。 为了了解系统和不同应用程序…

【Python数据结构与算法】--- 递归算法应用-五行代码速解汉诺塔问题.

&#x1f308;个人主页: Aileen_0v0 &#x1f525;系列专栏:PYTHON数据结构与算法学习系列专栏&#x1f4ab;"没有罗马,那就自己创造罗马~" 汉诺塔 两层汉诺塔的演示 三层汉诺塔的走法演示 我不知道有没有朋友跟我一样有一个疑问,如果我们顶端的先放到中间柱子呢?…

从零开始学习typescript——数据类型

数据类型 以前我们用js编写代码的时候&#xff0c;都是直接使用let、var、const 来定义数据类型&#xff1b;js会在运行时来确定数据类型&#xff0c;但是在ts中&#xff0c;可以在声明时就可以指定数据类型。如果你学过其他编程语言&#xff0c;比如c、java就能更好的理解了。…

上门维修安装派单系统小程序APP开发之会员级别设计深度解析

啄木鸟鲁班大师上门安装维修平台APP开发之VIP会员解析&#xff0c;在APP或者小程序里设置的会员叫VIP级别会员&#xff0c;系统一共分为4种会员&#xff0c;注册会员&#xff0c;正式会员&#xff0c;VIP金卡会员&#xff0c;VIP钻卡会员。注册用户是指注册了平台但是没有消费记…

安防视频监控管理平台EasyCVR定制首页开发与实现

视频监控平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;也能支持视…

0时区格林威治时间转换手机当地时间-Android

假设传入的是2023-11-01T12:59:10.420987这样的格式 要将格式为2023-11-01T12:59:10.420987的UTC时间字符串转换为Android设备本地时间&#xff0c;您可以使用java.time包中的类&#xff08;在API 26及以上版本中可用&#xff09;。如果您的应用需要支持较低版本的Android&…

基于ubuntu20.04安装ros系统搭配使用工业相机

基于ubuntu20.04安装ros系统搭配使用工业相机 1. ROS系统安装部署1.1更新镜像源1.1.1 备份源文件1.1.2 更新阿里源1.1.3 更新软件源 1.2 ros系统安装1.2.1 添加ros软件源1.2.2 添加秘钥1.2.3 更新软件源1.2.4 配置及更换最佳软件源1.2.5 ROS安装1.2.6 初始化rosdep1.2.7 设置环…

如何使用无代码系统搭建软件平台?有哪些开源无代码开发平台?

无代码是什么 无代码开发&#xff0c;也称为零代码&#xff08;Zero Code&#xff09;开发&#xff0c;是一种技术概念。无代码开发无需代码基础&#xff0c;适合业务人员、IT开发及其他各类人员使用。他们通过无代码开发平台快速构建应用&#xff0c;并适应各种需求变化&#…

吴恩达《机器学习》9-4-9-6:实现注意:展开参数、梯度检验、随机初始化

一、实现注意:展开参数 在上一个视频中&#xff0c;讨论了使用反向传播算法计算代价函数的导数。在本视频中&#xff0c;将简要介绍一个实现细节&#xff0c;即如何将参数从矩阵展开为向量。这样做是为了在高级最优化步骤中更方便地使用这些参数。 二、梯度检验 在神经网络中…

MySQL MHA高可用配置及故障切换

一、MHA相关概念 1&#xff0e;什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中&#xff0c;MHA能做到0-30秒内自动完成故障切换操作。 …

pytorch中.to(device) 和.cuda()的区别

在PyTorch中&#xff0c;使用GPU加速可以显著提高模型的训练速度。在将数据传递给GPU之前&#xff0c;需要将其转换为GPU可用的格式。 函数原型如下&#xff1a; def cuda(self: T, device: Optional[Union[int, device]] None) -> T:return self._apply(lambda t: t.cuda…

【C++进阶之路】第八篇:智能指针

文章目录 一、为什么需要智能指针&#xff1f;二、内存泄漏1.什么是内存泄漏&#xff0c;内存泄漏的危害2.内存泄漏分类&#xff08;了解&#xff09;3.如何检测内存泄漏&#xff08;了解&#xff09;4.如何避免内存泄漏 三、智能指针的使用及原理1.RAII2.智能指针的原理3.std:…

Windows安装MongoDB

1、下载MongoDB的zip&#xff0c;解压 2、创建目录 mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\db mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\log 3、创建一个配置文件mongod.cfg&#xff0c…

7.Gin 路由详解 - 路由分组 - 路由文件抽离

7.Gin 路由详解 - 路由分组 - 路由文件抽离 前言 在前面的示例中&#xff0c;我们直接将路由的定义全部写在 main.go 文件中&#xff0c;如果后面 路由越来越多&#xff0c;那将会越来越不好管理。 所以&#xff0c;下一步我们应该考虑将路由进行分组管理&#xff0c;并且将其抽…

使用jmeter对接口进行简单测试

JMeter是一个开源的性能测试工具&#xff0c;它可以对于Web应用程序、FTP、数据库服务器等各种服务器进行性能测试和负载测试&#xff0c;以确定它们是否能够承受预期的负载。JMeter支持多种协议和技术&#xff0c;如HTTP、HTTPS、FTP、JDBC、LDAP、SOAP、JMS等。它使用Java编写…

maven pom引入依赖不报红,但是项目Dependencies中没有引入jar包

前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识&#xff0c;有兴趣的小伙伴可以关注一下&#xff01; 也许一个人独行&#xff0c;可以走的很快&#xff0c;但是一群人结伴而行&#xff0c;才能走的更远&#xff01;让我们在成长的道路上互相学习&…

maven打包项目,然后给其他项目引用

A项目&#xff08;这个项目需要被打包&#xff0c;作为被引入的项目&#xff09;&#xff0c;不需要启动类&#xff0c;因为作为公共模块被B项目引入&#xff1a; package com.yunya.mvndependontest.rest;import org.springframework.web.bind.annotation.RequestMapping; im…

kubeadm join 192.168.10.16:6443 --token xxx报错Failed to request cluster-info

1、node节点执行 kubeadm join 192.168.10.16:6443 --token hak4zi.hrib9uv4p62t1uok --discovery-token-ca-cert-hash sha256:4337638eef783ee6a66045ad699722079e071c2dfbaa21e37d3174f04d58ea97 --v2 报错 [discovery] Failed to request cluster-info, will try again: G…

Qt应用开发(进阶篇)——线程 QThread

一、前言 QThread类继承于QObject基类&#xff0c;是Qt经典基础工具类&#xff0c;QThread类提供了一种独立于平台的方式来管理线程&#xff0c;让开发者能够快速的完成多线程的创建和使用。 正常情况下&#xff0c;一个PC程序使用到多线程的概率是非常高的&#xff0c;在不同方…

智能座舱架构与芯片- (11) 软件篇 上

一、智能汽车基础软件平台分类 汽车软件主要分为应用软件和基础软件。应用软件和业务形态高度关联&#xff0c;不同控制器的应用软件之间差异较大。基础软件介于应用软件和硬件之间&#xff0c;用于屏蔽硬件特性、支撑应用软件。可有效地实现应用软件与硬件之间解耦&#xff0…