单片机05__串口USART通信__按键控制向上位机传输字符串
串口USART通信
通用UART介绍
1.通信的概念
计算机与外界进行信息交换的过程称之为通信。
在通信的过程中,通信双方都需要遵守的规则称之为通信协议。
硬件协议:将数据以什么样的方式传输过去
软件协议:将数据以什么样的顺序传输过去
2.常用的通信方式
①并行通信---LCD屏
所传输的数据的各个二进制位数据都是同时发送或接收。
优点:通信速度快。
缺点:由于有多少位的二进制数据,就需要多少根数据线,所以说通信成本比较高。
一般适合在近距离场所使用。
②串行通信----串口
所传输的数据的各个二进制位数据按照顺序一位一位的发送或者接收。
优点:串行通信一般只需要1-2根数据线,所以说通信成本比较低。
缺点:通信速度比较慢。
一般适合在远距离场所使用。
3.串行通信种类
①异步通信
异步通信概念:
异步通信:指收发双方使用的时钟源(提供时钟脉冲)不同,不受到同一根时钟线的控制,在通信时不要求基本频率相等。
异步通信数据格式:
在异步通信的过程:数据或字符都是逐帧传输。
异步传输的数据帧为:起始位+数据位+校验位+结束位。
数据传输的方式为:先发低位(LSB),再发高位(MSB),从起始位到结束位构成了完整的一帧。
起始位:使用1个位的低电平“0”来表示数据通信的开始。
数据位:串行通信所需要传输的数据,数据位长度为5-8位(常用的是8位--1byte)
奇偶校验位:校验位在串行通信中是可选项,用于检验传输的数据是否正确,检验方法为:“奇校验”和“偶校验”。
停止位(数据缓存区):使用高电平“1”来表示数据通信的结束,停止位长度为:0.5位、1位、1.5位、2位、2.5位停止位数越大,传输的速度越慢。
奇校验:“数据位”加上“校验位”后,使得传输的数据中“1”的个数为奇数个。
偶校验:“数据位”加上“校验位”后,使得传输的数据中“1”的个数为偶数个。
例如:
数据位 | 校验位 |
1010 0011 | 奇校验:1 偶校验:0 |
0100 0000 | 奇校验:0 偶校验:1 |
②同步通信
同步通信概念:
通信双方受到同一根时钟源(时钟线)的控制,其时钟频率相等。
同步通信数据帧格式:
同步通信发送的数据开始是以“同步字符”来表示的(一般约定为1-2个字节),当接收方接收到同步字符后就表示接受下来收到的数据为需要发送的数据流(数据的位数不确定)。
4.串行通信的数据传输速度
串行通信数据的传输速度称为波特率(也叫比特率),是指一秒钟内所传输的数据(二进制)位数,英文简称BPS
例:假设数据传输的速率为120个字符每秒,每个字符有1个起始位,8个数据位以及1个停止位构成,其串行波特率是多少???
每个字符的位数:1+8+1= 10
每秒传输的位数:120*10/s = 1200 BPS
5.串行通信工作方式
①单工制式:只有一根数据线,数据在甲机和乙机之间只允许单方向传输。
②半双工:只有一根数据线,数据在甲机和乙机之间允许双方向的传输,但是在同一时刻只允许数据的发送或者接收。
③全双工:有两根数据线,数据在甲机和乙机之间允许双方向的传输,并且可以同时在同一时刻进行数据的发送或者接收。
6.串口数据发送的格式
串口发送数字、字母、英文符号按照ASCII码表的数值发送。
串口发送中文汉字,中文符号是按照“GB2312”简体中文编码表的数值发送。
USART模块介绍(STM3240x)
1.USART模块概述
STM32F40X芯片的USART模块是通用同步/异步收发器能够灵活地与外部设备进行全双工数据交换,此芯片一共有6个独立的USART模块(编号为USART1-6)。
可以实现同步/异步通信的是USART1、2、3、6,只能实现异步通信的是UART4、5。
同步串口可以是异步串口,但是异步串口不能是同步串口。
全双工:有两根数据线:TX RX 串口最远传输距离:15米左右
串口连接:交叉相连
USART: TX RX SCLK--时钟线-------同步串口
UART: TX RX ------异步串口
只有串口连接方式是交叉相连 :TX---RX RX----TX
2.USART模块框图
①串口发送数据的过程
1)在MCU内定义需要发送的数据(内核发送数据)
2)MCU将需要发送的数据通过数据总线写入到“发送数据寄存器(数据寄存器)”
/****************以下部分由硬件自动完成(无需配置)************************/
3)当“发送数据寄存器”被写入后,将数据并行发送到“发送移位寄存器”,并且由硬件自动产生一个“发送数据寄存器”为空的标志。
4)“发送移位寄存器”根据已经设置好的波特率时钟脉冲,把数据按照顺序一位一位的发送到数据发送管脚(TX)。
当“发送移位寄存器”为空并且“发送数据寄存器”也为空的时候,由硬件自动产生一个“传输完成”的标志。
5)数据在串口发送管脚发送数据,数据通过USB转串口芯片(电平转换芯片)后,由USB数据线传输到电脑上位机上。
②串口接收数据的过程
1)电脑上位机通过USB线发送数据,数据通过USB转串口芯片发送到串口接收数据管脚(RX)
2)接收管脚根据已经设置好的波特率时钟脉冲,一位一位的把数据传输到“接收移位寄存器”中。(被动接收:没有“满”标志,满时自动传输)
3)当“接收移位寄存器”接收完数据之后,并行把数据传输到“接收数据寄存器”中,并且会由硬件自动产生一个“接收数据寄存器”为满的标志。
/***************以上部分由硬件自动完成(无需配置)************************/
4)CPU通过数据总线读出“接收数据寄存器”的内容。
3. USART模块特征
- 可以支持波特率的时钟配为16倍过采样或或者8倍过采样来对不同时钟速度之间的误差容忍。
- 支持小数位波特率发生器。
- 可以根据实际情况配置数据位长度为8位(如果不使用奇偶校验位,则数据位为8位,如果使用奇偶校验位,则数据位为7位),或者数据位长度为9位(包含了校验位)。
- 停止位支持可以配置为1位或2位。
- 支持DMA数据高速传输。
- 发送器和接收器具有单独使能位,USTAR单独开启时钟。
- USART模块有3个状态标志:接收缓冲区已满、发送缓冲区为空、传输完成。
- USART模块不仅可以发送奇偶校验位,也可以对接收到的数据进行奇偶校验。
- USART模块具有4个错误检测标志:
溢出错误(原来的数据没有被读出,又来了新的数据,则产生溢出错误。溢出错误状态时,“接收数据寄存器”保留原来旧的数值,丢弃新的数值)、
噪声错误(干扰错误)、
帧错误(数据帧格式错误)、
奇偶校验错误
10.USART模块的中断源:
CTS变化(硬件流发送变化)、
LIN停止符号检测(LIN数据传输完成)、
发送数据寄存器为空、
发送完成、
接收数据寄存器为满,接收到线路空闲(USART线路在忙碌状态转换为空闲的时刻)、
溢出错误、
帧错误、
噪声错误、
奇偶校验错误。
只要发生上面的状态中的其中一条(前提是开启了中断),都会产生一个USART中断。
11.多处理器通信,如果地址不匹配,则进入静默模式。
12.从静默模式唤醒(通过线路空闲检测或地址标记检测)。
USART模块配置(STM3240x)
1.STM3240x外设功能管脚复用(GPIO配置)
STM32F40x外设功能管脚复用概念
STM32F40X芯片所有的片内外设(芯片以内内核以外)模块的功能管脚都是使用GPIO端口的复用功能,并且每个IO端口都会对应多个复用功能管脚。
STM32F40x外设功能管脚复用
STM32F40x外设管脚复用相应寄存器
①GPIO复用功能低位寄存器 (GPIOx_AFR[0]) (x = A..I)
寄存器作用:设置STM32F40X芯片GPIOx组端口0-7对应的外设模块复用功能,每4位控制一个IO口。把对应的“复用功能编码”写入相对应的位,则设置对应端口为复用功能。
②GPIO 复用功能高位寄存器 (GPIOx_AFR[1]) (x = A..I)
寄存器作用:设置STM32F40X芯片GPIOx组端口8-15对应的外设模块复用功能,每4位控制一个IO口。把对应的“复用功能编码”写入相对应的位,则设置对应端口为复用功能。
STM32F40x外设管脚复用步骤
例如:
1)需要使用的复用端口是否满足复用的前提条件。
2)配置端口模式寄存器,配置为复用功能。
3)根据具体的端口管脚选择对应的复用功能寄存器 0-7使用低位寄存器 8-15使用高位寄存器。
4)选择对应的“复用功能编码”配置复用功能寄存器。
RCC->AHB1ENR |= 1<<0; //开启A口时钟 //PA9 GPIOA->MODER &= ~(3<<9*2); GPIOA->MODER |= 2<<9*2; //配置复用功能 GPIOA->AFR[1] |= 7<<(9-8)*4; //配置为串口功能 //PA10 GPIOA->MODER &= ~(3<<10*2); GPIOA->MODER |= 2<<10*2; //配置复用功能 GPIOA->AFR[1] |= 7<<(10-8)*4; //配置为串口功能 |
2.STM3240x芯片USART模块相关寄存器
状态寄存器 (USART_SR)
寄存器作用:检测串口模块的具体功能的当前状态(数据是否接收/发送完成,寄存器是否为空),如果发生了对应的状态,硬件会自动置1,并且可以用来申请中断。
数据寄存器 (USART_DR)
寄存器作用:存放串口需要发送和接收的数据,数据寄存器包含了“接收数据寄存器”和“发送数据寄存器”,这两个寄存器共用同一个寄存器地址以及空间。
注:当CPU往数据寄存器写数据的时候,数据寄存器就是“发送数据寄存器”,当CPU对数据寄存器进行读操作的时候,数据寄存器就是“接收数据寄存器”。
波特率寄存器 (USART_BRR)
波特率:USART模块的指定波特率时钟大小(115200/9600等)-----已知
fck:USART模块挂载的时钟总线频率(HZ)--------已知 1MHZ = 10^6HZ
OVER8:USART模块采样滤波的选择,采用16倍过采样,则为数字“0”,采用8倍过采样,则为数字“1”
USARTDIV:存放USART模块波特率寄存器的计算值。
注:USARTDIV计算值不能直接放入波特率寄存器中,而是分别计算出整数部分和小数部分,分别写入到寄存器里面。
假设设置的波特率为115200,16倍过采样,使用的事USART1,挂载在APB2上时钟频率为72MHZ Float USARTDIV ; int ZHENG,XIAO; USARTDIV = 72000000.0/(8*(2-0)*115200); //39.0625 ZHENG = (int)USARTDIV;//39 0010 0111 XIAO = (USARTDIV - ZHENG)*16; //0001 USAT1->BRR = ZHENG<<4 | XIAO; // 0010 0111 0001 |
控制寄存器 1 (USART_CR1)
寄存器作用:设置串口模块对应的工作模式以及相关参数
控制寄存器 2 (USART_CR2)
寄存器作用:设置串口模块对应的工作模式以及相关参数
控制寄存器 3 (USART_CR3)
寄存器作用:设置串口模块对应的工作模式以及相关参数
USART模块编程思路
①找到USART模块对应的GPIO端口 -----CH340----PA9 PA10
1)先开对应的IO口时钟
2)设置端口功能:复用功能
3)通过复用功能寄存器选择具体的复用功能
GPIO时钟
串口USART时钟
GPIO寄存器配置
②USART模块初始化
1)使能USART对应的时钟
2)设置相关的工作参数---控制寄存器: 发送接收开启、数据位数、是否需要校验、停止位等。
3)如果需要中断,则开启对应中断位
USART1配置
③设置USART模块波特率
1)先设置采样参数:16倍过采样还是8倍过采样
2)根据波特率计算公式计算出波特率的计算数值
3)将波特率计算值分成小数和整数部分写入到波特率寄存器中
④使能串口
⑤USART模块发送数据
1)先检测“发送数据寄存器是否为空”或“传输完成”
2)把需要发送的数据写入到数据寄存器
⑥USART模块接收数据
1)轮询判断“接收数据寄存器为满”
2)读取数据寄存器中的内容
“usart.c”
/*************************
函数功能:串口USART1初始化
硬件接口:
PA9 --- USART1_TX --- 复用功能
PA10--- USART1_RX --- 复用功能
GPIOA --- AHB1 168MHZ
USART1 --- APB2 84MHZ
**************************/void USART1_Init(uint32_t brr)
{float USARTDIV; //波特率寄存器存放值uint32_t fck = 84000000.0; //USART1挂载在APB2的频率84MHZuint16_t integer,decimal; //波特率寄存器存放值的整数/小数RCC->AHB1ENR |= 1<<0; //开启A口时钟/*①*///PA9GPIOA->MODER &= ~(3<<9*2); GPIOA->MODER |= 2<<9*2; //配置复用功能GPIOA->AFR[1] |= 7<<(9-8)*4; //配置为串口功能//PA10GPIOA->MODER &= ~(3<<10*2);GPIOA->MODER |= 2<<10*2; //配置复用功能GPIOA->AFR[1] |= 7<<(10-8)*4; //配置为串口功能
/*②*/ //USARTRCC->APB2ENR |= 1<<4; //开启USART1时钟USART1->CR1 &= ~(1<<15); //串口配置16倍过采样USART1->CR1 &= ~(1<<12); //配置8位数据USART1->CR2 &= ~(3<<12); //1位停止位
/*③*///波特率USARTDIV = fck/(8*(2 - 0)*brr);integer = USARTDIV; //整数部分decimal = (USARTDIV - integer)*16; //小数部分USART1->BRR = integer<<4 | decimal; //数据放入波特率寄存器 /*④*/USART1->CR1 |= 1<<3; //使能发送器USART1->CR1 |= 1<<2; //使能接收器USART1->CR1 |= 1<<13; //使能串口}
“main.c”
USART1_Init(115200);while(1){while(!(USART1->SR & 1<<6)){//轮询检测接收数据寄存器标志位是否已满}USART1->DR = cha; //读出接收数据寄存器内容while(!(USART1->SR & 1<<5)) {//轮询检测发送数据寄存器标志位}cha = USART1->DR; //发送}
改写printf函数
目标:使用printf函数,通过串口USART1向上位机发送信息。
例如:printf("hello world\r\n");
int a=10;
printf("a = %d\r\n",a);
/********************************
函数功能:修改printf底层代码
注意:不可更改!
魔术棒Target---Use MicroLIB
*********************************/
int fputc(int data,FILE* file)
{while(!(USART1->SR & 1<<6)){}USART1->DR = data; //清标志位&&发送数据return data;
}
按键控制向上位机传输字符串示例
“usart.c”
#include "usart.h"
#include "stdio.h"
/*************************
函数功能:串口USART1初始化
硬件接口:
PA9 --- USART1_TX --- 复用功能
PA10--- USART1_RX --- 复用功能
GPIOA --- AHB1 168MHZ
USART1 --- APB2 84MHZ
**************************/void USART1_Init(uint32_t brr)
{float USARTDIV; //波特率寄存器存放值uint32_t fck = 84000000.0; //USART1挂载在APB2的频率84MHZuint16_t integer,decimal; //波特率寄存器存放值的整数/小数RCC->AHB1ENR |= 1<<0; //开启A口时钟//PA9GPIOA->MODER &= ~(3<<9*2); GPIOA->MODER |= 2<<9*2; //配置复用功能GPIOA->AFR[1] |= 7<<(9-8)*4; //配置为串口功能//PA10GPIOA->MODER &= ~(3<<10*2);GPIOA->MODER |= 2<<10*2; //配置复用功能GPIOA->AFR[1] |= 7<<(10-8)*4; //配置为串口功能//USARTRCC->APB2ENR |= 1<<4; //开启USART1时钟USART1->CR1 &= ~(1<<15); //串口配置16倍过采样USART1->CR1 &= ~(1<<12); //配置8位数据USART1->CR2 &= ~(3<<12); //1位停止位//波特率USARTDIV = fck/(8*(2 - 0)*brr);integer = USARTDIV; //整数部分decimal = (USARTDIV - integer)*16; //小数部分USART1->BRR = integer<<4 | decimal; //数据放入波特率寄存器 USART1->CR1 |= 1<<3; //使能发送器USART1->CR1 |= 1<<2; //使能接收器USART1->CR1 |= 1<<13; //使能串口}/********************************
函数功能:修改printf底层代码
注意:不可更改!
魔术棒Target---Use MicroLIB
*********************************/
int fputc(int data,FILE* file)
{while(!(USART1->SR & 1<<6)){}USART1->DR = data; //清标志位&&发送数据return data;
}/************************************
函数功能:串口USART1传输字符串
函数参数:str:字符串
*************************************/
void Prin_Str(uint8_t *str)
{uint8_t ch;uint32_t i = 0;while(str[i] != '\0'){ch = str[i];while(!(USART1->SR & 1<<6)){}USART1->DR = ch;i++;}
}
“KEY.c”
#include "KEY.h"
#include "delay.h"
/*****************************************
函数功能:按键初始化
函数接口:KEY1--PA0--浮空/下拉输入
******************************************/
void KEY_Init(void)
{RCC->AHB1ENR |= 1<<0; //按键PA0时钟使能GPIOA->MODER &= ~(3<<0*2); //清零&&输入模式GPIOA->PUPDR &= ~(3<<0*2); //清零&&浮空GPIOA->PUPDR |= 2<<0*2; //下拉
}
/*****************************************
函数功能:按键消抖
函数接口:KEY1--PA0--浮空/下拉输出
返回参数:返回0:没有按下,返回1:按键按下
******************************************/
uint8_t KEY_Scan(void){ static uint8_t flag =0; //0:按键未按下,1:按键已按下if((flag ==0) && (GPIOA->IDR & 1<<0)) //判断按键是否按下,IDR第0位为1时按下{flag = 1;delay(500);if(GPIOA->IDR & 1<<0){return 1;}}else if((flag==1)&& !(GPIOA->IDR & 1<<0)) //松手检测{flag = 0; //按键松手}return 0;
}#if 0
uint8_t KEY_Scan2(void)
{static uint8_t flag = 0;if((flag == 0)&&(GPIOA->IDR & 1<<0 || GPIOA->IDR & 1<<1)){delay(1000);if(GPIOA->IDR & 1<<0){return 1;}if(GPIOA->IDR & 1<<1){return 2;}}else if((flag == 1) && (!(GPIOA->IDR & 1<<0) || !(GPIOA->IDR & 1<<1))){flag = 0;}return 0;
}uint8_t KEY_Scan3(void)
{static uint8_t flag = 0;if((flag == 0)&&(KEY1==1 || KEY2 == 1)){delay(1000);if(KEY1==1){return 1;}if(KEY2==1){return 2;}}else if((flag == 1) && (KEY1==0 || KEY2==0)){flag = 0;}return 0;
}#endif
“main.c”
#include "stm32f4xx.h" // Device header
#include "LED.h"
#include "KEY.h"
#include "delay.h"
#include "time.h"
#include "usart.h"
#include "stdio.h"#define STR "qwertyuiop" //串口1传输字符串int main(void)
{uint8_t key;LED_Init();KEY_Init();USART1_Init(115200);printf("按下KEY1发送数据:\r\n");while(1){ key = KEY_Scan();if(key == 1){Prin_Str(STR);LED5 = !LED5;printf("按下KEY1发送数据:\r\n");}}
}
相关文章:

单片机05__串口USART通信__按键控制向上位机传输字符串
串口USART通信 通用UART介绍 1.通信的概念 计算机与外界进行信息交换的过程称之为通信。 在通信的过程中,通信双方都需要遵守的规则称之为通信协议。 硬件协议:将数据以什么样的方式传输过去 软件协议:将数据以什么样的顺序传输过去 2.常用…...

实习日志30
概要 高拍仪硬件通信原理,WebSocket源码解析(JavaScript) WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据…...

【MySQL】探索表结构、数据类型和基本操作
表、记录、字段 数据库的E-R(entity-relationship,实体-关系)模型中有三个主要概念: 实体集 、 属性 、 关系集 。 一个实体集对应于数据库中的一个表,一个实体则对应于数据库表 中的一行,也称为一条记录。…...

解决采集时使用selenium被屏蔽的办法
解决采集时使用selenium被屏蔽的办法 实用seleniumbase uc模式 from seleniumbase import Driver driver Driver(ucTrue) # 使用UC模式UC模式是基于undetected-chromedriver 但做了一些优化更新,使用起来更方便 官方例子: from seleniumbase import …...

stream流-> 判定 + 过滤 + 收集
List<HotArticleVo> hotArticleVos hotArticleVoList .stream() .filter(x -> x.getChannelId().equals(wmChannel.getId())).collect(Collectors.toList()); 使用Java 8中的Stream API对一个名为hotArticleVoList的列表进行过滤操作,筛选出符合指定条件…...

人工智能在测绘行业的应用与挑战
目录 一、背景 二、AI在测绘行业的应用方向 1. 自动化特征提取 2. 数据处理与分析 3. 无人机测绘 4. 智能导航与路径规划 5. 三维建模与可视化 6. 地理信息系统(GIS)智能化 三、发展前景 1. 技术融合 2. 精准测绘 3. 智慧城市建设 4. 可…...

四、分类算法 - 随机森林
目录 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结 sklearn转换器和估算器KNN算法模型选择和调优朴素贝叶斯算法决策树随机森林 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结...

pytorch -- DataLoader
定义 提供了给定数据集的迭代器 torch.utils.data.DataLoader(dataset, batch_size1, 每次拿多少数据 shuffleNone, 是否打乱 samplerNone, batch_samplerNone, num_workers0, 多进程(加载数据时采用)默认是0,使用主进程加载数据 collate_fnNone, p…...

【MySQL面试复习】索引创建的原则有哪些?
系列文章目录 在MySQL中,如何定位慢查询? 发现了某个SQL语句执行很慢,如何进行分析? 了解过索引吗?(索引的底层原理)/B 树和B树的区别是什么? 什么是聚簇索引(聚集索引)和非聚簇索引…...

四种主流的prompt框架
省流版: 文章介绍了在使用GPT时的四种prompt框架,有利于使用者打磨提问风格,与GPT进行更好的交互以提高生产力,能帮助大家有效提高工作效率~ 创作不易,如果对你有帮助的话,还请三连支持~ 想要使用Prompt…...

Educational Codeforces Round 160 (Rated for Div. 2) E. Matrix Problem(费用流)
原题链接:E. Matrix Problem 题目大意: 给出一个 n n n 行 m m m 列的 0 / 1 0/1 0/1 矩阵,再给出一些限制条件:一个长为 n n n 的数组 a a a,和一个长为 m m m 的数组 b b b 。 其中 a i a_{i} ai 表示第 …...

基于SpringBoot的气象数据监测分析大屏
项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问…...

关于硅的制造芯片的过程
芯片是如何制作的? 先将硅融化制成硅晶片,再用光刻机印压电路。 bilibili芯片制作视频 硅晶片作为现代芯片的主要元件,广泛用于集成电路。 首先将多晶硅放入特制的密封炉,排除其中空气后加热到1420摄氏度,将融化的硅放…...

【深度学习笔记】3_10 多层感知机的PyTorch实现
注:本文为《动手学深度学习》开源内容,仅为个人学习记录,无抄袭搬运意图 3.10 多层感知机的简洁实现 下面我们使用PyTorch来实现上一节中的多层感知机。首先导入所需的包或模块。 import torch from torch import nn from torch.nn import …...

输入法在 Android13上候选词 候选区域 不显示的问题
背景 自研的输入法发现在 Android13 平台上不显示候选区域,在之前平台上以及需求是输入英文时不显示,中文需要显示。 最终解决办法:setExtractViewShown(false) Override public View onCreateCandidatesView() {...setExtractViewShown(f…...

Java 面向对象进阶 18 JDK8、9开始新增的方法;接口的应用;适配器设计模式;内部类(黑马)
一、JDK8开始新增的方法 默认方法不是抽象方法,所以不强制被重写: 但是如果被重写,就要去掉default关键字: public可以省略,但是default不可以省略: public是灰色的,代表可以省略 但是default是…...

数据结构-二分搜索树(Binary Search Tree)
一,简单了解二分搜索树 树结构: 问题:为什么要创造这种数据结构 1,树结构本身是一种天然的组织结构,就好像我们的文件夹一样,一层一层的. 2,树结构可以更高效的处理问题 二,二分搜索树的基础 1、二叉树 2,二叉树的重要特性 满二叉树 总结: 1. 叶子结点出现在二叉树的最…...

YOLO如何训练自己的模型
目录 步骤 一、打标签 二、数据集 三、跑train代码出模型 四、跑detect代码出结果 五、详细操作 步骤 一、打标签 (1)在终端 pip install labelimg (2)在终端输入labelimg打开 如何打标签: 推荐文章…...

05 EXTI外部中断
一、中断系统 中断系统:管理和执行中断的逻辑结构。中断:在主程序运行过程中,出现了特定的中断触发条件——中断源,使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继…...

2024.2.23
1.1.1 信号默认、捕获、忽略处理(普通信号) #include <myhead.h> void handler(int signo) {if(signoSIGINT){printf("用户键入 ctrlc\n");} } int main(int argc, const char *argv[]) {//忽略信号if(signal(SIGINT,SIG_IGN)SIG_ERR){perror("signal er…...

PHP实现分离金额和其他内容便于统计计算
得到的结果可以粘贴到excel计算 <?php if($_GET["x"] "cha"){ $tips isset($_POST[tips]) ? $_POST[tips] : ; $pattern /(\d\.\d|\d)/; $result preg_replace($pattern, "\t\${1}\t", $tips); echo "<h2><strong>数…...

基础数据结构和算法《》
递归 1.递归应该一种比较常见的实现一些特殊代码逻辑时需要做的,但常常也是最绕的一种方式,在解释递归 之前,我们用循环和递归来做个比较1.1.如果你打开一扇门后,同样发现前方也有一扇们,紧接着你又打开下一扇门...直…...

[设计模式Java实现附plantuml源码~行为型]对象间的联动~观察者模式
前言: 为什么之前写过Golang 版的设计模式,还在重新写Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很…...

vue3+js 实现记住密码功能
常见的几种实现方式 1 基于spring security 的remember me 功能 localStorage 除非主动清除localStorage 里的信息 ,不然永远存在,关闭浏览器之后下次启动仍然存在 存放数据大小一般为5M 不与服务器进行交互通信 cookies 可以…...

基于单片机的太阳能电池板自动跟踪系统的研究
摘要 伴随着人类社会的发展,人口基数越来越大,电量消耗巨大,传统发电原 料污染环境的同时,可用量日益减少,给人类未来生产生活带来了一定的威胁, 因而解决日益剧增的用电量,寻求一种新能源显得极其重要。论文正是基于此 背景下,针对当前太阳能电池板采光率低、自动化水…...

React 模态框的设计(二)
自定义组件是每个前端开发者必备的技能。我们在使用现有框架时难免有一些超乎框架以处的特别的需求,比如关于弹窗,每个应用都会用到,但是有时我们使用的框架中提供的弹窗功能也是功能有限,无法满足我们的应用需求,今天…...

操作符详解3
✨✨ 欢迎大家来到莉莉的博文✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 前面我们已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作 符,今天继续介绍一部分。 目录 1.操作符的分类 2…...

【C语言基础】:操作符详解(一)
文章目录 操作符详解1. 操作符的分类2. 二进制和进制转换2.1 什么是二进制、八进制、十进制、十六进制2.1.1 二进制和进制转换2.1.2 二进制转十进制2.2.3 二进制转八进制2.2.4 二进制转十六进制 3. 源码、反码、补码4. 移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&…...

通俗易懂分析:Vite和Webpack的区别
1、对项目构建的理解 先从浏览器出发, 浏览器是由浏览器内核和JS引擎组成;浏览器内核编译解析html代码和css代码,js引擎编译解析JavaScript代码;所以从本质上,浏览器只能识别运行JavaScript、CSS、HTML代码。 而我们在…...

OpenCart程序结构与业务逻辑
一、程序业务逻辑说明 在 OpenCart 中,index.php 文件是整个应用程序的入口文件,它负责初始化应用程序并调度请求。以下是 index.php 文件加载执行的流程: 1. **设置路径常量:** - index.php 首先定义了一些重要的路径常量&…...