蓝桥杯电子类单片机提升二——串口发送与接收

news2024/11/29 4:53:25

目录

单片机资源数据包_2023

一、串口收发数据的介绍

1.波特率(Baud Rate)

2.帧格式

3.SBUF寄存器(Serial Buffer)

4.中断处理

二、如何从stc-isp获取串口收发数据的代码

1.代码的获取

2.代码的修改

1)第一步,修改头文件

2)第二步,删除重复定义

3)第三步,删除I/0口配置

4)第四步,修改波特率并测试

3.代码的使用

三、代码演示


前言
关于蓝桥杯比赛时会提供的资料前几篇都有提到,这里就不在赘述了,只放一个下载链接:

单片机资源数据包_2023

除了基础部分的按键、LED灯,数码管扫描,还有温度传感器,AD/DA转化,EEPROM存储器,RTC之外,还有三个模块考试的时候可能会考,分别是超声波,NE555和串口。近几年的题也是越来越难,这三个模块也逐渐出现在了省赛的舞台上(当然如果进国赛了,这几个模块就都可能考了)。提升篇主要针对这三个模块进行介绍。

由于这三个模块比赛时不会提供底层代码,所以许多都需要咱们自己来完成,所以不同人写的代码,差异性可能会更大。此外这些代码会涉及到单片机运行的底层知识,关于单片机基础部分的内容,提升篇也会尽可能介绍一部分(当然如果你不会也没关系,文章会教你如何用stc生成或者查数据手册,就算不知道原理,小背一背也是能自己实现的)

一、串口收发数据的介绍

串口收发数据简单点说就是单片机给电脑发数据,电脑给单片机发数据,平时下载程序就是电脑在给单片机发数据。我们在收发数据之前,首先要调整好COM以及波特率。COM口我们可以在设备管理器——端口处查看,一般情况下stc—isp都能正确扫描到COM口。

本篇文章关于串口的部分会着重告诉大家如何去找代码,而非自己去写这串代码,因为这串代码虽然考试时不会给,但是isp里面提供的有现成的代码,至少底层代码不用自己写了,可以直接去移植。这里先介绍一些串口有关的基础知识(当然比赛时用不到),当然也不用记,第二章会告诉大家如何获取与修改现成的代码。

1.波特率(Baud Rate)

波特率是表示每秒传输的位数,通常用波特(bps)来表示。在串口通信中,发送方和接收方必须配置相同的波特率才能正确地进行数据传输。STC15F2K单片机的串口模块可以通过设定计数器的值来实现不同的波特率,也就是说在使用串口时,需要一个定时器/计时器作为波特率发生器。

2.帧格式

帧格式指的是如何将数据转换为连续的位流进行传输。通常包括起始位(Start Bit)、数据位(Data Bits)、校验位(Parity Bit)和停止位(Stop Bit)。起始位指示数据的传输开始,停止位指示数据的传输结束,数据位是实际要传输的数据,而校验位用于检验数据传输的正确性。常见的帧格式包括8N1(8个数据位,无校验位,1个停止位)和8E1(8个数据位,偶校验,1个停止位)。

3.SBUF寄存器(Serial Buffer)

SBUF寄存器是STC15F2K单片机中用于串口通信的特殊寄存器。

对于发送数据,在发送之前,将要发送的数据写入SBUF寄存器。当发送完成后,SBUF寄存器会自动清空等待下一次写入。对于接收数据,接收到的数据会存放在SBUF寄存器中,然后可以通过读取SBUF寄存器来获取接收到的数据。

数据传输:对于发送数据,可以通过将要发送的数据写入SBUF寄存器,然后通过串口模块发送出去。发送数据时,需要检查串口发送完成标志位(TI)是否被置位,以避免数据的丢失。对于接收数据,可以通过读取SBUF寄存器来获取接收到的数据。接收数据时,需要检查串口接收完成标志位(RI)是否被置位,以判断是否有新的数据到达。

写成代码的话,unsigned char da;da=SBUF就是读数据,SBUF=da就是写数据了,当然,这样说太理想了,实际上还需要一些其他处理。SBUF其实是两个寄存器,只是名字一样而已,在发送和接受时虽然都是SBUF,但是对应的寄存器其实是不相同的。

4.中断处理

在接收数据时,可以使用串口接收中断来实现异步接收数据的功能,以提高系统的实时性和效率。串口中断跟定时器中断一样,不过定时器中断是每隔一定时间进一次中断,而串口中断是每次接收到数据之后,就会进一次中断。

二、如何从stc-isp获取串口收发数据的代码

1.代码的获取

stc-isp有一个“范例程序”的功能,在菜单中选择stc15系列单片机,就能找到许多范例程序,这里我们只看串口收发数据的,这里以定时器1模式0(16为自动重载)作为波特率发生器,其他定时器作为波特率发生器的代码也都一样。另外,比赛时一定要合理安排单片机资源。

下面是stc-isp复制过来的代码,这个代码是带有main函数的,我们后续还要对其进行修改:

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 定时器1用作串口1的波特率发生器举例------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序        */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz


#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

#define FOSC 11059200L          //系统频率
#define BAUD 115200             //串口波特率

#define NONE_PARITY     0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY     2       //偶校验
#define MARK_PARITY     3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT NONE_PARITY   //定义校验位

sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

sfr AUXR  = 0x8e;               //辅助寄存器

sfr P_SW1   = 0xA2;             //外设功能切换寄存器1

#define S1_S0 0x40              //P_SW1.6
#define S1_S1 0x80              //P_SW1.7

sbit P22 = P2^2;

bit busy;

void SendData(BYTE dat);
void SendString(char *s);

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

    ACC = P_SW1;
    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
    P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)
    
//  ACC = P_SW1;
//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0
//  ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)
//  P_SW1 = ACC;  
//  
//  ACC = P_SW1;
//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1
//  ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)
//  P_SW1 = ACC;  

#if (PARITYBIT == NONE_PARITY)
    SCON = 0x50;                //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    SCON = 0xda;                //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    SCON = 0xd2;                //9位可变波特率,校验位初始为0
#endif

    AUXR = 0x40;                //定时器1为1T模式
    TMOD = 0x00;                //定时器1为模式0(16位自动重载)
    TL1 = (65536 - (FOSC/4/BAUD));   //设置波特率重装值
    TH1 = (65536 - (FOSC/4/BAUD))>>8;
    TR1 = 1;                    //定时器1开始启动
    ES = 1;                     //使能串口中断
    EA = 1;

    SendString("STC15F2K60S2\r\nUart Test !\r\n");
    while(1);
}

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4
{
    if (RI)
    {
        RI = 0;                 //清除RI位
        P0 = SBUF;              //P0显示串口数据
        P22 = RB8;              //P2.2显示校验位
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    if (P)                      //根据P来设置校验位
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 0;                //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 1;                //设置校验位为1
#endif
    }
    else
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 1;                //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 0;                //设置校验位为0
#endif
    }
    busy = 1;
    SBUF = ACC;                 //写数据到UART数据寄存器
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}

2.代码的修改

可以看到这串代码引用的头文件是#include "reg51.h",而我们之前引用的都是stc15.h,其实,我们可以理解为15单片机是51单片机的哥哥,是向下兼容51的,而stc15.h其实是包含有reg51.h的所有内容,并且stc15.h里还有一些51单片机没有,但是15单片机有的东西(不知道上述内容对不对,反正大概是这样的),所以我们需要对代码进行修改,大致分四步走:

1)第一步,修改头文件

删除头文件reg51.h并添加头文件stc15.h

2)第二步,删除重复定义

删除所有sfr以及sbit开头的定义,因为这些定义都是51没有但是15有的,所以引用51的头文件之后,15的东西需要单独定义出来,而引用15的头文件之后,这些都在头文件定义过了,就不用再定义了,具体删除的代码如下:

#include "reg51.h"

sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;


sfr AUXR  = 0x8e;               //辅助寄存器

sbit P22 = P2^2;

3)第三步,删除I/0口配置

I/0口配置在main函数内,while(1)之前,这些代码都是配置引脚为准双向的(或者叫初始化为准双向),对于stc15f2k单片机这些是不必要的,因为默认就是准双向,但是对于某些单片机,引脚必须先初始化之后才可以使用。需要删除的代码如下:

    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

其实,我们也可以在stc-isp内找到这些引脚的配置代码,可以根据自己的需要生成:

4)第四步,修改波特率并测试

代码上已经定义了波特率,我们直接修改其数值即可,改为9600

在stc-isp的串口助手选择正确的串口,并调整波特率为9600,然后就可以打开串口了。默认的代码只有上电之后发送一串数据,所以可以重启一下开发板,就可以看到发送的数据了!

3.代码的使用

经过2代码的修改之后,剩下的代码已经十分的干净了,剩下的代码中在main函数的while(1)之前完成了定时器的初始化。此外代码还写好了两个发送数据的代码,我们可以直接拿来用。对于接收数据,UART中断服务函数内可以自行对数据处理:

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4
{
    if (RI)
    {
        RI = 0;                 //清除RI位
        P0 = SBUF;              //P0显示串口数据
        P22 = RB8;              //P2.2显示校验位
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
}

从P0=SBUF那一行那里开始,就是我们可以修改的地方。比如我们可以用一个自己定义的全局变量来记录SBUF的值,再放到其他地方处理。

但是实际上,在真正的比赛中,我们还需要考虑的内容还有许多,这里只是一种最简单的情况。

此外呢,其实也不难发现,刚才的几个过程也并非必要(因为我一个字都不改时,这串代码就可以正常运行),有的人真的把15单片机当51使用也不是不可以。

三、代码演示

刚才已经把代码介绍与修改好了,这里演示一个修改好之后完整的代码,实现以下功能:

1.上电发送数据"STC15F2K60S2\r\nUart Test !\r\n"

2.LED灯显示接收到的数据:

main.c

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 定时器1用作串口1的波特率发生器举例------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序        */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz


#include <stc15.h>
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

#define FOSC 11059200L          //系统频率
#define BAUD 9600             //串口波特率

#define NONE_PARITY     0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY     2       //偶校验
#define MARK_PARITY     3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT NONE_PARITY   //定义校验位


#define S1_S0 0x40              //P_SW1.6
#define S1_S1 0x80              //P_SW1.7


bit busy;

void SendData(BYTE dat);
void SendString(char *s);

void main()
{
    ACC = P_SW1;
    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
    P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)

#if (PARITYBIT == NONE_PARITY)
    SCON = 0x50;                //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    SCON = 0xda;                //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    SCON = 0xd2;                //9位可变波特率,校验位初始为0
#endif

    AUXR = 0x40;                //定时器1为1T模式
    TMOD = 0x00;                //定时器1为模式0(16位自动重载)
    TL1 = (65536 - (FOSC/4/BAUD));   //设置波特率重装值
    TH1 = (65536 - (FOSC/4/BAUD))>>8;
    TR1 = 1;                    //定时器1开始启动
    ES = 1;                     //使能串口中断
    EA = 1;
	
//不能连续发送!(直接放在while(1)里)可以在发送之间加一个100ms延时,否则容易接收不到,发送不出去
    SendString("STC15F2K60S2\r\nUart Test !\r\n");
    while(1);
}

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4
{
    if (RI)
    {
        RI = 0;                 //清除RI位
        P0 = SBUF;              //P0显示串口数据
				P2|=0x80;P2&=0x9F;P2&=0x1F;//打开LED灯
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    if (P)                      //根据P来设置校验位
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 0;                //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 1;                //设置校验位为1
#endif
    }
    else
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 1;                //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 0;                //设置校验位为0
#endif
    }
    busy = 1;
    SBUF = ACC;                 //写数据到UART数据寄存器
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}

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

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

相关文章

打字侠网站,提供免费的双拼打字练习

在当今信息时代&#xff0c;电脑已成为人们生活、学习和工作不可或缺的一部分。随着电脑的普及和广泛应用&#xff0c;打字成了一项必备的技能&#xff0c;尤其是对于从事编程和写作等工作的人来说甚至更为重要。而要想提高打字速度和准确度&#xff0c;良好的打字练习是必不可…

Flink理论—容错之状态

Flink理论—容错之状态 在 Flink 的框架中&#xff0c;进行有状态的计算是 Flink 最重要的特性之一。所谓的状态&#xff0c;其实指的是 Flink 程序的中间计算结果。Flink 支持了不同类型的状态&#xff0c;并且针对状态的持久化还提供了专门的机制和状态管理器。 Flink 使用…

Linux第55步_根文件系统第2步_测试使用busybox生成的根文件系统

测试使用busybox生成的根文件系统。测试内容较多&#xff0c;很杂。 1、修改“nfs-kernel-server” 1)、打开终端 输入“sudo vi /etc/default/nfs-kernel-server回车”&#xff0c;打开“nfs-kernel-server”文件。 输入密码“123456回车” 见下图&#xff1a; 2)、在最后…

模拟电子技术——基本放大电路

文章目录 前言一、三极管输入输出特性三极管放大作用三极管电流放大关系三极管的特性曲线 二、基本放大电路-电路结构与工作原理基本放大电路的构成基本放大电路放大原理三种基本放大电路比较 三、基本放大电路静态工作点什么是静态工作点&#xff1f;静态工作点的作用估算法分…

OpenCV Mat实例详解 一

OpenCV中的Mat是一个类&#xff0c;它用存储图像信息。由两部分数据组成&#xff1a;矩阵头和像素值矩阵。矩阵头包含矩阵尺寸、存储方法、存储地址等信息&#xff0c;而像素值矩阵则存储实际的像素值数据。 Mat类在OpenCV中有十分重要的作用&#xff0c;图像信息的载入、保存、…

2024 CKS 题库 | 6、创建 Secret

不等更新题库 CKS 题库 6、创建 Secret Task 在 namespace istio-system 中获取名为 db1-test 的现有 secret 的内容 将 username 字段存储在名为 /cks/sec/user.txt 的文件中&#xff0c;并将password 字段存储在名为 /cks/sec/pass.txt 的文件中。 注意&#xff1a;你必须创…

ubuntu22.04@laptop OpenCV Get Started: 009_image_thresholding

ubuntu22.04laptop OpenCV Get Started: 009_image_thresholding 1. 源由2. image_thresholding应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 重点分析3.1 Binary Thresholding ( THRESH_BINARY )3.2 Inverse-Binary Thresholding ( THRESH_BINARY_INV )3.3 Truncate Threshold…

【AIGC】Stable Diffusion的采样器入门

在 Stable Diffusion 中&#xff0c;采样器&#xff08;Sampler&#xff09;是指用于生成图像的一种技术或方法&#xff0c;它决定了模型如何从潜在空间中抽样并生成图像。采样器在生成图像的过程中起着重要作用&#xff0c;影响着生成图像的多样性、质量和创造性。以下是对 St…

WebStorm | 如何修改webstorm中新建html文件默认生成模板中title的初始值

在近期的JS的学习中&#xff0c;使用webstorm&#xff0c;总是要先新建一个html文件&#xff0c;然后再到里面书写<script>标签&#xff0c;真是麻烦&#xff0c;而且标题也是默认的title&#xff0c;想改成文件名还总是需要手动去改 经过小小的研究&#xff0c;找到了修…

问题:如果要编辑建好的建筑和空间,需要在分级按钮( )和细分操作按钮楼层下,才能选中建筑物和空间; #微信#媒体#其他

问题&#xff1a;如果要编辑建好的建筑和空间&#xff0c;需要在分级按钮&#xff08; &#xff09;和细分操作按钮楼层下&#xff0c;才能选中建筑物和空间&#xff1b; A、楼层 B、规划图 C、全景 D、建筑物 参考答案如图所示

【单总线与DS18B20总结和代码实现】

单总线介绍与总结 单总线介绍单总线时序图DS18B20的操作流程代码 读温度代码思路代码实现 单总线介绍 单总线应用案例&#xff1a;Ds18B20、温湿度传感器用到的就是这个&#xff0c;这里Ds18B20从当的角色是从机部分&#xff0c;而开发板充当的部分人是主机部分。 Ds18B20内部结…

红队打靶练习:HACK ME PLEASE: 1

信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:69:c7:bf, IPv4: 192.168.61.128 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.61.2 00:50:56:f0:df:20 …

ubuntu22.04@laptop OpenCV Get Started: 010_blob_detection

ubuntu22.04laptop OpenCV Get Started: 010_blob_detection 1. 源由2. blob应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 重点分析3.1 Threshold3.2 Area3.3 Circularity3.4 Convexity3.5 Inertia Ratio 4. 总结5. 参考资料6. 补充 1. 源由 Blob是图像中的一组连接像素&#…

Git 初学

目录 一、需求的产生 二、版本控制系统理解 1. 认识版本控制系统 2. 版本控制系统分类 &#xff08;1&#xff09;集中式版本控制系统 缺点&#xff1a; &#xff08;2&#xff09;分布式版本控制系统 三、初识 git 四、git 的使用 例&#xff1a;将 “ OLED文件夹 ”…

STM32物联网(ESP-01S模块及STM32和ESP-01S通信方式介绍)

文章目录 前言一、ESP-01S模块介绍二、STM32和ESP-01S通信方式介绍三、什么是AT指令四、创建基础工程总结 前言 本篇文章我们开始正式进入STM32物联网的专栏&#xff0c;在这个专栏中将会带大家学习使用STM32进行联网&#xff0c;联网模块的话主要就是使用到了ESP-01S WIFI模块…

嵌入式STM32 单片机 GPIO 的工作原理详解

STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称&#xff0c;是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接&#xff0c;可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子&#xff0c;该芯片共有 144 脚芯片&#xff0c…

[word] word技巧分享_word自动编号的标题 #知识分享#知识分享#其他

word技巧分享_word自动编号的标题 日常办公&#xff0c;我们时时都在使用 word 软件。 word 软件内容的组织是通过一节一节的标题进行的。 我们常常需要处理的是下图一样的章节目录

计算机设计大赛 深度学习OCR中文识别 - opencv python

文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习OCR中文识别系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;…

挑战杯 python图像检索系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python图像检索系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c…

【C深度解剖】取模与取余

简介&#xff1a;本系列博客为C深度解剖系列内容&#xff0c;以某个点为中心进行相关详细拓展 适宜人群&#xff1a;已大体了解C语法同学 作者留言&#xff1a;本博客相关内容如需转载请注明出处&#xff0c;本人学疏才浅&#xff0c;难免存在些许错误&#xff0c;望留言指正 作…