GD32F103VE串口与DMA传输

news2024/7/6 0:50:01

GD32F103VE串口与DMA传输,本测试采用的的串口1和DMA0之间的数据传输,然后通过RS485和其它设备进行数据交换,没有采用任何中断参与。

GD32F103VE的DMA0请求映射到串口:
1,USART0_RX映射到DMA0的通道4,USART0_TX映射到DMA0的通道3;
2,USART1_RX映射到DMA0的通道5,USART1_TX映射到DMA0的通道6
3,USART2_RX映射到DMA0的通道2,USART2_TX映射到DMA0的通道1;

有时需要插图讲解,可能会更好。无图的中文,过了一段时间,自己都不清楚自己在讲啥。见下图:

 程序比一堆文字叙述更为重要。说实话,也参考了很多的人测试程序,没有达到我想要的结果。

#include "USART1_DMA0.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "delay.h"

/*
DMA0请求映射到串口:
USART0_RX映射到DMA0的通道4,USART0_TX映射到DMA0的通道3;
USART1_RX映射到DMA0的通道5,USART1_TX映射到DMA0的通道6;
USART2_RX映射到DMA0的通道2,USART2_TX映射到DMA0的通道1;
*/

void GD32F103_USART1_DMA0_Init(unsigned int bound);
void RS485_USART1_DMA_Send(void);
void RS485_USART1_DMA_Receive(void);

void Usart1Send_DMA0_DMA_CH6_config(void);
void Usart1Receive_DMA0_DMA_CH5_config(void);

void usart_dma_config(void);

#define ARRAYNUM(arr_name) (uint32_t)(sizeof(arr_name)/sizeof(*(arr_name))) //计算数组arr_name[]的长度

uint8_t USART1_TX_Buffer[USART1_TX_Buffer_Size] ={ 'A', 'B', 'C', 'D', '\r', '\n' };
#define USART1_RX_Buffer_Size 		      100
uint8_t USART1_RX_Buffer[USART1_RX_Buffer_Size];
uint8_t USART1_RX_Buffer_StartIndex;//USART1_RX_Buffer[]的装载索引值
uint8_t USART1_RX_Buffer_EndIndex;//USART1_RX_Buffer[]的装载索引值

void RS485_Enable_Output_Init(void)
{
	rcu_periph_clock_enable(RCU_GPIOA);  //使能GPIOA时钟,enable GPIO clock 
	gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
	//将GPIOA1设置为输出上拉

	RS485_ENABLE_PIN_Output_High();
}

//函数功能:初始化USART1
void GD32F103_USART1_DMA0_Init(unsigned int bound)
{
	RS485_Enable_Output_Init();

	rcu_periph_clock_enable(RCU_GPIOA);  //使能GPIOA时钟,enable GPIO clock 
	rcu_periph_clock_enable(RCU_USART1); //使能USART时钟,enable USART clock
	gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
	//将GPIOA2设置为AFIO口(复用IO口),输出上拉
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
	//将GPIOA3设置为浮空输入口

	usart_deinit(USART1);                        //复位USART1,USART configure
	usart_baudrate_set(USART1,bound);            //设置USART1的波特率
	usart_word_length_set(USART1,USART_WL_8BIT); //设置USART1数据传输格式为8位
	usart_stop_bit_set(USART1,USART_STB_1BIT);   //设置USART1停止位为1位
	usart_parity_config(USART1,USART_PM_NONE);   //设置USART1无需奇偶校验
	usart_hardware_flow_rts_config(USART1,USART_RTS_DISABLE);  //设置不使能USART1的RTS引脚功能
	usart_hardware_flow_cts_config(USART1,USART_CTS_DISABLE); //设置不使能USART1的CTS引脚功能
	usart_receive_config(USART1, USART_RECEIVE_ENABLE);    //使能USART1接收
	usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);  //使能USART1发送
	usart_enable(USART1); //使能USART1

	Usart1Send_DMA0_DMA_CH6_config();
	Usart1Receive_DMA0_DMA_CH5_config();
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
	usart_data_transmit(USART1, (uint8_t) ch);
	while( RESET == usart_flag_get(USART1, USART_FLAG_TBE) )
	{//等待串口0发送结束
	}

	return ch;
}

void Usart1Receive_DMA0_DMA_CH5_config(void)
{
	dma_parameter_struct dma_init_struct;

	RS485_ENABLE_PIN_Output_Low();
	//必须先允许RS485接收,然后再配置"串口到DMA接收",否则第一个数据为0
	delay_ms(5);

	rcu_periph_clock_enable(RCU_DMA0);//使能DMA0时钟,enable DMA0

///配置串口DMA接收开始
初始化"DMA0通道5寄存器"开始///
  dma_deinit(DMA0, DMA_CH5);
	dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;//DMA传送方向:从外设到内存

	dma_init_struct.periph_addr = USART1_DATA_REGISTER_ADDRESS; //源数据块首地址为:串口接收数据寄存器
	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;//源数据块地址不递增
	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;//源数据块的数据宽度为8位

	dma_init_struct.memory_addr = (uint32_t)USART1_RX_Buffer;//目的数据首地址为:USART1_RX_Buffer[]
	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //目的数据块地址递增
	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;    //目的数据块的数据宽度为8位
	dma_init_struct.number = USART1_RX_Buffer_Size;          //需要接收的数据长度

  dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;      //超高的优先级
	dma_init(DMA0, DMA_CH5, &dma_init_struct);//使用dma_init_struct数据结构初始化DMA0通道5
初始化"DMA0通道5寄存器"结束//

配置"DMA0通道5工作模式"开始///
	dma_circulation_disable(DMA0, DMA_CH5);      //不使能"DMA0通道5循环工作模式"
	dma_memory_to_memory_disable(DMA0, DMA_CH5); //不使能"DMA0通道5内存到内存传输模式"
配置"DMA0通道5工作模式"结束///
///配置串口DMA接收开结束

	dma_channel_enable(DMA0, DMA_CH5);//使能指定的DMA0通道5
  usart_dma_receive_config(USART1,USART_DENR_ENABLE);//使能DMA串口接收

	USART1_RX_Buffer_StartIndex=USART1_RX_Buffer_Size-dma_transfer_number_get(DMA0,DMA_CH5);
	USART1_RX_Buffer_EndIndex=USART1_RX_Buffer_StartIndex;
}

void Usart1Send_DMA0_DMA_CH6_config(void)
{
	dma_parameter_struct dma_init_struct;

	rcu_periph_clock_enable(RCU_DMA0);//使能DMA0时钟,enable DMA0

	///配置串口DMA发送开始
初始化"DMA0通道6寄存器"开始///
	dma_deinit(DMA0,DMA_CH6);//根据DMA0通道6,将DMA0通道6的相关寄存器初始化为初始值
	dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;    //DMA传送方向:从内存到外设

	dma_init_struct.memory_addr = (uint32_t)USART1_TX_Buffer;//源数据首地址为:USART1_TX_Buffer[]
	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //源数据块地址递增
	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;    //源数据块的数据宽度为8位
	dma_init_struct.number = USART1_TX_Buffer_Size;          //源数据块的数据长度

	dma_init_struct.periph_addr = USART1_DATA_REGISTER_ADDRESS; //目的数据首地址为:串口发送数据寄存器
	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;//目的数据块地址不递增
	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;//目的据块的数据宽度为8位

	dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;      //超高的优先级
	dma_init(DMA0, DMA_CH6, &dma_init_struct);//使用dma_init_struct数据结构初始化DMA0通道6
初始化"DMA0通道6寄存器"结束///

配置"DMA0通道6工作模式"开始///
	dma_circulation_disable(DMA0, DMA_CH6);      //不使能"DMA0通道6循环工作模式"
	dma_memory_to_memory_disable(DMA0, DMA_CH6); //不使能"DMA0通道6内存到内存传输模式"
配置"DMA0通道6工作模式"结束///
///配置串口DMA发送结束

配置"DMA0通道5工作模式"开始///
	dma_circulation_disable(DMA0, DMA_CH5);      //不使能"DMA0通道5循环工作模式"
	dma_memory_to_memory_disable(DMA0, DMA_CH5); //不使能"DMA0通道5内存到内存传输模式"
配置"DMA0通道5工作模式"结束///
///配置串口DMA接收开结束

	dma_channel_enable(DMA0, DMA_CH5);//使能指定的DMA0通道5
//	usart_dma_transmit_config(USART1, USART_DENT_ENABLE);//使能DMA串口发送
}

void RS485_USART1_DMA_Send(void)
{
	RS485_ENABLE_PIN_Output_High();//允许发送
	delay_ms(5);//等待
	usart_dma_transmit_config(USART1,USART_DENT_ENABLE);//使能DMA串口发送
//	if(SET == dma_flag_get(DMA0,DMA_CH6,DMA_FLAG_FTF))//如果
//	{//USART1 TX DMA0 channel3 transfer complete
//		dma_flag_clear(DMA0,DMA_CH6,DMA_FLAG_FTF);

"DMA0通道6"初始化开始/
    dma_deinit(DMA0,DMA_CH6);//将DMA0通道6的相关寄存器初始化为初始值
	  dma_transfer_direction_config(DMA0,DMA_CH6,DMA_MEMORY_TO_PERIPHERAL);//DMA传送方向:从内存到外设
	  dma_memory_address_config(DMA0,DMA_CH6,(uint32_t)USART1_TX_Buffer);  //源数据首地址为:USART1_TX_Buffer[]
	  dma_memory_increase_enable(DMA0,DMA_CH6);                            //源数据块地址递增
	  dma_memory_width_config(DMA0,DMA_CH6,DMA_MEMORY_WIDTH_8BIT);         //源数据块的数据宽度为8位
	  dma_transfer_number_config(DMA0,DMA_CH6,strlen((char*)USART1_TX_Buffer));//源数据块的数据长度

	  dma_periph_address_config(DMA0,DMA_CH6,USART1_DATA_REGISTER_ADDRESS);//目的数据首地址为:串口发送数据寄存器
	  dma_periph_increase_disable(DMA0,DMA_CH6);                           //目的数据块地址不递增
	  dma_periph_width_config(DMA0,DMA_CH6,DMA_PERIPHERAL_WIDTH_8BIT);     //目的据块的数据宽度为8位
	  dma_priority_config(DMA0,DMA_CH6,DMA_PRIORITY_ULTRA_HIGH);           //超高的优先级
"DMA0通道6"初始化结束/

		dma_channel_enable(DMA0, DMA_CH6);//使能指定的DMA0通道6
//		usart_dma_transmit_config(USART1,USART_DENT_ENABLE);//使能DMA串口发送
//  }

  while(RESET == dma_flag_get(DMA0,DMA_CH6,DMA_FLAG_FTF))//等待发送完成
  {
  }
	dma_flag_clear(DMA0,DMA_CH6,DMA_FLAG_FTF);//清除DMA0的通道6标志
	delay_ms(5);//DMA传完,不代表串口发送完成,所以这里要等待

	RS485_ENABLE_PIN_Output_Low();//允许RS485接收
	delay_ms(5);
}

void RS485_USART1_DMA_Receive(void)
{
	uint8_t i;
	uint8_t len_New;
	uint8_t len_Old;

	len_New=dma_transfer_number_get(DMA0,DMA_CH5);//读DMA0通道5剩余空间
	len_Old=len_New;
	USART1_RX_Buffer_EndIndex=USART1_RX_Buffer_Size-len_Old;
	if(USART1_RX_Buffer_StartIndex!=USART1_RX_Buffer_EndIndex)//发现新数据
	{
	  for(i=0;i<10;i++)
	  {
		  delay_ms(2);
		  len_New=dma_transfer_number_get(DMA0,DMA_CH5);//读DMA0通道5剩余空间
		  if(len_New!=len_Old)//接收没有完成
		  {
			  len_Old=len_New;
			  i=0;
		  }
		  else i=11;
	  }
		USART1_RX_Buffer_EndIndex=USART1_RX_Buffer_Size-len_Old;

		i=0;
		for(;USART1_RX_Buffer_StartIndex!=USART1_RX_Buffer_EndIndex;)
		{//将接收到的数据保存到USART1_TX_Buffer[]中;
//			if(USART1_RX_Buffer[USART1_RX_Buffer_StartIndex])//若发现字符为0x00,则抛弃
//			{//RS485从发送进入接收,第1个字符为0
				USART1_TX_Buffer[i]=USART1_RX_Buffer[USART1_RX_Buffer_StartIndex];
			  i++;
//			}
//			else
//			{
//				USART1_TX_Buffer[i]='F';i++;
//				USART1_TX_Buffer[i]='F';i++;
//			}
			USART1_RX_Buffer_StartIndex++;
		}
		USART1_TX_Buffer[i]='\r';i++;
		USART1_TX_Buffer[i]='\n';i++;
		USART1_TX_Buffer[i]='\0';
		RS485_USART1_DMA_Send();//将接收到的数据回传

    Usart1Receive_DMA0_DMA_CH5_config();//重新初始化串口到DMA接收
	}
}

 

#ifndef __USART1_DMA0_H
#define __USART1_DMA0_H

#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t,bool

#define USART0_DATA_REGISTER_ADDRESS   ((USART0) + (0x00000004U))
//((uint32_t)0x40013804),串口0发送/接收数据寄存器地址
//USART0的基地址为0x40013800,APB2时钟
//串口发送/接收数据寄存器偏移地址为0x0004

#define USART1_DATA_REGISTER_ADDRESS   ((USART1) + (0x00000004U))  //串口0发送/接收数据寄存器地址

#define RS485_Enable_Output 		       PAout(1)
#define RS485_ENABLE_PIN_Output_High() GPIO_BOP(GPIOA)=GPIO_PIN_1  //定义RS485串口使能脚输出高电平
#define RS485_ENABLE_PIN_Output_Low()  GPIO_BC(GPIOA)=GPIO_PIN_1   //定义RS485串口使能脚输出低电平
#define RS485_ENABLE_PIN_Toggle() gpio_bit_write( GPIOA,GPIO_PIN_1,(bit_status)((1-gpio_input_bit_get(GPIOA,GPIO_PIN_1))) )
//GA1取反输出电平

#define USART1_TX_Buffer_Size 		      50
extern uint8_t USART1_TX_Buffer[USART1_TX_Buffer_Size];

extern void GD32F103_USART1_DMA0_Init(unsigned int bound);
extern void RS485_USART1_DMA_Send(void);
extern void RS485_USART1_DMA_Receive(void);

#endif

main.c程序如下:

#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t,bool
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()

#include "delay.h"
#include "USART1_DMA0.h"

const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
const char CPU_Is_Run_REG[]="\r\nCPU is run!\r\n";
int main(void)
{
	//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
	//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
	//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
	//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
	//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"
  INTX_ENABLE();//开启所有中断
	delay_init();//初始化延迟函数
	GD32F103_USART1_DMA0_Init(115200);
  
	delay_ms(500);

	strcpy((char*)USART1_TX_Buffer,CPU_Reset_REG);
	RS485_USART1_DMA_Send();

	strcpy((char*)USART1_TX_Buffer,CPU_Is_Run_REG);
	RS485_USART1_DMA_Send();
	while(1)
	{
		RS485_USART1_DMA_Receive();
	}
}

 

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

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

相关文章

springboot 多模块 每个模块进行单独打包

springboot项目目录结构 打包模块需要进行的配置 配置文件引入打包插件 <build><finalName>api</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifac…

APT80DQ40BG-ASEMI快恢复二极管APT80DQ40BG

编辑&#xff1a;ll APT80DQ40BG-ASEMI快恢复二极管APT80DQ40BG 型号&#xff1a;APT60DQ20BG 品牌&#xff1a;ASEMI 封装&#xff1a;TO-3P 恢复时间&#xff1a;≤50ns 正向电流&#xff1a;80A 反向耐压&#xff1a;400V 芯片个数&#xff1a;双芯片 引脚数量&…

MySQL|查看事务加锁情况

文章目录 使用information_schema数据库中的表获取锁信息INNODB_TRXINNODB_LOCKSINNODB_LOCK_WAITS 使用SHOW ENGINE INNODB STATUS获取信息补充 使用information_schema数据库中的表获取锁信息 在information_schema数据库中&#xff0c;有几个与事务和锁紧密相关的表 INNOD…

回归预测 | MATLAB实现K折交叉验证GRNN广义回归神经网络多输入单输出回归预测

回归预测 | MATLAB实现K折交叉验证GRNN广义回归神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现K折交叉验证GRNN广义回归神经网络多输入单输出回归预测效果一览基本介绍研究内容程序设计参考资料效果一览 基本介绍 回归预测 | MATLAB实现K折交叉验证GRNN广义回归神经…

MySQL高阶知识点(一) 一条 SQL查询语句是如何被执行的

一条 SQL查询语句是如何被执行的 MySQL 的基本架构示意图如下所示&#xff1a;

MySQL分析查询语句Explain

1概述 ​ 定位了查询慢的SQL之后&#xff0c;就可以使用EXPLAIN或者DESCRIBE工具做针对性的分析查询。两者使用方法相同&#xff0c;并且分析结果也是相同的。 ​ MySQL中有专门负责SQL语句优化的优化器模块&#xff0c;主要功能是计算分析系统中收集到的统计信息&#xff0c…

生信豆芽菜-limma差异分析使用说明

网站&#xff1a;http://www.sxdyc.com/diffLimmaAnalyse 一、limma简介 什么是limma&#xff1f; 首先要明白&#xff0c;不管哪种差异分析&#xff0c;其本质都是广义线性模型。 limma也是广义线性模型的一种&#xff0c;其对每个gene的表达量拟合一个线性方程。 limma的分析…

模拟实现消息队列项目(系列8) -- 实现MqClient

目录 前言 1. 创建ConnectionFactory 2. Connection 和 Channel 的定义 2.1 Connection 2.2 Channel 3. 封装请求响应读写操作 3.1 写入请求 3.2 读取响应 3.3 Connection中创建Channel 4. 封装发送请求的操作 4.1 创建Channel 4.2 阻塞等待服务器响应 4.3 添加响应信息到 basi…

【构造】CF1798 D

Problem - D - Codeforces 题意&#xff1a; 思路&#xff1a; 首先如果 a 全是 00&#xff0c;那么显然无解。 否则考虑从左到右构造新数列&#xff0c;维护新数列的前缀和 s。 如果 s≥0&#xff0c;则在剩余未加入的数中随便选择一个非正数添加到新数列末尾。如果 s<…

Semantic Kernel 入门系列:Memory内存

了解的运作原理之后&#xff0c;就可以开始使用Semantic Kernel来制作应用了。 Semantic Kernel将embedding的功能封装到了Memory中&#xff0c;用来存储上下文信息&#xff0c;就好像电脑的内存一样&#xff0c;而LLM就像是CPU一样&#xff0c;我们所需要做的就是从内存中取出…

视频声音怎么转换成文字?这四种转换方法很简单

将视频声音转换成文字的好处不仅仅限于方便记录、保存和查阅视频内容。它还可以大大提高视频内容的可访问性和可搜索性&#xff0c;使得非母语人士、听力障碍者等人群更容易理解视频内容&#xff0c;并且可以更快速地找到相关信息。此外&#xff0c;将视频声音转换成文字还可以…

ArcGISPro随机森林自动化调参分类预测模型展示

更改ArcGISPro的python环境变量请参考文章 ArcGISPro中如何使用机器学习脚本_Z_W_H_的博客-CSDN博客 脚本文件如下 点击运行 结果展示 负类预测概率 正类预测概率 二值化概率 文件夹&#xff08;模型验证结果&#xff09; 数据集数据库 ROC曲线 由于个人数据量太少所以…

工业4.0:欢迎来到智能制造

制造业正在经历一场被称为“工业4.0”的全新技术革命&#xff0c;这场革命将数字化、网络化、智能化和自动化技术融合在一起&#xff0c;旨在打造高质、高效、高产且可持续的智能工厂。工业4.0将彻底改变产品制造的方式&#xff0c;颠覆我们对制造业的传统认知。 什么是工业4.…

APP电话管家在各行业的应用

目前语音呼叫在各行业广泛应用&#xff0c;不管是电话销售也好&#xff0c;还是客户呼入咨询也好&#xff0c;部署呼叫中心对于业务提升&#xff0c;还是很有效率的。但是随着使用的行业越来越多&#xff0c;有些行业属性所在&#xff0c;需要有便于携带&#xff0c;企业管理可…

无涯教程-Perl - exp函数

描述 此函数将e(自然对数底数)返回到EXPR的幂。如果省略EXPR,则给出exp($_)。 语法 以下是此函数的简单语法- exp EXPRexp返回值 此函数不返回任何值。 Perl 中的 exp函数 - 无涯教程网无涯教程网提供描述此函数将e(自然对数底数)返回到EXPR的幂。如果省略EXPR,则给出exp(…

Flowable-结束事件-终止结束事件

目录 定义图形标记XML内容视频教程 定义 当流程到达终止结束事件时&#xff0c;该流程将终止。当流程实例有多个流程分支被激活时&#xff0c;当有一个 分支到达终止结束事件时&#xff0c;所有其它流程分支也立即结束。在 flowable 中&#xff0c;当流程执行到达终止结 束事件…

轻松抓取网页内容!API助力开发者,快速数据采集

在如今这个信息爆炸的时代&#xff0c;人们需要从各种渠道获取数据来支持自己的业务需求。而对于开发者们来说&#xff0c;如何快速、准确地从互联网上抓取所需的数据也成为了一项重要的技能。而抓取网页内容 API 则是一种能够帮助开发者轻松实现数据抓取的工具。 一、什么是抓…

springboot mongo 使用

nosql对我来说&#xff0c;就是用它的变动列&#xff0c;如果列是固定的&#xff0c;我为什么不用mysql这种关系型数据库呢&#xff1f; 所以&#xff0c;现在网上搜出来的大部分&#xff0c;用实体类去接的做法&#xff0c;并不适合我的需求。 所以&#xff0c;整理记录一下…

Vue命名规范

JS文件命名 一般采用的是小驼峰命名法&#xff0c;如 pieChartHelp 第一个单词小写&#xff0c;其他单词首字母大写 Components 文件命名 一般采用的是大驼峰命名法&#xff0c;如PieChart 所有单词的首字母大写 常量命名 一般全部大写&#xff0c;每个单词使用分隔符隔开&…

python_day18_socket客户端

客户端 import socket# 创建socket对象 socket_client socket.socket() # 链接服务器 socket_client.connect(("localhost", 19999))发消息 while True:# 发消息msg input("输入&#xff1a;")if msg exit:breaksocket_client.send(msg.encode("U…