USART的标准库编程

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

UASRT标准库编程接口

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

USART的初始化

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

使用串口来发送数据
实验的简介
USART的标准库编程_第25张图片
串口调试助手参数设置
USART的标准库编程_第26张图片
如何用串口去发送单个字节
USART的标准库编程_第27张图片
左边的代码是对寄存器的直接操作 右边是标准库的库函数操作
USART的标准库编程_第28张图片
发送一个字节的代码

#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)
	{
	}
}

发送字节数组
USART的标准库编程_第29张图片
发送一个数组

		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)
USART的标准库编程_第30张图片
USART的标准库编程_第31张图片
发送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
//		{
//			//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
		{
		}
	}
}


你可能感兴趣的:(单片机,stm32)