京东导购网站开发/seo关键词有话要多少钱
1.USART简介
STM32芯片具有多个USART外设用于串口通讯,它是 Universal Synchronous Asynchronous Receiver and Transmitter的缩写, 即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。有别于USART, 它还有具有UART外设(Universal Asynchronous Receiver and Transmitter),它是在USART基础上裁剪掉了同步通信功能, 只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART。
USART在STM32应用最多莫过于“打印”程序信息,一般在硬件设计时都会预留一个USART通信接口连接电脑, 用于在调试程序是可以把一些调试信息“打印”在电脑端的串口调试助手工具上,从而了解程序运行是否正确、指出运行出错位置等等。
USART只需两根信号线(TX和RX)即可完成双向通信,对硬件要求低,使得很多模块都预留USART接口来实现与其他模块或者控制器进行数据传输, 比如GSM模块,WIFI模块、蓝牙模块等等。在硬件设计时,注意还需要一根“共地线”。
2.USART标准库简介
typedef struct {uint32_t USART_BaudRate; // 波特率uint16_t USART_WordLength; // 字长uint16_t USART_StopBits; // 停止位uint16_t USART_Parity; // 校验位uint16_t USART_Mode; // USART模式uint16_t USART_HardwareFlowControl; // 硬件流控制
} USART_InitTypeDef;
-
USART_BaudRate:波特率设置。一般设置为2400、9600、19200、115200。标准库函数会根据设定值计算得到USARTDIV值, 并设置USART_BRR寄存器值。
-
USART_WordLength:数据帧字长,可选8位或9位。它设定USART_CR1寄存器的M位的值。如果没有使能奇偶校验控制, 一般使用8数据位;如果使能了奇偶校验则一般设置为9数据位。
-
USART_StopBits:停止位设置,可选0.5个、1个、1.5个和2个停止位, 它设定USART_CR2寄存器的STOP[1:0]位的值,一般我们选择1个停止位。
-
USART_Parity:奇偶校验控制选择,可选USART_Parity_No(无校验)、 USART_Parity_Even(偶校验)以及USART_Parity_Odd(奇校验),它设定USART_CR1寄存器的PCE位和PS位的值。
-
USART_Mode:USART模式选择,有USART_Mode_Rx和USART_Mode_Tx, 允许使用逻辑或运算选择两个,它设定USART_CR1寄存器的RE位和TE位。
-
USART_HardwareFlowControl:硬件流控制选择,只有在硬件流控制模式才有效, 可选有使能RTS、使能CTS、同时使能RTS和CTS、不使能硬件流。
当使用同步模式时需要配置SCLK引脚输出脉冲的属性,标准库使用一个时钟初始化结构体USART_ClockInitTypeDef来设置, 因此该结构体内容也只有在同步模式才需要设置。
typedef struct {uint16_t USART_Clock; // 时钟使能控制uint16_t USART_CPOL; // 时钟极性uint16_t USART_CPHA; // 时钟相位uint16_t USART_LastBit; // 最尾位时钟脉冲
} USART_ClockInitTypeDef;
-
USART_Clock:同步模式下SCLK引脚上时钟输出使能控制,可选禁止时钟输出(USART_Clock_Disable)或开启时钟输出(USART_Clock_Enable); 如果使用同步模式发送,一般都需要开启时钟。它设定USART_CR2寄存器的CLKEN位的值。
-
USART_CPOL:同步模式下SCLK引脚上输出时钟极性设置,可设置在空闲时SCLK引脚为低电平(USART_CPOL_Low)或高电平(USART_CPOL_High)。 它设定USART_CR2寄存器的CPOL位的值。
-
USART_CPHA:同步模式下SCLK引脚上输出时钟相位设置,可设置在时钟第一个变化沿捕获数据(USART_CPHA_1Edge)或在时钟第二个变化沿捕获数据。 它设定USART_CR2寄存器的CPHA位的值。USART_CPHA与USART_CPOL配合使用可以获得多种模式时钟关系。
-
USART_LastBit:选择在发送最后一个数据位的时候时钟脉冲是否在SCLK引脚输出,可以是不输出脉冲(USART_LastBit_Disable)、 输出脉冲(USART_LastBit_Enable)。它设定USART_CR2寄存器的LBCL位的值。
3.USART示例
3.1硬件设计
为利用USART实现开发板与电脑通信,需要用到一个USB转USART的IC,我们选择CH340芯片来实现这个功能,这个芯片需要安装驱动。
3.2编程要点
- 使能RX和TX引脚GPIO时钟和USART时钟;
- 初始化GPIO,并将GPIO复用到USART上;
- 配置USART参数;
- 配置中断控制器并使能USART接收中断;
- 使能USART;
- 在USART接收中断服务函数实现数据接收和发送。
void Init_USART(void)
{RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟//USART1对应引脚复用映射GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_USART1);//PA9复用为USART1GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_USART1);//PA10复用为USART1//USART1端口配置GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;//复用功能GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;//推挽复用输出GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;//上拉GPIO_InitStruct.GPIO_Speed=GPIO_Fast_Speed;//速度50MHzGPIO_Init(GPIOA,&GPIO_InitStruct);//初始化PA9,PA10//配置USART参数USART_InitTypeDef USART_Init_Struct;USART_Init_Struct.USART_BaudRate=115200;USART_Init_Struct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_Init_Struct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_Init_Struct.USART_Parity=USART_Parity_No;USART_Init_Struct.USART_StopBits=USART_StopBits_1;USART_Init_Struct.USART_WordLength=USART_WordLength_8b;USART_Init(USART1,&USART_Init_Struct);//配置中断控制器并使能USART接收中断NVIC_InitTypeDef NVIC_Init_Struct;NVIC_Init_Struct.NVIC_IRQChannel=USART1_IRQn;NVIC_Init_Struct.NVIC_IRQChannelCmd=ENABLE;NVIC_Init_Struct.NVIC_IRQChannelPreemptionPriority=1;NVIC_Init_Struct.NVIC_IRQChannelSubPriority=0;NVIC_Init(&NVIC_Init_Struct);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能USARTUSART_Cmd(USART1,ENABLE);
}
void USART1_IRQHandler(void)
{uint8_t ucTemp;if(SET==USART_GetITStatus(USART1,USART_IT_RXNE)){ucTemp = USART_ReceiveData(USART1);USART_SendData(USART1,ucTemp);}
}
int main(void)
{//重新设置系统时钟HSE_SetSysClock(8, 336, 2, 7);//设置中断分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);Init_USART();/* Infinite loop */while (1){}
}
但是,出问题了!!!
出现乱码了!!!到底是哪里出问题了呢???
最后,我们在USART_Init函数中发现蹊跷了。关于波特率的设置,它通过配置值115200,然后通过系统时钟去计算应该配置的寄存器的值。但是,系统时钟的获取函数好像有点问题,因为之前那个宏定义的值不对,所以我们在main函数中又自己实现了系统时钟配置函数。详细可以看【STM32】时钟树系统-CSDN博客。现在看来,我们还是的修改标准库文件了,因为它的函数接口都在使用那个错误的宏定义。
所以,修改了标准库文件中的两个宏定义后,我们就可以在main函数中省略自己配置系统时钟函数了。
int main(void)
{//设置中断分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);Init_USART();/* Infinite loop */while (1){}
}
同时也发现无乱码了。
4.使用USART打印日志
#ifndef __BSP_USART_H
#define __BSP_USART_H#ifdef __cplusplus
extern "C"{#endif#include "stm32f4xx.h"
#include "stdio.h"#define LOGGER_USART USART1
#define LOGGER_USART_BAUDRATE 115200
#define LOGGER_USART_CLK RCC_APB2Periph_USART1
#define LOGGER_USART_IRQHandler USART1_IRQHandler
#define LOGGER_USART_IRQ USART1_IRQn#define USART1_TX_PIN GPIO_Pin_9
#define USART1_TX_GPIO_Port GPIOA
#define USART1_TX_GPIO_CLK RCC_AHB1Periph_GPIOA
#define USART1_TX_AF GPIO_AF_USART1
#define USART1_TX_SOURCE GPIO_PinSource9#define USART1_RX_PIN GPIO_Pin_10
#define USART1_RX_GPIO_Port GPIOA
#define USART1_RX_GPIO_CLK RCC_AHB1Periph_GPIOA
#define USART1_RX_AF GPIO_AF_USART1
#define USART1_RX_SOURCE GPIO_PinSource10void Init_USART(void);#ifdef __cplusplus
}
#endif#endif
#include "bsp_usart.h"void Init_USART(void)
{RCC_AHB1PeriphClockCmd(USART1_TX_GPIO_CLK|USART1_RX_GPIO_CLK,ENABLE);//使能GPIOA时钟RCC_APB2PeriphClockCmd(LOGGER_USART_CLK,ENABLE);//使能USART1时钟//USART1对应引脚复用映射GPIO_PinAFConfig(USART1_TX_GPIO_Port, USART1_TX_SOURCE,USART1_TX_AF);//PA9复用为USART1GPIO_PinAFConfig(USART1_RX_GPIO_Port, USART1_RX_SOURCE,USART1_RX_AF);//PA10复用为USART1//USART1端口配置GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin=USART1_TX_PIN;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;//复用功能GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;//推挽复用输出GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;//上拉GPIO_InitStruct.GPIO_Speed=GPIO_Fast_Speed;//速度50MHzGPIO_Init(USART1_TX_GPIO_Port,&GPIO_InitStruct);//初始化PA9GPIO_InitStruct.GPIO_Pin=USART1_RX_PIN;GPIO_Init(USART1_RX_GPIO_Port,&GPIO_InitStruct);//初始化PA10//配置USART参数USART_InitTypeDef USART_Init_Struct;USART_Init_Struct.USART_BaudRate=LOGGER_USART_BAUDRATE;USART_Init_Struct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_Init_Struct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_Init_Struct.USART_Parity=USART_Parity_No;USART_Init_Struct.USART_StopBits=USART_StopBits_1;USART_Init_Struct.USART_WordLength=USART_WordLength_8b;USART_Init(LOGGER_USART,&USART_Init_Struct);//配置中断控制器并使能USART接收中断NVIC_InitTypeDef NVIC_Init_Struct;NVIC_Init_Struct.NVIC_IRQChannel=LOGGER_USART_IRQ;NVIC_Init_Struct.NVIC_IRQChannelCmd=ENABLE;NVIC_Init_Struct.NVIC_IRQChannelPreemptionPriority=1;NVIC_Init_Struct.NVIC_IRQChannelSubPriority=0;NVIC_Init(&NVIC_Init_Struct);USART_ITConfig(LOGGER_USART,USART_IT_RXNE,ENABLE);//使能USARTUSART_Cmd(LOGGER_USART,ENABLE);
}void LOGGER_USART_IRQHandler(void)
{uint8_t ucTemp;if(SET==USART_GetITStatus(LOGGER_USART,USART_IT_RXNE)){ucTemp = USART_ReceiveData(LOGGER_USART);USART_SendData(LOGGER_USART,ucTemp);}
}//重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{/* 发送一个字节数据到串口 */USART_SendData(LOGGER_USART, (uint8_t) ch);/* 等待发送完毕 */while (USART_GetFlagStatus(LOGGER_USART, USART_FLAG_TXE) == RESET);return (ch);
}
#include "bsp_usart.h"void delay(uint32_t cnt)
{while(cnt--);
}int main(void)
{//设置中断分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);Init_USART();/* Infinite loop */while (1){printf("hello,i am logger!\r\n");delay(0xfffffff);}
}
这样,我们就可以使用printf函数直接输出到串口上了。
在C语言标准库中,fputc函数是printf函数内部的一个函数,功能是将字符ch写入到文件指针f所指向文件的当前写指针位置, 简单理解就是把字符写入到特定文件中。我们使用USART函数重新修改fputc函数内容,达到类似“写入”的功能。
fgetc函数与fputc函数非常相似,实现字符读取功能。在使用scanf函数时需要注意字符输入格式。
还有一点需要注意的,使用fput和fgetc函数达到重定向C语言标准库输入输出函数必须在MDK的工程选项把“Use MicroLIB”勾选上, MicoroLIB是缺省C库的备选库,它对标准C库进行了高度优化使代码更少,占用更少资源。
为使用printf、scanf函数需要在文件中包含stdio.h头文件。
相关文章:

【STM32】USART串口通讯
1.USART简介 STM32芯片具有多个USART外设用于串口通讯,它是 Universal Synchronous Asynchronous Receiver and Transmitter的缩写, 即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。有别于USART, 它还有具有UART外设(Univers…...

Qt6中如何将QList转为QSet?
QSet是一个具有唯一值的哈希集合。比较少用。比较有用的是QSet里面的intersect查找两个集合中不同元素,并合并。 转换过程比较简单,第一种是直接用迭代器。 QSet<int> set(list.begin(), list.end()); 第二种就是逐一遍历赋值: QLi…...

aspectj:AOP编程备忘录-切面定义的注意事项
AOP编程时定义切面时需要注意的事 Around 以Around注解拦截构造方法(Constructor)时切面定义只能用call方式而不能是execution,否则 ProceedingJoinPoint.proceed()返回的是null,得不到构造的实例。 execution execution切入点要修改对象内部&#x…...

大数据面试题之Hive(1)
目录 说下为什么要使用Hive?Hive的优缺点?Hive的作用是什么? 说下Hive是什么?跟数据仓库区别? Hive架构 Hive内部表和外部表的区别? 为什么内部表的删除,就会将数据全部删除,而外部表只删除表结构?为什么用外部表更好? Hive建表语句?创建表…...

【Git】分布式版本控制工具
一、简介 二、目标 Git分布式版本控制工具 一、简介 Git是一种分布式版本控制系统,用于跟踪和管理源代码的变化。它由林纳斯托瓦兹(Linus Torvalds)于2005年开发,并迅速成为最流行的版本控制工具之一。以下是关于Git的一些关键…...

排序之插入排序----直接插入排序和希尔排序(1)
个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 排序之插入排序----直接插入排序和希尔排序(1) 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记,欢迎大家在评论区交流讨…...

快速创建条形热力图
Excel中的条件格式可以有效的凸显数据特征,如下图中B列所示。 现在需要使用图表展现热力条形图,如下图所示。由于颜色有多个过渡色,因此手工逐个设置数据条的颜色,基本上是不可能完成的任务,使用VBA代码可以快速创建这…...

go switch 与 interface
go switch 与 interface 前言 前言 github.com/google/cel-go/common/types/ref type Val interface {// ConvertToNative converts the Value to a native Go struct according to the// reflected type description, or error if the conversion is not feasible.ConvertTo…...

BaseMapper 接口介绍
基于 mybatis-mapper/provider 核心部分实现的基础的增删改查操作,提供了一个核心的 io.mybatis.mapper.BaseMapper 接口和一个 预定义 的 io.mybatis.mapper.Mapper 接口,BaseMapper 接口定义如下: /*** 基础 Mapper 方法,可以在…...

HAL-Cubemax定时器使用记录
title: HAL-Cubemax定时器使用记录 tags: STM32HalCubemax 文章目录 HAL-Cubemax定时器使用记录分享一种思路1.创建一个ms(毫秒)级延时中断2.创建计数的变量3.在需要延时的函数中对变量阈值进行判断4.验证实例--完整使用记录代码 问题往期内容基础库HAL cubemax VSCODE GCC …...

同时使用磁吸充电器和Lightning时,iPhone充电速度会变快吗?
在智能手机的世界里,续航能力一直是用户关注的焦点。苹果公司以其创新的MagSafe技术和传统的Lightning接口,为iPhone用户提供了多样化的充电解决方案。 然而,当这两种技术同时使用时,它们能否带来更快的充电速度?本文…...

零成本搭建个人图床服务器
前言 图床服务器是一种用于存储和管理图片的服务器,可以给我们提供将图片上传后能外部访问浏览的服务。这样我们在写文章时插入的说明图片,就可以集中放到图床里,既方便多平台文章发布,又能统一管理和备份。 当然下面通过在 Git…...

SpringBoot 搭建sftp服务 实现远程上传和下载文件
maven依赖: <dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version> </dependency>application.yml sftp:protocol: sftphost: port: 22username: rootpassword: sp…...

IDEA中使用leetcode 刷题
目录 1.IDEA下载leetcode插件 2.侧边点开插件 3.打开网页版登录找到cookie复制 4.回到IDEA登录 5.刷题 6.共勉 1.IDEA下载leetcode插件 2.侧边点开插件 3.打开网页版登录找到cookie复制 4.回到IDEA登录 5.刷题 6.共勉 算法题来了不畏惧, 挑战前行是成长的舞台…...

华为海思CPU解读
安全可靠CPU测评结果(华为海思篇) 中国信息安全测评中心于2024年5月20日发布安全可靠测评结果公告(2024年第1号),公布依据《安全可靠测评工作指南(试行)》的测评结果,自发布起有效期…...

中介子方程三十三
XXFXXuXXWXXuXXdXXrXXαXXuXpXXdXXpXuXXαXXrXXdXXuXWXπXXWXeXyXeXbXπXpXXNXXqXeXXrXXαXXuXpXXdXXpXuXXαXXrXXeXqXXNXXpXπXbXeXyXeXWXXπXWXuXXdXXrXXαXXuXpXXdXXpXuXXαXXrXXdXXuXXWXXuXXFXXEXXyXXEXXrXXαXXuXpXXdXXpXuXXαXXrXXEXXyXXαXiXXαXiXrXkXtXyXXpXVXXdXuXWX…...

今年哪两个行业可能有贝塔?
银行和综合板块存在比较明显的行业贝塔,背后原因是:银行板块中,最小的几家银行市值也不小;综合板块中,最大的几家市值也不大。 一、今年哪两个行业可能有贝塔? 我们一直强调今年市场呈现出【行业弱beta、风…...

嵌入式软件开发工具使用介绍
软件开发工具 辅助开发工具 硬件工具与仪器设备 逻辑分析仪使用 串口数据解码分析 示波器使用 1.示波器简介 TBS 1052B(Tektronix)系列数字存储示波器在紧凑的设计中提供了经济的性能。 由于多种标配功能, 包括 USB 连接、34 种自动测量、…...

【TB作品】MSP430G2553,单片机,口袋板, 交通灯控制系统
题8 交通灯控制系统 十字路口交通灯由红、绿两色LED显示器(两位8段LED显示器)组成,LED显示器显示切换倒计时,以秒为单位,每秒更新一次;为确保安全,绿LED计数到0转红,经5秒延时&#…...

windows 安装 Kubernetes(k8s)
windows 安装 docker 详情见: https://blog.csdn.net/sinat_32502451/article/details/133026301 minikube Minikube 是一种轻量级的Kubernetes 实现,可在本地计算机上创建VM 并部署仅包含一个节点的简单集群。 下载地址:https://github.…...

C语言 | Leetcode C语言题解之第189题轮转数组
题目: 题解: void swap(int* a, int* b) {int t *a;*a *b, *b t; }void reverse(int* nums, int start, int end) {while (start < end) {swap(&nums[start], &nums[end]);start 1;end - 1;} }void rotate(int* nums, int numsSize, int…...

【安全审核】音视频审核开通以及计费相关
融云控制台音视频审核入口:音视频审核 1 音视频审核文档:融云开发者文档 1 提示: 开发环境: 免费体验 7 天(含 21 万分钟音频流和 420 万张视频审核用量),免费额度用尽后,将关停服务…...

【实战】Spring Cloud Stream 3.1+整合Kafka
文章目录 前言新版版本优势实战演示增加maven依赖增加applicaiton.yaml配置新增Kafka通道消费者新增发送消息的接口 实战测试postman发送一个正常的消息postman发送异常消息 前言 之前我们已经整合过Spring Cloud Stream 3.0版本与Kafka、RabbitMQ中间件,简直不要太…...

java之可变字符串之append方法
可变字符串如果要添加内容,需要用到append方法 语法格式如下 sbf.append(obj) 其中sbf是任意的可变字符串 obj是任意数据类型的对象 这个方法是将任意数据转换成字符串,然后添加到此序列中 public class Buffer {public static void main(String[]…...

[保姆级教程]uniapp自定义导航栏
文章目录 导文隐藏默认导航栏:全局隐藏当前页面隐藏 添加自定义导航栏视图:手写导航栏组件导航栏 导文 在 UniApp 中,自定义导航栏通常涉及到隐藏默认的导航栏,并在页面顶部添加自定义的视图组件来模拟导航栏的功能。 隐藏默认导航…...

项目训练营第二天
项目训练营第二天 用户登录逻辑 1、账户名不少于4位 2、密码不少于8位 3、数据库表中能够查询到账户、密码 4、密码查询时用同样加密脱敏处理手段处理后再和数据库中取出字段进行对比,如果账户名未查询到,直接返回null 5、后端设置相应的脱敏后用户的s…...

考研数学一有多难?130+背后的残酷真相
考研数学一很难 大家平时在网上上看到很多人说自己考了130,其实这些人只占参加考研数学人数的极少部分,有个数据可以展示出来考研数学到底有多难: 在几百万考研大军中,能考到120分以上的考生只有2%。绝大多数人的分数集中在30到…...

vue2脚手架笔记总结1
1.什么是组件 组件是实现局部代码和功能资源的集合 2.vue.config.js配置文件 使用vue inspect > output.js可以查看到Vue脚手架的默认配置,但是在这里面修改不会影响实际的配置,如果需要修改配置需要使用用vue.config.js文件,详情见:https://cli.vuej…...

校园巡礼:一周只上四天课,入学即发钱?深圳理工大学,开局即王炸
校园巡礼 | 一周只上四天课,入学即发钱?深圳理工大学,开局即王炸! 会议之眼 快讯 目前各省的高考成绩现已陆续揭晓,广东省教育考试院发布了2024年高考录取最低分数线,物理类本科线为442分,历史…...

免交互 实验
免交互 交互:我们发出指令控制程序的运行,程序在接收到指令之后按照指令的效果做出对应的反应。 免交互:间接的,通过第三方的方式把指令传送给程序,不用直接下达指令。 Here document 免交互 这是命令行格式&#…...