USART串口通讯函数实现 (基于寄存器)

news2024/9/27 5:49:47

环境

芯片:STM32F103ZET6

库:来自HAL的STM32F1XX.H

原理图

如图可知TX和RX两条线接到了PA9和PA10

  • Driver_USART1.h

    • #ifndef __DRIVER_USART1_H
      #define __DRIVER_USART1_H
      
      #include "stm32f1xx.h"
      
      /**
       * 初始化USART1  完成相关配置 能够调用下面收发数据的代码
       */
      void Driver_USART1_Init(void);
      
      /**
       * 发送一个字节
       * uint8_t ch: 需要发送的一个字节
       */
      void Driver_USART1_SendChar(uint8_t ch);
      
      /**
       * 接收一个字节
       * return: uint8_t 接收到的字节
       */
      uint8_t Driver_USART1_ReceiveChar(void);
      
      /**
       * 发送多个字节
       * uint8_t *str: 一个字符串
       * uint8_t len: 字符串长度
       */
      void Driver_USART1_SendString(uint8_t *str,uint8_t len);
      
      /**
       * 接收多个字节  ->  由于不能确定接收数据的长度 ->  推荐buff够大
       * 收到空闲位结束
       * uint8_t buff[]: 存接收到的数据
       * uint8_t * len: 实际接收数据的长度 -> 需要函数中赋值
       */
      void Driver_USART1_ReceiveString(uint8_t buff[],uint8_t * len);
      
      #endif
      
  •  Driver_USART1.c

    • #include "Driver_USART1.h"
      
      /**
       * 初始化USART1  完成相关配置 能够调用下面收发数据的代码
       */
      void Driver_USART1_Init(void)
      {
          /* 1. 打开USART1相关时钟 AFIO主要控制事件和外部中断 -> 片上外设的复用引脚有专门的位控制 */
          RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
          RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
          /* 2. 配置使用到的引脚模式  ->  PA9 TX 复用推挽输出 1011 ->  PA10 RX 浮空输入模式  0100 */
          GPIOA->CRH |= (GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9);
          GPIOA->CRH &= ~(GPIO_CRH_CNF9_0);
      
          GPIOA->CRH |= GPIO_CRH_CNF10_0;
          GPIOA->CRH &= ~(GPIO_CRH_CNF10_1 | GPIO_CRH_MODE10);
      
          /* 3. 配置USART1 */
          // 3.1 配置波特比率
          USART1->BRR = 0X0271;
          // 3.2 数据长度  8位
          USART1->CR1 &= ~(USART_CR1_M);
          // 3.3 校验位
          USART1->CR1 &= ~(USART_CR1_PCE);
          // 3.4 停止位
          USART1->CR2 &= ~(USART_CR2_STOP);
      
          // 3.5 打开使能开关
          // 3.5.1 发送开关
          USART1->CR1 |= USART_CR1_TE;
          // 3.5.2 接收开关
          USART1->CR1 |= USART_CR1_RE;
          // 3.5.3 总开关
          USART1->CR1 |= USART_CR1_UE;
      }
      
      /**
       * 发送一个字节
       * uint8_t ch: 需要发送的一个字节
       */
      void Driver_USART1_SendChar(uint8_t ch)
      {
          // 往DR寄存器直接写 -> 发送数据
          // 需要等待上一个字节发送完成之后  ->  才能发送下一个字节
          // SR_TXE   如果数据正在发 ->  0
          //          如果数据发生完成 -> 1
          while ((USART1->SR & USART_SR_TXE) == 0)
              ;
      
          USART1->DR = ch;
      }
      
      /**
       * 接收一个字节
       * return: uint8_t 接收到的字节
       */
      uint8_t Driver_USART1_ReceiveChar(void)
      {
          // 接收数据也需要挂起 -> 等待有数据传入
          // SR_RXNE : 有数据进来 -> 1
          //           读取一次之后 -> 0
          while ((USART1->SR & USART_SR_RXNE) == 0)
              ;
          return USART1->DR;
      }
      
      /**
       * 发送多个字节
       * uint8_t *str: 一个字符串
       * uint8_t len: 字符串长度
       */
      void Driver_USART1_SendString(uint8_t *str, uint8_t len)
      {
          for (uint8_t i = 0; i < len; i++)
          {
              Driver_USART1_SendChar(str[i]);
          }
      }
      
      /**
       * 接收多个字节  ->  由于不能确定接收数据的长度 ->  推荐buff够大
       * 收到空闲位结束
       * uint8_t buff[]: 存接收到的数据
       * uint8_t * len: 实际接收数据的长度 -> 需要函数中赋值
       */
      void Driver_USART1_ReceiveString(uint8_t buff[], uint8_t *len)
      {
          uint8_t i = 0;
          while (1)
          {
              // 1. 收到数据  存缓存
              if (USART1->SR & USART_SR_RXNE)
              {
                  buff[i] = USART1->DR;
                  i++;
              }
      
              // 2. 收到空闲 停止
              if (USART1->SR & USART_SR_IDLE)
              {
                  
                  *len = i;
                  break;
              }
      
          }
      }
      
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2067331.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java的汽车在线销售系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Java技术 MySQL数据库 B/S结构 SSM框架 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展…

学院党员管理系统

TOC ssm002学院党员管理系统jsp 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各行业&#…

从零开始学习深度学习库-6:集成新的自动微分模块和MNIST数字分类器

在上一篇文章中&#xff0c;我们完成了自动微分模块的代码。深度学习库依赖于自动微分模块来处理模型训练期间的反向传播过程。然而&#xff0c;我们的库目前还是“手工”计算权重导数。现在我们拥有了自己的自动微分模块&#xff0c;接下来让我们的库使用它来执行反向传播吧&a…

【深度分析】从《黑神话:悟空》看国产游戏的出海之路

8月20日&#xff0c;中国3A游戏《黑神话&#xff1a;悟空》正式上线并全球发行。正式发布后不到一小时&#xff0c;《黑神话&#xff1a;悟空》就超越《CS2》成为Steam&#xff08;全球最大的综合性数字发行平台之一&#xff09;最受欢迎游戏排行榜冠军&#xff0c;同时在线玩家…

进阶-3.SQL优化

SQL优化 1. 插入数据2.主键优化3.order by 优化4.group by 优化5.limit优化6.count优化7.update优化8.总结 1. 插入数据 insert优化 批量插入 insert into user values(1,tom),(2,Cat),(3,Hello);手动事务提交 start transaction; insert into user values(1,tom),(2,Cat),…

区块链浪潮:Web3时代的数字经济新格局

随着科技的迅猛发展&#xff0c;全球经济正迎来一场前所未有的变革&#xff0c;区块链技术正在其中扮演着关键角色。Web3作为下一代互联网的核心&#xff0c;正在通过区块链技术重塑数字经济的格局&#xff0c;为全球市场带来新的机遇和挑战。这场以去中心化为特征的技术革命&a…

『功能项目』鼠标双击人物跟随【03】

我们打开上一篇02的射线点击项目&#xff0c; 本章要做的事情是在PlayerRayNavgation脚本中添加一个双击跟随函数&#xff0c;实现人物在场景中鼠标双击后主角跟随鼠标移动功能。 添加代码后保存代码运行项目&#xff0c;鼠标双击后主角即可实现跟随鼠标移动效果。 本篇只实现了…

PHP之 in_array判断出来的结果错误

示例 <?php $a "[232087,232468,234691,235390,235513,235550,235573,235611,235636,235637,235652,235672,235674,235695,235697,235711,235721,235733,235739,235754,235764,235795,235808,235833,235834,235836,235857,235861,235870,235883,235887,235888,23591…

STM32————SPI硬件外设实现读写

首先是理论知识&#xff1a; 常用8位数据帧、高位先行 SPI的时钟由PCLK内部时钟分频得来&#xff0c;最大可到36MHz 精简为半双工就是去掉一根数据线后&#xff0c;用剩下的一根作为发送/接收数据&#xff1b;单工就是去掉接收线&#xff0c;只用发送线进行发送数据&#xf…

python绘制爱心代码

效果展示 完整代码 Python中绘制爱心的代码可以通过多种方式实现&#xff0c;高级的爱心代码通常指的是使用较复杂的算法或者图形库来生成更加精致的爱心图形。下面是一个使用Python的Turtle模块来绘制爱心的示例代码&#xff1a; import turtledef draw_love():turtle.speed…

python-货物种类(赛氪OJ)

[题目描述] 某电商平台有 n 个仓库&#xff0c;编号从 1 到 n 。当购进某种货物的时候&#xff0c;商家会把货物分散的放在编号相邻的几个仓库中。我们暂时不考虑售出&#xff0c;你是否能知道&#xff0c;当所有货物购买完毕&#xff0c;存放货物种类最多的仓库编号为多少&…

数字身份革命:探索Web3对个人隐私的保护

在数字化时代&#xff0c;个人隐私和数据保护成为越来越重要的话题。随着Web3的兴起&#xff0c;这一领域正在经历一场深刻的变革。Web3不仅仅是技术的演进&#xff0c;更是对个人隐私保护的一次革命性革新。本文将探讨Web3如何通过去中心化技术重新定义数字身份&#xff0c;并…

Moodle集成ONLYOFFICE文档:提高师生协作效率的最佳解决方案

引言 通过一些教育机构和老师朋友的推荐&#xff0c;我最近了解到了一款非常实用的办公软件组合——Moodle与ONLYOFFICE。作为一名教师&#xff0c;日常教学中的文档编辑、课程管理和学生协作是不可避免的任务。虽然市场上有很多办公软件&#xff0c;但Moodle与ONLYOFFICE的结…

稚晖君智元机器人远程机器人系列发布:引领具身智能新高度

在最近的发布会上&#xff0c;前华为“天才少年”稚晖君及其团队亮相了他们的最新作品——智元机器人的第二代远程机器人系列。这次发布会不仅展示了丰富的产品线&#xff0c;还揭示了其未来的发展路线以及开源计划。本文将详细解析本次发布会的亮点和技术背后的创新。 一、发…

企业数字化转型是什么?有什么用?

什么是数字化转型&#xff1f;为什么要数字化转型&#xff1f;对企业有何价值&#xff1f;一文给你讲透&#xff01; 先来给大家简单易懂的方式介绍一下&#xff0c;就很明白什么是数字化&#xff1f;企业为什么要数字化转型了。 “信息化”可理解为&#xff1a;是用电脑或者手…

BAT 实现五子棋人机对战

&#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &#x1f680;感谢大家点赞&#x1f44d;收藏⭐评论✍ 引言…

【python】Python中小巧的异步web框架Sanic快速上手实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Java 3.1 - 计算机网络

目录 OSI 七层协议是什么&#xff1f;每一层的作用是什么&#xff1f; TCP / IP 四层模型是什么&#xff1f;每一层的作用是什么&#xff1f; 应用层&#xff08;Application Layer&#xff09; 传输层&#xff08;Transport Layer&#xff09; 网络层&#xff08;Network …

Linux系统编程(15)send/recv函数

一、send/recv send 和 recv 是在网络编程中常用的两个函数&#xff0c;用于在套接字&#xff08;socket&#xff09;之间发送和接收数据。 1.send 函数 用于将数据发送到连接的套接字。 ssize_t send(int sockfd, const void *buf, size_t len, int flags); sockfd&#…

掌握语义内核(Semantic Kernel):如何使用Memories增强人工智能应用

随着人工智能领域的不断发展&#xff0c;语义内核&#xff08;Semantic Kernel&#xff09;的概念应运而生&#xff0c;为我们处理和理解庞大的数据集提供了新的视角。今天&#xff0c;我们将聚焦于语义内核中的一个核心概念——Memories&#xff0c;它是如何使我们的数据查询更…