• 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)
    	{
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

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

    #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)
    	{
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

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

    		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){};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    发送字符

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    串口接收数据
    ![在这里插入图片描述在这里插入图片描述![](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
    //		{
    //			//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
    		{
    		}
    	}
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
  • 相关阅读:
    写给Java应用开发看的Elasticsearch调优手册
    CV 面试指南—深度学习知识点总结(5)
    【Proteus仿真】【Arduino单片机】LED
    线性代数笔记18--行列式公式、代数余子式
    shiro安全框架的学习笔记
    Spring的SmartLifecycle可以没用过,但没听过就不好了! - 第517篇
    haskell 的where 或者 let ..in 表达式
    【RKNN】YOLO V5中pytorch2onnx,pytorch和onnx模型输出不一致,精度降低
    手机如何开启开发者选项? (小米为例)
    【MySQL系列】MySQL 字符集的演变与选择
  • 原文地址:https://blog.csdn.net/qq_74185687/article/details/134515480