USART的标准库编程

news2024/11/15 17:50:22

使用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
		{
		}
	}
}


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科技赋能,创新发展!英码科技受邀参加2023中国创新创业成果交易会

11月17日至19日&#xff0c;2023中国创新创业成果交易会&#xff08;简称&#xff1a;创交会&#xff09;在广州市广交会展馆圆满举行。英码科技受邀参加本届创交会&#xff0c;并在会场展示了创新性的AIoT产品、深元AI引擎和行业热门解决方案。 据介绍&#xff0c;本届创交会由…

RT-Thread Hoist_Motor PID

本节介绍的是一个举升电机&#xff0c;顾名思义&#xff0c;通过转轴控制物体升降&#xff0c;为双通道磁性译码器&#xff0c;利用电调进行操控&#xff0c;具体驱动类似于大学期间最大众的SG180舵机&#xff0c;在一定的频率下&#xff0c;通过调制脉宽进行控制。 设备介绍…

V100 GPU服务器安装CUDNN教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Startdrive中上传参数设置的具体方法和注意事项

Startdrive中上传参数设置的具体方法和注意事项 适用于配 SINAMICS S120、G130、G150、S150和MV(基于CU3x0-2的驱动器)和所有启动驱动器版本INAMICS G115D/G120/G120D/G120C/G120P/G110M(基于CU2x0-2的驱动器) 根据SINAMICS类型的不同,Startdrive中的Upload参数有所不同。…

机器人制作开源方案 | 莲花灯

1. 功能描述 莲花灯是一款基于莲花形象设计的机器人&#xff0c;本文示例将用两种模式来实现莲花灯的亮灭功能。 自主模式&#xff1a;用 光强传感器 控制莲花灯的灯叶开合。暗光情况下灯叶打开&#xff0c;灯亮&#xff1b;强光情况下灯叶闭合&#xff0c;灯灭。 …

TensorFlow实战教程(一)-TensorFlow环境部署

从本篇文章开始,作者正式开始研究Python深度学习、神经网络及人工智能相关知识。第一篇文章主要讲解神经网络基础概念,同时讲解TensorFlow2.0的安装过程及基础用法,主要结合作者之前的博客和"莫烦大神"的视频介绍,后面随着深入会讲解具体的项目及应用。基础性文章…

Ubuntu20上离线安装samba

如果联网&#xff0c;一条 sudo apt-get install samba就可能解决问题&#xff0c;但是没有网&#xff0c;那么只能一个一个的解决问题&#xff1a; 我以为装了samba-common就可以了&#xff0c;发现smbd.serverice not found,于是开始了漫长的下载依赖包&#xff0c;安装&…

Leetcode刷题之有效的括号(C语言版)

Leetcode刷题之有效的括号&#xff08;C语言版&#xff09; 一、题目描述二、题目测试用例三、题目分析四、完整代码 一、题目描述 20、有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是…

智能高效的转运机器人,为物流行业注入新动力

在当今社会&#xff0c;随着科技的不断发展&#xff0c;机器人已经逐渐融入到我们的生活中。其中&#xff0c;转运机器人作为物流行业的新秀&#xff0c;正以其高效、智能的特点&#xff0c;引起了广泛的关注。 转运机器人&#xff0c;是指能够自主进行物品搬运和运输的机器人…

Python---变量的作用域

变量作用域&#xff1a;指的是变量的作用范围&#xff08;变量在哪里可用&#xff0c;在哪里不可用&#xff09;&#xff0c;主要分为两类&#xff1a;局部变量和全局变量。 定义在函数外部的变量就称之为全局变量&#xff1b; 定义在函数内部的变量就称之为局部变量。 # 定义…

Java 设计模式——桥接模式

目录 1.概述2.结构3.实现3.1.实现化类3.2.具体实现化类3.3.抽象化类3.4.扩展抽象化类3.5.测试 4.优缺点5.使用场景 1.概述 &#xff08;1&#xff09;现在有一个需求&#xff0c;需要创建不同的图形&#xff0c;并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来…

ssm青少年航天知识科普网站-计算机毕设 附源码59487

青少年航天知识科普网站 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&am…

MySQL数据库——存储过程-条件处理程序(通过SQLSTATE指定具体的状态码,通过SQLSTATE的代码简写方式 NOT FOUND)

目录 介绍 案例 通过SQLSTATE指定具体的状态码 通过SQLSTATE的代码简写方式 NOT FOUND 介绍 条件处理程序&#xff08;Handler&#xff09;可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。具体语法为&#xff1a; DECLARE handler_action HANDLER FOR c…

技术为业务赋能:深度剖析开发与业务的紧密结合

技术为业务赋能&#xff1a;深度剖析开发与业务的紧密结合 很多做开发的同学有一种认知&#xff0c;技术最牛&#xff0c;进而忽视了对业务的理解和积累&#xff0c;眼里认为技术和游戏一样&#xff0c;有着层出不穷的新技术&#xff0c;更新迭代的非常快&#xff0c;而业务方…

C/C++内存管理(1):C/C++内存分布,C++内存管理方式

一、C/C内存分布 1.1 1.2 二、C内存管理方式 C可以通过操作符new和delete进行动态内存管理。 2.1 new和delete操作内置类型 int main() {int* p1 new int;// 注意区分p2和p3int* p2 new int(10);// 对*p2进行初始化 10int* p3 new int[10];// p3 指向一块40个字节的int类…

FL Studio21.2.0.3858免激活版安装下载

前阵子世界级电音盛会Tomorrowland在比利时如期举行&#xff0c;拉开了疫情下Rave文化复兴的帷幕。而国内&#xff0c;也推出了如《超感星电音》等电子音乐综艺&#xff0c;在节目上大家也更多地了解到了电子音乐的制作过程。节目中最被大家看好的制作人Carta所使用的FL Studio…

Vue2系列 -- 组件自动化全局注册(require.context)

参考官网&#xff1a;https://v2.cn.vuejs.org/v2/guide/components-registration.html 1 作用 省略 import 引入组件 省略 在main.js 中注册 实现自动化引入组件 2 自定义文件夹 在 src 下新建一个 components/base 文件夹&#xff0c;用于存放要自动注册的组件 3 在 base…

练习八-利用有限状态机进行时序逻辑的设计

利用有限状态机进行时序逻辑的设计 1&#xff0c;任务目的&#xff1a;2&#xff0c;RTL代码&#xff0c;及原理框图3&#xff0c;测试代码&#xff0c;输出波形 1&#xff0c;任务目的&#xff1a; &#xff08;1&#xff09;掌握利用有限状态机实现一般时序逻辑分析的方法&am…

Python pip 镜像源设置指南

文章目录 Python pip 镜像源设置指南前言安装单个包使用PyPI镜像使用镜像升级 pip设为默认pip镜像结语 Python pip 镜像源设置指南 前言 平时在使用 pip 安装一些包的时候速度非常慢,本文介绍如何在 Python3 下设置 PyPI 设置镜像源,本文以给 Python3 设置清华 镜像源举例. …

智能座舱架构与芯片 - (2) 架构篇

一、定义 1.1 智能座舱定义 按照百度百科的定义&#xff0c;智能座舱&#xff08;intelligent cabin&#xff09;旨在集成多种IT和人工智能技术&#xff0c;打造全新的车内一体化数字平台&#xff0c;为驾驶员提供智能体验&#xff0c;促进行车安全。目前国内外已经有很多研究…