STM32——USART—串口发送

news/2025/3/10 3:23:33/

目录

一:USART简介

二:初始化USART

1.开启时钟 

2.代码 

三:USART发送数据

1.USART发送数据函数

2.获取标志位的状态

3.代码 

4.在main.c内调用 

 5.串口调试

1.串口选择要与设备管理器中的端口保持一致

 2.波特率、停止位等要与前面USART设置的一致

6.结果

7.ASCLL码值表

四:USART发送数组

1.代码

2.显示结果

五:USART发送字符串 

1.代码

2.结果

六: 调用SendNumber发送数字的每一位

1.数字拆分

2.代码

3.结果 

七:Printf函数的移值方法

1.勾上MicroLIB

  2.对printf进行重定向

3.乱码解决方案


 

一:USART简介

  • USART(Universal Synchronous/Asynchronous Receiver/Transmitter)是STM32微控制器内部集成的一个硬件外设,用于串行数据通信。它能够根据数据寄存器中的一个字节数据自动生成数据帧时序,并通过TX引脚发送出去,同时也可以自动接收RX引脚的数据帧时序,将其拼接成一个字节数据并存放在数据寄存器中。

  • 可配置数据位长度(8/9需要校验位就是9位),停止位长度(0.5/1/1.5/2)

  • 可选校验位:无校验,奇校验,偶校验

  • 引脚:TX、RX(TX引脚输出定时器翻转的高低电平,RX定时读取引脚的高低电平)

  • 全双工(双方都可以进行通信)

  • STM32F103C8T6 USART资源:USART1,USART2,USART3

初始化完成之后,如果要发送数据,调用一个发送函数就行了。如果要接收数据,发送一个接收函数就好了。如果燕获取发送和接收的状态,就调用获取标志位的函数。

函数

  • void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);写DR寄存器

    uint16_t USART_ReceiveData(USART_TypeDef* USARTx);读DR寄存器

二:初始化USART

  • 第一步:开启时钟,把需要的USART和GPIO的时钟打开

  • 第二步:GPIO初始化,把TX配置成复用输出,RX配置成输入

  • 第三步:配置USART,直接使用一个结构体

  • 第四步:如果只需要一个发送功能,只需要把USART直接开启就好了,初始化结束。如果需要中断功能,就要在开启USART之前,再加上Config和NVIC的代码。

1.开启时钟 

由STM32引脚定义可知,USART1_TX对应的是PA9,USART1_RX对应的是PA10,所以要给GPIOA的端口使能

由图可知,USART和GPIOA口都在ABP2总线上,所以给ABP2时钟使能

2.代码 

//开启USART和GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//GPIO初始化GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //配置USARTUSART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600;//波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位USART_InitStructure.USART_Parity = USART_Parity_No; //校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Tx;//输出端口USART_Init(USART1, &USART_InitStructure); //使能USARTUSART_Cmd(USART1, ENABLE);

三:USART发送数据

1.USART发送数据函数

  • 函数名:USART_ SendData 
  • 功能描述:通过外设USARTx发送单个数据
  • 输入参数1:USARTxx可以是12或者3,来选择USART外设
  • 输入参数二:Data: 待发送的数据
  • 函数原型:void USART_SendData(USART_TypeDef* USARTx, u8 Data)

2.获取标志位的状态

  • 函数名:USART_ GetFlagStatus
  • 功能描述:检查指定的USART标志位设置与否
  • 输入参数1:SARTxx可以是12或者3,来选择USART外设
  • 输入参数2:USART_FLAG:待检查的USART标志位
  • 下图是参数2可取的值
  • 相关状态的描述

 

3.代码 

void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
}

4.在main.c内调用 

//初始化串口Serial_Init();//用串口发送一个0x41Serial_SendByte(0x41);

 5.串口调试

1.串口选择要与设备管理器中的端口保持一致

 

 

 2.波特率、停止位等要与前面USART设置的一致

6.结果

我们一开始显示的是字符串的形式

如果想显示16进制,就勾上“16进制显示”,就出现41

 

7.ASCLL码值表

 

四:USART发送数组

1.代码

void Serial_SendArray(uint8_t *Array,uint16_t Length)
{uint16_t i;for(i=0;i<Length;i++){Serial_SendByte(Array[i]);//调用发送数据函数}
}

主函数调用

uint8_t MyArray[]={0x40,0x41,0x42,0x43};Serial_SendArray(MyArray,4);

2.显示结果

五:USART发送字符串 

注意:“\0”是字符串结束的标志位,'\r''\n'换行

1.代码

void Serial_SendSrting(char *String)
{uint8_t i;for(i=0;String[i]!='\0';i++){Serial_SendByte(String[i]);}
}

主函数调用

Serial_SendSrting("HelloWord!\r\n");

 

2.结果

六: 调用SendNumber发送数字的每一位

1.数字拆分

取某一位就是,数字/(10^x)%10(其中x=数字的位数-1,比如数字是三位的,则x取2),列如:取123的1,就用123/10^2%10 余数就为1

2.代码

//次方函数 x的Y次方
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{int Result=1;while(Y--){Result*= X;}return Result;
}//发送数字的每一位
void Serial_SendNumber(uint32_t Number,uint8_t Length)
{uint8_t i;for(i=0;i<Length;i++){Serial_SendByte(Number/Serial_Pow(10,Length-1-i)%10+'0');//'0'是加一个偏移}
}

主函数调用

Serial_SendNumber(12345,5);

3.结果 

 

七:Printf函数的移值方法

1.勾上MicroLIB

  2.对printf进行重定向

  • 在串口模块里最开始加上#include <stdio.h>
  • 再重写fputc函数:int fputc(int ch,FILE *f)
  • 在函数里面,把fputc重定向到串口,就是Serial_SendByte(ch)
  • 最后return ch;
  • 原理:因为fputv是printf的底层,printf函数在打印的时候,就是不断调用fputc函数一个个打印的,把fputc函数重定向到串口,printf就输出到端口了。
  • 代码
    int fputc(int ch,FILE *f)
    {Serial_SendByte(ch);return ch;
    }

    3.乱码解决方案

第一种:因为我们Keil5汉字编写格式选的是UTF8,所以最终串口也得选择UTF8

第二种:切换为GB2312编码


http://www.ppmy.cn/news/1577965.html

相关文章

Linux权限维持之vim python 扩展后门(五)

适用于安装了vim且安装了python扩展(绝大版本默认安装)的linux系统。 cd /usr/lib/python2.7/site-packages && $(nohup vim -E -c "pyfile dir.py"> /dev/null 2>&1 &) && sleep 2 && rm -f dir.py$(nohup vim -E -c "…

蓝桥备赛(13)- 链表和 list(下)

一、动态链表 - list (了解) new 和 delete 是非常耗时的操作 在算法比赛中&#xff0c;一般不会使使用 new 和 delete 去模拟实现一个链表。 而且STL 里面的 list 的底层就是动态实现的双向循环链表&#xff0c;增删会涉及 new 和 delete&#xff0c;效率不高&#xff0c;竞赛…

LINUX网络基础 [五] - HTTP协议

目录 HTTP协议 预备知识 认识 URL 认识 urlencode 和 urldecode HTTP协议格式 HTTP请求协议格式 HTTP响应协议格式 HTTP的方法 HTTP的状态码 ​编辑HTTP常见Header HTTP实现代码 HttpServer.hpp HttpServer.cpp Socket.hpp log.hpp Makefile Web根目录 H…

【Java开发指南 | 第三十四篇】IDEA没有Java Enterprise——解决方法

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 1、新建Java项目2、单击项目名&#xff0c;并连续按两次shift键3、在搜索栏搜索"添加框架支持"4、勾选Web应用程序5、最终界面6、添加Tomcat 1、新建Java项目 2、单击项目名&#xff0c;并连续按两次…

【五.LangChain技术与应用】【12.LangChain语言模型介绍:AI语言处理的核心技术】

(敲黑板)各位老铁坐稳了!今儿咱们要深扒LangChain里最硬核的语言模型模块,这玩意儿简直就是AI界的"翻译官+编剧+军师"三合一。我翻烂了官方文档,结合全网20+篇技术贴,给你们整出这篇万字脱水指南! 一、LangChain是啥?——给大模型装个USB接口 想象你要用Cha…

使用 Node.js 部署高性能应用:从入门到进阶

使用 Node.js 部署高性能应用:从入门到进阶 大家好,我是你们的运维伙伴Echo_Wish。今天我们来探讨如何使用Node.js部署高性能应用。Node.js因其异步非阻塞I/O模型、高效的事件驱动架构以及强大的包管理器npm,成为了现代Web开发的重要工具。我们将从简单的应用入手,逐步深入…

10.RabbitMQ集群

十、集群与高可用 RabbitMQ 的集群分两种模式,一种是默认集群模式,一种是镜像集群模式&#xff1b; 在RabbitMQ集群中所有的节点(一个节点就是一个RabbitMQ的broker服务器) 被归为两类:一类是磁盘节点,一类是内存节点&#xff1b; 磁盘节点会把集群的所有信息(比如交换机、绑…

计算机三级网络技术知识点汇总【7】

第七章 路由器配置及使用 1. 路由器的基础知识 1.1 路由器的基本概念 路由器是工作在网络层的设备&#xff0c;负责将数据分组从源端主机经最佳路径传送到目的端主机&#xff0c;实现在网络层的互联。路由器工作在 TCP/IP 网络模型的网络层&#xff0c;对应于 OSI 网络参考模…