STM32--USART串口
文章目录
- 通信接口
- 串口通信
- 硬件电路
- 电平标准
- 参数
- 时序
- USART
- 主要特性
- 框图
- 数据帧
- 发送器
- 波特率发生器
- SWART串口发送与接收工程
- 串口收发数据包
通信接口
通信接口是指连接中央处理器(CPU)和标准通信子系统之间的接口,用于实现数据和控制信息在不同设备之间的传输和交换。通信接口可以是硬件或软件实现,其目的是使不同设备之间能够进行有效地通信。
上图是常见的通用通信类型。
双工指的是接口能够实现双向数据传输,即可以同时进行发送和接收数据的功能。
半双工:数据在同一个通信信道上交替地进行双向传输,但不能同时进行发送和接收。发送方和接收方需要在不同时间段进行数据传输。
全双工:数据可以同时进行双向数据传输,发送方和接收方可以在同一时间段进行数据发送和接收。通信双方可以独立地进行发送和接收工作。
时钟是指在传输数据是否能达到同步传输。
同步传输:发送方和接收方之间使用一个共同的时钟信号来同步数据的传输。发送方根据时钟信号将数据按照固定的速率发送,接收方也按照相同的时钟信号来接收数据。
异步传输:数据的传输不依赖于共同的时钟信号,而是使用起始位、停止位和数据位之间的固定时间间隔进行同步。发送方会在发送数据之前先发送一个起始位作为同步信号,接收方通过检测起始位来确定数据的开始和结束。
电平是指传输信号时的电压信号形式。
单端传输:信号传输使用单个导线进行,信号的电压相对于某个参考电平变化来表示。这意味着信号只有一个极性,数据通过高低电平表示。在单端传输中,由于信号线未与其他导线耦合,容易受到电磁干扰的影响,可能导致信号质量的下降。
差分传输:信号的传输使用两个导线进行,信号通过两个相互补充的电压信号的差异来表示。差分传输具有很强的抗干扰能力,可以减少电磁干扰对信号的影响。
串口通信
串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信;适用于近距离的通信。
单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力。
硬件电路
简单双向串口通信有两根通信线(发送端TX和接收端RX)
TX与RX要交叉连接
当只需单向的数据传输时,可以只接一根通信线
当电平标准不一致时,需要加电平转换芯片
电平标准
电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:
TTL电平:+3.3V或+5V表示1,0V表示0
RS232电平:-3~ -15V表示1,+3~ +15V表示0
RS485电平:两线压差+2~+6V表示1,-2 ~-6V表示0(差分信号)
参数
波特率:串口通信的速率,可以指定每秒传输的位数
起始位:标志一个数据帧的开始,固定为低电平
数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行
校验位:用于数据验证,根据数据位计算得来
常用奇偶校验位:通过在数据中添加一个附加位(校验位),以确保接收端可以检测到传输过程中的错误。
奇校验:如果数据位中1的个数为偶数,则校验位设置为1,使得数据位和校验位中的1的总和保持奇数。如果数据位中1的个数为奇数,那么校验位置0。
偶校验:如果数据位中1的个数为偶数,则校验位置0,使得数据位和校验位的总个数为偶数。如果数据位中1的个数为奇数,校验位置1 。
停止位:用于数据帧间隔,固定为高电平
时序
输入不同的数据,显示不同的时序。
USART
通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。
主要特性
1.全双工的,异步通信
2.分数波特率发生器系统
─ 发送和接收共用的可编程波特率,最高达4.5Mbits/s
3.可编程数据字长度(8位或9位)
4.可配置的停止位-支持1或2个停止位
5.校验控制
─ 发送校验位
─ 对接收数据进行校验
6.支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN
框图
先看左上角的接口处,TX与RX就是发送和接收的引脚,下面的三个接口是智能卡和IrDA通信的引脚。
发送脚就是通过发送移位寄存器送出去的,接收脚就是将接收数据送到接收移位寄存器的。
灰色部分就是串口的数据寄存器。有两个数据寄存器,一个用来发送数据,一个用来接收数据;在程序上,只表现为一个寄存器,它们寄存器共用地址进行存储。
当你进行写入操作时,数据就写到TDR,当你进行读取操作时,数据就从RDR进行读出。
下面是移位寄存器,作用是把一个字节的数据一位一位进行位移。
假设你在某时刻给TDR写入数据0x66,在二进制存储就是01100110,此时硬件会检测到你写入的数据,就会检查移位寄存器是否有数据正在移位,如果没有01100110就会立刻放入移位寄存器中,此时也会置出一个标志位TXE,发送寄存器为空;有了这个标志我们就可以在TDR再写入一个数据了。移位寄存器在发送器控制的情况下,将数据一位一位进行传输到TX引脚进行输出(低位先出),当数据全部移位后,新的数据就会再次从TDR转移到移位寄存器中来,如果移位寄存器还没有完成,那么TDR会等移位寄存器完成移位之后才将数据转移。有了TDR和移位寄存器双重缓存,可以保证数据发送时,数据帧之间没有空闲。
而接收部分也是同样的道理,接收移位寄存器由接收器控制,低位先放到移位寄存器的高位,随着数据的增加而右移,当移位寄存器数据达到一个字节后,传输给接收寄存器RDR,此时也会有一个标志位RXNE置1,意味着接收寄存器有数据了,我们可以对DR寄存器的数据进行读走。
接着看到下面,有一个硬件数据流控,如果发送设备发送太快,接收设备来不及处理,可以通过流控来控制传输的速度。
它有两个引脚,一个是nRTS,另一个是nCTS。
nRTS是请求发送,是输出脚,就是告诉别人,我当前能不能接收;
nCTS是清除发送,是输入脚,用于接收别人nRTS的信号;
接着看右边的SCLK,这是一个产生同步的时钟信号,它是配合发送移位寄存器输出的,发送移位寄存器每发送一次,同步时钟电平就跳变一个周期,时钟会告诉对方我已经移出去一个数据了,你看要不要让我这个时钟信号来指导你接收一下?当然这个时钟只支持输出,不支持输入,所以两个SWART不能实现同步的串口通信。
主要用途是兼容别的协议或者做自适应波特率。
接着看到中间的唤醒单元,这部分的作用是实现串口挂载多个设备。
中断控制,支持对标志位标志的地方进行中断。
最下面的波特率发生器部分,其实就是分频器,对APB时钟进行分频,得到发送和接收移位的时钟。
数据帧
字长可以通过编程USART_CR1寄存器中的M位,选择成8或9位(见图249)。在起始位期间, TX脚处于低电平,在停止位期间处于高电平。
发送器
发送器根据M位的状态发送8位或9位的数据字。当发送使能位(TE)被设置时,发送移位寄存器中的数据在TX脚上输出,相应的时钟脉冲在CK脚上输出。
USART支持多种停止位的配置: 0.5、 1、 1.5和2个停止位。
波特率发生器
发送器和接收器的波特率由波特率寄存器BRR里的DIV确定
计算公式:波特率 = fPCLK2/1 / (16 * DIV)
假设我们要输出波特率为9600,那么通过计算DIV=72M/16/9600=468.75
所以置于波特率寄存器中的值为468.75.
SWART串口发送与接收工程
OLED代码链接入口
接线方式:
发送时需要一个串口助手在电脑来显示内容,我们将实现STM32与电脑之间的数据传输。以STM32为主机。
Serial.h
#ifndef __SERIAL_H__
#define __SERIAL_H__#include <stdio.h>void Serial_Init();
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t* Arr,uint8_t Lenth);
void Serial_SendString(char* String);
void Serial_SendNumber(uint32_t Number,uint8_t Lenth);
uint8_t Serial_GetRxFlag();
uint8_t Serial_GetRxData();#endif
Serial.c
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>uint8_t Serial_RxData;
uint8_t Serial_RxFlag;void Serial_Init()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate=9600; //配置波特率USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //配置硬件流控模式USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; //串口模式USART_InitStructure.USART_Parity=USART_Parity_No; //配置奇偶效验位USART_InitStructure.USART_StopBits=USART_StopBits_1; //指定停止位数USART_InitStructure.USART_WordLength=USART_WordLength_8b; //指定数据帧位数USART_Init(USART1,&USART_InitStructure);//配置usart开启中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//中断源RXNENVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);
}//发送字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1,Byte);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}//发送数组
void Serial_SendArray(uint8_t* Arr,uint8_t Lenth)
{uint8_t i;for(i=0;i<Lenth;i++){Serial_SendByte(Arr[i]);}
}//发送字符串
void Serial_SendString(char* String)
{uint8_t i;for(i=0;String[i]!='\0';i++){Serial_SendByte(String[i]);}
}uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{uint32_t Result=1;while(Y--){Result*=X;}return Result;
}void Serial_SendNumber(uint32_t Number,uint8_t Lenth)
{uint8_t i;for(i=0;i<Lenth;i++){Serial_SendByte(Number/Serial_Pow(10,Lenth-1-i)%10+'0');}
}//获取接收状态
uint8_t Serial_GetRxFlag()
{if(Serial_RxFlag==1){Serial_RxFlag=0;return 1;}return 0;}
//获取接收数据
uint8_t Serial_GetRxData()
{return Serial_RxData;
}void USART1_IRQHandler()
{if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){Serial_RxData=USART_ReceiveData(USART1);Serial_RxFlag=1;USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
}
初始化输出需要配置复用功能,因为SWART为片上外设。
发送字节需要用TXE标志位来表示已经从DR寄存器发送到移位寄存器中。所以用到while来进行等待;
接收时,利用RNXE产生的标志位来产生中断,在中断函数中获取DR寄存器的数据。
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Buzzer.h"
#include "Serial.h"
#include "OLED.h"
int main()
{uint8_t Rxdata;OLED_Init();Serial_Init();OLED_ShowString(1,1,"RxData:");while(1){if(Serial_GetRxFlag()==1){Rxdata=Serial_GetRxData();Serial_SendByte(Rxdata);OLED_ShowHexNum(1,8,Rxdata,2);}}}
串口收发数据包
连接方式:
利用连续的数据序列来对LED灯的亮灭进行控制;
Serial.h
#ifndef __SERIAL_H__
#define __SERIAL_H__#include <stdio.h>
#include <string.h>extern uint8_t Serial_RxFlag;
extern char Serial_RxPacket[];void Serial_Init();
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t* Arr,uint8_t Lenth);
void Serial_SendString(char* String);
void Serial_SendNumber(uint32_t Number,uint8_t Lenth);
void Serial_Printf(char* format,...);#endif
Serial.c
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>char Serial_RxPacket[100];
uint8_t Serial_RxFlag;void Serial_Init()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate=9600; //配置波特率USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //配置硬件流控模式USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; //串口模式USART_InitStructure.USART_Parity=USART_Parity_No; //配置奇偶效验位USART_InitStructure.USART_StopBits=USART_StopBits_1; //指定停止位数USART_InitStructure.USART_WordLength=USART_WordLength_8b; //指定数据帧位数USART_Init(USART1,&USART_InitStructure);//配置usart开启中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//中断源RXNENVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);
}//发送字节
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1,Byte);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}//发送数组
void Serial_SendArray(uint8_t* Arr,uint8_t Lenth)
{uint8_t i;for(i=0;i<Lenth;i++){Serial_SendByte(Arr[i]);}
}//发送字符串
void Serial_SendString(char* String)
{uint8_t i;for(i=0;String[i]!='\0';i++){Serial_SendByte(String[i]);}
}uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{uint32_t Result=1;while(Y--){Result*=X;}return Result;
}
//发送数字
void Serial_SendNumber(uint32_t Number,uint8_t Lenth)
{uint8_t i;for(i=0;i<Lenth;i++){Serial_SendByte(Number/Serial_Pow(10,Lenth-1-i)%10+'0');}
}void Serial_Printf(char* format,...)
{char String[100];va_list arg;va_start(arg,format);vsprintf(String,format,arg);va_end(arg);Serial_SendString(String);
}//串口接收中断(接收一位数据中断一次),接收数据包
void USART1_IRQHandler()
{static uint8_t RxState=0; //获取当前状态static uint8_t pRxPacket=0; //数据包有效位下标if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){uint8_t RxData=USART_ReceiveData(USART1);if(RxState==0){if(RxData=='&'&& Serial_RxFlag==0){RxState=1;pRxPacket=0;}}else if(RxState==1){ if(RxData=='\r'){RxState=2;}else{Serial_RxPacket[pRxPacket++]=RxData;}}else if(RxState==2){if(RxData=='\n'){RxState=0;Serial_RxPacket[pRxPacket]='\0';Serial_RxFlag=1;}}USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
}
对于接收的数据包,利用了一种状态机的方式进行接收
通过包头和包尾对数据有效位进行保护,可以让一连串重复的数据可以找到数据位,避免找不到数据位的头的情况。
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Serial.h"
#include "OLED.h"
int main()
{OLED_Init();Serial_Init();LED_Init();OLED_ShowString(1, 1, "RxPacket:");while(1){if(Serial_RxFlag==1){if(strcmp(Serial_RxPacket,"LED_ON")==0){LED1_ON();OLED_ShowString(2,1,"LED_ON_OK ");Serial_SendString("LED_ON_OK");}else if(strcmp(Serial_RxPacket,"LED_OFF")==0){LED1_OFF();OLED_ShowString(2,1,"LED_OFF_OK ");Serial_SendString("LED_OFF_OK");}else{OLED_ShowString(2,1,"ERROR_COMMAND");Serial_SendString("ERROR_COMMAND");}Serial_RxFlag=0;}}}
LED.c
#include "stm32f10x.h" // Device headervoid LED_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);
}void LED1_ON(void)
{GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}void LED1_OFF(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_1);
}void LED1_Turn(void)
{if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0){GPIO_SetBits(GPIOA, GPIO_Pin_1);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_1);}
}void LED2_ON(void)
{GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}void LED2_OFF(void)
{GPIO_SetBits(GPIOA, GPIO_Pin_2);
}void LED2_Turn(void)
{if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0){GPIO_SetBits(GPIOA, GPIO_Pin_2);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_2);}
}
LED.h
#ifndef __LED_H__
#define __LED_H__void LED_Init();
void LED1_ON();
void LED1_OFF();
void LED1_Turn();
void LED2_ON();
void LED2_OFF();
void LED2_Turn();#endif
相关文章:
STM32--USART串口
文章目录 通信接口串口通信硬件电路电平标准参数时序 USART主要特性框图 数据帧发送器 波特率发生器SWART串口发送与接收工程串口收发数据包 通信接口 通信接口是指连接中央处理器(CPU)和标准通信子系统之间的接口,用于实现数据和控制信息在不…...
2023年Java毕业设计题目推荐,怎样选题?500道毕业设计题目推荐
大家好,我是程序员徐师兄,最近有很多同学咨询,说毕业设计了,不知道选怎么题目好,有哪些是想需要注意的。 今天,我整理了一些Java毕业设计的题目,可以参考一下,希望对大家有所帮助 文章目录 一、…...
基于数据湖的多流拼接方案-HUDI概念篇
目录 一、为什么需要HUDI? 1. 传统技术选型存在哪些问题? 2. Hudi有什么优点? 基于 Hudi Payload 机制的多流拼接方案: 二、HUDI的应用场景 1. 什么场景适合使用hudi? 2. 什么场景不适合使用hudi? …...
OpenCV基础知识(5)— 几何变换
前言:Hello大家好,我是小哥谈。OpenCV中的几何变换是指改变图像的几何结构,例如大小、角度和形状等,让图像呈现出缩放、翻转、旋转和透视效果。这些几何变换操作都涉及复杂、精密的计算。OpenCV将这些计算过程都封装成了非常灵活的…...
Linux下源码安装MySQL 8.0
MySQL 8.0源码安装 环境准备步骤 环境准备 Linux环境,本文基于CentOS 8 MySQL安装包,本文基于MySQL 8.1,以下为带boost MySQL 8.1源码下载地址: https://dev.mysql.com/get/Downloads/MySQL-8.1/mysql-boost-8.1.0.tar.gz 步骤…...
大聪明教你学Java | 深入浅出聊 Java 内存模型
前言 🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。 🍊支持作者: 点赞👍、关注💖、留言💌~ 在多线程环境下,多个线程同时访问共享数据可能导致一系列问题,如数据不一致、竞态条件和死锁等…...
SAP ABAPG开发屏幕自动生成日期的搜索帮助
代码如下: REPORT z_jason_test_f4 . TABLES: s031. PARAMETER p_spmon TYPE spmon DEFAULT sy-datum0(6) OBLIGATORY. SELECT-OPTIONS s_spmon FOR s031-spmon DEFAULT sy-datum0(6) OBLIGATORY. AT SELECTION-SCREEN ON VALUE-REQUEST…...
leetcode 674. 最长连续递增序列
2023.8.24 与最长递增子序列 类似,不同的是, 本题要求连续序列,所以不需要第二层遍历比较之前所有的元素了,只需要比较上一个元素i-1。 dp[i]的含义为:以nums[i]元素为结尾的序列的最长递增子序列。 注意这里是以i为结…...
Mysql简短又易懂
MySql 连接池:的两个参数 最大连接数:可以同时发起的最大连接数 单次最大数据报文:接受数据报文的最大长度 数据库如何存储数据 存储引擎: InnoDB:通过执行器对内存和磁盘的数据进行写入和读出 优化SQL语句innoDB会把需要写入或者更新的数…...
vue 简单实验 v-model 变量和htm值双向绑定
1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"two-way-binding"><p>{{ message }}</p><input v-model"message" /> </div> <script>…...
测试框架pytest教程(8)失败重试-pytest-rerunfailures
pytest-rerunfailures是一个pytest插件,用于重新运行失败的测试用例。当测试用例在第一次运行时失败,该插件会自动重新运行指定次数的失败用例,以提高稳定性和减少偶发性错误的影响。 要使用pytest-rerunfailures插件,需要按照以…...
6个主流的工业3D管道设计软件
3D 管道设计软件是大多数行业工程工作的主要部分,例如: 电力、石油和天然气、石化、炼油厂、纸浆和造纸、化学品和加工业。 全球各工程公司使用了近 50 种工厂或管道设计软件。 每个软件都有优点和缺点,包括价格点。 EPC 和业主部门当前的趋势…...
基于微信小程序的垃圾分类系统设计与实现(2.0 版本,附前后端代码)
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 1 简介 视频演示地址: 基于微信小程序的智能垃圾分类回收系统,可作为毕业设计 小…...
基础论文学习(4)——CLIP
《Learning Transferable Visual Models From Natural Language Supervision》 CLIP的英文全称是Contrastive Language-Image Pre-training,即一种基于对比文本-图像对的预训练模型。CLIP是一种基于对比学习的多模态模型,与CV中的一些对比学习方法如moc…...
SpringBoot利用ConstraintValidator实现自定义注解校验
一、前言 ConstraintValidator是Java Bean Validation(JSR-303)规范中的一个接口,用于实现自定义校验注解的校验逻辑。ConstraintValidator定义了两个泛型参数,分别是注解类型和被校验的值类型。在实现ConstraintValidator接口时&…...
十、pikachu之php反序列化
文章目录 1、php反序列化概述2、实战3、关于Magic function4、__wakeup()和destruct() 1、php反序列化概述 在理解这个漏洞前,首先搞清楚php中serialize(),unserialize()这两个函数。 (1)序列化serialize():就是把一个…...
PHP“牵手”拼多多商品详情数据获取方法,拼多多API接口批量获取拼多多商品详情数据说明
拼多多商品详情接口 API 是开放平台提供的一种 API 接口,它可以帮助开发者获取拼多多商品的详细信息,包括商品的标题、描述、图片等信息。在拼多多电商平台的开发中,拼多多详情接口 API 是非常常用的 API,因此本文将详细介绍拼多多…...
前端面试:【Redux】状态管理的精髓
嘿,亲爱的Redux探险家!在前端开发的旅程中,有一个强大的状态管理工具,那就是Redux。Redux是一个状态容器,它以一种可预测的方式管理应用的状态,通过Store、Action、Reducer、中间件和异步处理等核心概念&am…...
element-ui中的el-table的summary-method(合计)的使用
场景图片: 图片1: 图片2: 一:使用element中的方法 优点: 直接使用summary-method方法,直接,方便 缺点: 只是在表格下面添加了一行,如果想有多行就不行了 1:h…...
“深入探索JVM:解析Java虚拟机的工作原理与性能优化“
标题:深入探索JVM:解析Java虚拟机的工作原理与性能优化 摘要:本文将深入探讨Java虚拟机(JVM)的工作原理和性能优化。我们将首先介绍JVM的基本组成和工作流程,然后重点讨论JVM内存管理、垃圾回收算法以及性…...
【后端】Core框架版本和发布时间以及.net 6.0启动文件的结构
2023年,第35周,第1篇文章。给自己一个目标,然后坚持总会有收货,不信你试试! .NET Core 是一个跨平台的开源框架,用于构建现代化的应用程序。它在不同版本中有一些重要的区别和发布时间 目录 一、Core版本和…...
Linux 定时任务 crontab 用法学习整理
一、linux版本 lsb_release -a 二、crontab 用法学习 2.1,crontab 简介 linux中crontab命令用于设置周期性被执行的指令,该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。cron 系统调度进程。…...
看板之道:如何利用Kanban优化您的项目流程
引言 在项目管理的世界中,如何确保任务的流畅进行并及时交付是每个团队都面临的挑战。Kanban,作为一种敏捷项目管理方法,为此提供了一个答案。它不仅提供了一种可视化的方式来跟踪任务的进度,还鼓励团队持续改进其工作流程&#…...
Docker的基础操作
1.安装docker服务,配置镜像加速器 1.1 使用yum进行安装 添加docker-ce的源信息 [rootlocalhost ~]# yum install yum-utils device-mapper-persistent-data lvm2 -y [rootlocalhost ~]# yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/doc…...
14、缓存预热+缓存雪崩+缓存击穿+缓存穿透
缓存预热缓存雪崩缓存击穿缓存穿透 ● 缓存预热、雪崩、穿透、击穿分别是什么?你遇到过那几个情况? ● 缓存预热你是怎么做到的? ● 如何避免或者减少缓存雪崩? ● 穿透和击穿有什么区别?它两一个意思还是截然不同&am…...
【PostGreSQL】PostGreSQL到Oracle的数据迁移
项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果是个PostGreSQL的数据,于是装数据库,但这个也不懂呀,而且本系统用的Oracle,于是得解决迁移转换的问题。 总结下来两个思路。 1、Postg…...
jupyter notebook出现ERR_SSL_VERSION_OR_CIPHER_MISMATCH解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...
前端进阶Html+css10----定位的参照对象(高频面试题)
1.relative的参照对象 1)元素按照标准流进行排布; 2)定位参照对象是元素自己原来的位置,可以通过left、right、top、bottom来进行位置调整; 2.absolute(子绝父相) 1)元素脱离标准流…...
总结记录Keras开发构建神经网络模型的三种主流方式:序列模型、函数模型、子类模型
Keras是一个易于使用且功能强大的神经网络建模库,它是基于Python语言开发的。Keras提供了高级API,使得用户能够轻松地定义和训练神经网络模型,无论是用于分类、回归还是其他任务。 Keras的主要特点如下: 简单易用:Kera…...
python环境建设
1. 查看通过pip安装包的路径 问题:devchat vscode中配置需要查找devchat的安装路径,使用pip相关的命令查看 pip list | grep package_name 命令显示获取已安装包的信息(包名与版本号)pip show package_name命令能显示该安装的包…...
wordpress修改页面标题显示不出来/佛山网络推广公司
企业内部发展很关键,这是硬实力,而产品的质量和功效也是属于硬实力,但是宣传也是一大要点。因为宣传企业和产品才是软实力。也是企业销售中的亮点。如今的销售方式有很多,但是不管什么样的销售方式前提都是宣传,让更多…...
网站建设文档/海外营销推广服务
maven 项目下想更改 Dynamic Web module 的版本时,发现出现了一下的错误 解决这个错误之前先看一下项目依赖的jdk版本,如果jdk版本过低的话,即便成功修改了 Dynamic Web module 不一定适用。 新建的maven项目,在eclipse下默认使用…...
国外做设计的网站有哪些/自助建站工具
(5.7sp1版测试通过)织梦DedeCMS网站内容模型普通文章调用自定义图片字段的方法:方法一:我们首先需要创建一个自定义函数,找到:/include/extend.func.php ,在< ?php 后加入以下代码:function GetOneImgU…...
网站的建设与预算/外贸推广平台怎么做
转载自:http://blog.csdn.net/zhangdaiscott/article/details/18220411 1、JavaScript视频教程 链接: http://pan.baidu.com/s/1gd57FVH 密码: d9ei 2、JPA视频教程 链接: http://pan.baidu.com/s/1dDCx1fj 密码: fwwd 3、马士兵hibernate视频教程 链接:…...
腾讯网站建设/会计培训班有用吗
1.查看快捷键定义的地方 Window->Preferences->General->Keys。 2.更改启动页 在AndroidManifest.xml第一个activity标签项中 android:name".ResultDemoActivity" ResultDemoActivity改为你想要第一启动的activity。 3.取消对“块注释的格式化” Windows-&g…...
网站设计和策划的步骤是什么/微博推广效果怎么样
这边我是使用了一个数组使用ArrayasLIst转换成了list集合; 打算遍历取出并删除原数据; 删除的时候报错UnsupportedOperationException 后来发现是asList只是给原来的数组套了一个list的接口,并没有实现原生的删除api所以无法使用;…...