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的初始化总代码

c 复制代码
#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)
	{
	}
}

使用串口来发送数据

实验的简介

串口调试助手参数设置

如何用串口去发送单个字节

左边的代码是对寄存器的直接操作 右边是标准库的库函数操作

发送一个字节的代码

c 复制代码
#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)
	{
	}
}

发送字节数组

发送一个数组

c 复制代码
		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){};

发送字符

c 复制代码
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灯就灭

c 复制代码
#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
		{
		}
	}
}
相关推荐
PegasusYu2 小时前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
lantiandianzi7 小时前
基于单片机的多功能跑步机控制系统
单片机·嵌入式硬件
文弱书生6567 小时前
输出比较简介
stm32
哔哥哔特商务网7 小时前
高集成的MCU方案已成电机应用趋势?
单片机·嵌入式硬件
跟着杰哥学嵌入式7 小时前
单片机进阶硬件部分_day2_项目实践
单片机·嵌入式硬件
东芝、铠侠总代136100683938 小时前
浅谈TLP184小型平面光耦
单片机·嵌入式硬件·物联网·平面
lantiandianzi8 小时前
基于单片机中医药柜管理系统的设计
单片机·嵌入式硬件
嵌入式知识大讲堂8 小时前
HDMI数据传输三种使用场景
单片机
黑客呀9 小时前
[系统安全]Rootkit基础
stm32·单片机·系统安全
小A1599 小时前
STM32完全学习——使用SysTick精确延时(阻塞式)
stm32·嵌入式硬件·学习