8.串行通信

news2024/10/6 8:30:20

1.通信接口相关知识:

(1)处理器与外界设备通信的两种方式:

  1)并行通信:

  • 传输原理:数据各个位同时传输;

  • 优点:速度快;

  • 缺点:占用引脚资源多;

   2)串行通信:

  • 传输原理:数据按位顺序传输;
  • 优点:占用引脚资源少;
  • 缺点:速度相对较慢;

(2)按照数据传送方向分为:

  • 单工:数据传输只支持数据在一个方向上传输;
  • 半双工:允许数据在两个方向上传输,但在某一时刻,只允许数据在一个方向上传输,实际是一种切换方向的单工通信;
  • 全双工:允许数据同时在两个方向上传输,所以全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力;

 2.串行通信的通信方式:

  • 同步通信:带时钟同步信号传输;如SPI、IIC;
  • 异步通信:不带时钟同步信号;如UART(通用异步收发器)、单总线;

3.常见的串行通信接口:

4.STM32F103串行通信:

(1)STM32的串行通信接口:

  • UART:通用异步收发器;
  • USART:通用同步异步收发器;

(2)UART异步通信方式引脚连接方法:

  • RED:数据输入引脚。数据接收;
  • TXD:数据发送引脚。数据发送;

 

 (3)UART异步通信方式特点:

  • 全双工异步通信;
  • 分数波特率发生器系统,提供精确的波特率;发送和接收共用的可编程波特率,最高可达4.5Mbit/s;
  • 可编程额数据字节长度(8位或9位);
  • 可配置的停止位(支持1位或者2位停止位);
  • 可配置的使用DMA多缓冲器通信;
  • 单独的发送器和接收器使能位;
  • 检测标志:1.接收缓冲器、2.发送缓冲器、3.传输结束标志;
  • 多个带标志的中断源,触发中断;
  • 其他:校验控制,四个错误检测标志;

(4)串口通信过程:

 (5)STM32串口异步通信需要定义的参数:

  • 起始位;
  • 数据位(8位或9位);
  • 奇偶校验位(第九位);
  • 停止位(1,15,2位);
  • 波特率设置;

5.库函数实现串口通信: 

(1)串口配置的步骤:

  1. 串口时钟使能,GPIO时钟使能;
  2. 串口复位(不是必须);
  3. GPIO端口模式设置;
  4. 开启中断并且初始化NVIC(如果需要开启中断才需要该不步骤);
  5. 使能串口;
  6. 编写中断处理函数;
  7. 串口数据收发;
  8. 串口传输状态获取;

(2)串口相关原理图:

 (3)实现结果:

STM32通过USART1实现与PC对话,STM32的USART1收到PC发来的数据后原封不动的返回给PC显示。同时使用LED0指示灯不断闪烁提示系统正常运行。

1)主函数:

#include "delay.h"
#include "led.h"
#include "usart1.h"

int main(){
    
    u8 i=0; 
    u16 length=0;
    u16 temp=0;
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //设置中断分组
    delay_init();   //延时初始化
    LED_Init();   //LED初始化
    usart1_Init(9600);  //串口初始化
    while(1){
       if(USART1_RX_STA&0x8000)     //判断是否接收完成->这里表示接收完成
       {
          length=USART1_RX_STA&0x3fff; //接收到的数据长度
          for(temp=0;temp<length;temp++)
          {
             USART_SendData(USART1,USART1_RX_BUF[temp]);    //将接收到的数据,发送出去
             while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);     //判断是否已经发送完成 
          }
          USART1_RX_STA=0; //发送完成之后,对USART1_RX_STA进行清零

       }
       i++;
       if(i%20==0)
       {
          LED0=!LED0;
       }
       delay_ms(10);
       }
}

2)头文件:

#ifndef __USART1_H
#define __USART1_H

#define USART1_REC_LEN 200

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;

extern u8 USART1_RX_BUF[USART1_REC_LEN];   //接收缓存的数据容器
extern u16 USART1_RX_STA;  //标志位

void usart1_Init(u32 bund);    //串口1初始化


#endif

3)串口1初始化函数:

#include "usart1.h"
#include "stm32f10x.h"


/*
   功能:串口1的初始化
   变量:bund:波特率
   返回值:无

*/
void usart1_Init(u32 bund)
{
   GPIO_InitTypeDef GPIO_InitStruct;
   USART_InitTypeDef USART_InitStruct;
   NVIC_InitTypeDef NVIC_InitStruct;
   
   //1.GPIO时钟使能和端口复用时钟使能
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
   
   //2.配置GPIO->TX-PA9
   GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;   //复用推挽输出
   GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;   //PA9
   GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    //输出速度
   GPIO_Init(GPIOA,&GPIO_InitStruct);
   
   //配置GPIO->RX-PA10
   GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;   //浮空输入
   GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;   //PA9
   GPIO_Init(GPIOA,&GPIO_InitStruct);
   
   //3.初始化串口参数
   USART_InitStruct.USART_BaudRate=bund;  //设置波特率
   USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;    //不使用硬件流控制
   USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;    //使能接收和发送
   USART_InitStruct.USART_Parity=USART_Parity_No;  //不使用奇偶校验位
   USART_InitStruct.USART_StopBits=USART_StopBits_1;  //1位停止位
   USART_InitStruct.USART_WordLength=USART_WordLength_8b;   //字长8位,无奇偶校验位
   USART_Init(USART1,&USART_InitStruct);
   
   //4.设置串口中断优先级,使能串口中断通道
   NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;    //设置串口1通道
   NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;   //使能中断
   NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;  //抢占优先级
   NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;   //子优先级
   NVIC_Init(&NVIC_InitStruct);
   
   //5.设置串口中断类型
   USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);    //串口1,接收中断,使能
   
   //6.使能串口
   USART_Cmd(USART1,ENABLE);

}


/*
   功能:串口1中断服务函数
   变量:无
   返回值:无
   设置通信方式-注意:
         1.0x0A(换行),0x0D(回车);
         2.识别累计接收的数据长度以及是否接收到0x0D和0x0A;当连续接收到0x0D和0x0A才算接收完成;
         3.USART1_RX_STA的15位为1,则为接收完成的标志;USART1_RX_STA的14位为1,则接收到0x0D;
         4.0~13位,表示接收的有效数据字节;
*/

u8 USART1_RX_BUF[USART1_REC_LEN];   //接收缓存的数据容器
u16 USART1_RX_STA=0;    //标志位

void USART1_IRQHandler(void)
{
   u8 data=0;
   if(USART_GetITStatus(USART1,USART_IT_RXNE))    //获取串口接收中断标志
   {
      data=USART_ReceiveData(USART1);  //将串口1接收到的数据,存储到data中;
      if((USART1_RX_STA&0x8000)==0)    //判断是否接收完成->这里是接收未完成
      {  
         if((USART1_RX_STA&0x4000))    //判断是否接收到0x0D->这里是接收到了0x0D
         {
            if(data==0x0A)    //判断接收到0X0D后,下一次接收的是否是0X0A->这里是已经接收到0x0A
            {
               USART1_RX_STA|=0x8000;  //将USART1_RX_STA最高位设置为1,表示接收完成
            }
            else     //未接收到0x0A
            {
               USART1_RX_STA=0;  //接收错误,置0
            }
         }
         else  //未接收到0x0D
         {
            if(data==0x0D)    //下一次接收到0x0D时
            {
               USART1_RX_STA|=0x4000;  //将USART1_RX_STA的第14位设置为1
            }
            else  //下一次并未接收到0X0D时
            {
               USART1_RX_BUF[USART1_RX_STA&0x3fff]=data;   //将data内的数据,放入USART1_RX_BUF中
               USART1_RX_STA++;
               if(USART1_RX_STA>(USART1_REC_LEN-1))   //判断累计的次数是否大于数组极限容量值->这里表示超过
               {
                  USART1_RX_STA=0;  //接收错误,置0
               }
            }
         }
      }
   }
}

6.串口通信printf

(1)使用结果:

在上诉实验中进行改进,对printf进行重定向,再通过printf函数将信息打印到串口调试助手上显示,同时LED0指示灯不断闪烁,表示系统正常运行。

(2)库函数实现:

1)主函数:在主函数中添加printf打印;

 

2)头文件:在头文件中添加#include "stdio.h";

3)串口初始化函数:对printf进行重定向;

注意: 

 在串口通信中需要使用printf打印时,需要勾选Use Micro LIB否则将无法打印出信息;

 

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

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

相关文章

vue+leaflet笔记之地图网格

vueleaflet笔记之地图网格 本文介绍了Web端使用Leaflet开发库显示地图经纬网和标准图幅网格的方法 (底图来源:天地图)&#xff0c; 地图格网是由间隔均匀的横向线和纵向线组成的网络&#xff0c;用于在地图上识别各个位置。 经纬网通过在地图上描绘纬度和经度格网&#xff0c;…

40.Docker

目录 一、Docker。 &#xff08;1&#xff09;认识Docker。 &#xff08;1.1&#xff09;什么是Docker。 &#xff08;1.2&#xff09;Docker和虚拟机的区别。 &#xff08;2&#xff09;镜像、容器、DockerHub、Docker架构。 &#xff08;3&#xff09;安装Docker&#…

VS+QT+VTK三维曲面网格点选切割

程序示例精选 VSQTVTK三维曲面网格点选切割 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<VSQTVTK三维曲面网格点选切割>>编写代码&#xff0c;代码整洁&#xff0c;规则&…

DAMA学习笔记1:概念模型-逻辑模型篇

A实体的某个字段指向 B实体的主键, 则称A实体的那个字段为该实体的外键, 一个表里可以有多个外键&#xff0c;也可以没有外键&#xff1b; 被指向的实体称为主实体(主表)&#xff0c;也叫父实体(父表)&#xff0c;负责指向的实体称为从实体(从表)&#xff0c;也叫子实体(子表)…

记录好项目D18

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是个网上商城 一、系统介绍 前台商城系统&#xff1a;包含首页登录、商…

动态规划——下降路径最小和

题目链接 leetcode在线oj题——下降路径最小和 题目描述 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一行选择的元素和当前…

mmpose冻结参数训练,如何添加find_unused_parameters参数

mmpose冻结参数训练&#xff0c;如何添加find_unused_parameters参数 在backbone下方添加 frozen_stages7即可冻结前7层的参数。要注意对于多卡训练来说还需要添加 find_unused_parameters True。看图片中代码的位置。

回忆雅礼朱哥二三事

少年时代的记忆是最模糊的&#xff0c;却也是最深刻的。一些瞬间在大脑里几十年&#xff0c;那一定是你曾经心动和在乎过的感受。年少求学期间&#xff0c;因对数学的痴迷&#xff0c;和数学有关的一切我都记忆犹新&#xff1a;记得一个人趴在地上解题一下午的投入&#xff0c;…

分析各种富文本框的自动填写方法

怎样自动填写表单中的富文本框&#xff1f; 什么是富文本框&#xff1f;富文本框就是在网页上可以输入带格式的文本输入框。在富文本框中&#xff0c;可以设置使用不同的字体、颜色&#xff0c;可以控制段落、边距&#xff0c;还可以插入图片、表情等。是实现在线编辑不可或缺…

c++ word简单的写文本与画表格只支持docx

简单使用的代码如下所示&#xff1a; #include "stdafx.h" #include <windows.h> #include "minidocx.hpp" using namespace docx; using namespace std; std::string GB2312ToUTF8(const std::string& gb2312) { int len MultiByteToWid…

【ESP32C3合宙ESP32C3】:ESP32C3和合宙ESP32C3的环境搭建与离线包安装

项目场景&#xff1a; 最近买了一块合宙ESP32C3的开发板&#xff0c;于是想要开发一下&#xff0c;当然开发最开始少不掉开发环境的搭建&#xff0c;在这个搭建的过程中&#xff0c;遇到了一些问题&#xff0c;解决了&#xff0c;也希望能帮助到大家。 ESP32C3 和 合宙ES…

Spring Boot 中的 Elasticsearch 的数据操作配置

Spring Boot 中的 Elasticsearch 的数据操作配置 Elasticsearch是一个基于Lucene的搜索引擎&#xff0c;可以快速地存储、搜索和分析大量的数据。Spring Boot是一个开发框架&#xff0c;提供了快速构建基于Spring的应用程序的工具和技术。在本文中&#xff0c;我们将讨论如何在…

GBASE南大通用时代亿信共筑商业秘密防护联合解决方案

当前&#xff0c;数字经济因其覆盖面广且渗透力强&#xff0c;与各行业深度融合&#xff0c;正在逐渐引领新经济发展。另一方面&#xff0c;数据安全已上升为国家战略&#xff0c;中央相继出台政策文件&#xff0c;加强数据安全、商业秘密、个人隐私保护&#xff0c;提高网络安…

聚观早报 | 美团收购光年之外;世卫:可乐中甜味剂或致癌

今日要闻&#xff1a;美团以20.65亿人民币收购光年之外&#xff1b;世卫&#xff1a;可乐中甜味剂或致癌&#xff1b;AI公司融13亿美元&#xff0c;仅次于OpenAI&#xff1b;微信支付就校园支付费率过高致歉&#xff1b;B站回应成立交易生态中心 美团以20.65亿人民币收购光年之…

C# Excel 表列序号

171 Excel 表列序号 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1: 输入: columnTitle “A” 输出: 1 示例 2: …

11-Vue的diff算法

参考回答&#xff1a;​​​​​​​ 当组件创建和更新时&#xff0c;vue均会执行内部的update函数&#xff0c;该函数使用render函数生成的虚拟dom树&#xff0c;将新旧两树进行对比&#xff0c;找到差异点&#xff0c;最终更新到真实dom对比差异的过程叫diff&#xff0c;vue在…

《移动互联网技术》第五章 界面开发: 掌握Activity的基本概念,Activity的堆栈管理和生命周期

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

chatgpt赋能python:如何升级Python包

如何升级Python包 如果你是一名有着10年Python编程经验的工程师&#xff0c;那么你一定知道如何安装和使用Python包。但是&#xff0c;有时候你需要升级一些已经安装的包&#xff0c;以获得更好的性能和新功能。在本文中&#xff0c;我们将讨论如何升级Python包。 什么是Pyth…

GDI MFC抠图贴图

文章目录 抠图贴图添加消息命中 抠图 请添加图片描述 BOOL CPokemonDlg::OnInitDialog() {CDialogEx::OnInitDialog();// 设置此对话框的图标。 当应用程序主窗口不是对话框时&#xff0c;框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon,…

Spring Boot 中的 RabbitMQ 是什么,如何使用

Spring Boot 中的 RabbitMQ 是什么&#xff0c;如何使用 简介 RabbitMQ 是一个开源的消息队列系统&#xff0c;它通过 AMQP&#xff08;高级消息队列协议&#xff09;来实现消息的传递。Spring Boot 是目前非常流行的 Java 开发框架&#xff0c;它提供了很多便利性的功能&…