GD32F103VE串口与DMA传输

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 clockgpio_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 configureusart_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); //使能USART1Usart1Send_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接收",否则第一个数据为0delay_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通道5usart_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个字符为0USART1_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.mzph.cn/news/28711.shtml

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

相关文章

FFmpeg 硬编码VideoToolBox流程

介绍 FFmpeg已经提供对 VideoToolBox 的编解码支持&#xff1b;主要涉及到的文件有videotoolbox.c、videotoolbox.h、videotoolboxenc.c、ffmepg_videotoolbox.c。在编译 FFmpeg 源码时&#xff0c;想要支持VideoToolBox&#xff0c;在 configure 时&#xff0c;需要–enable-…

艺术创作的新纪元:如何训练Lora模型打造令人惊叹的AI绘画

目录 前言一、&#x1f981; 选择合适的云端平台1-1、云端平台的优势1-2、选择适合的云端平台 二、&#x1f981; 账号注册三、&#x1f981; 开始炼丹3-1、购买算力并创建工作空间3-2、启动工作空间3-3、应用市场一键安装 四、&#x1f981; 使用Stable-Diffusion作图4-1、国风…

Flutter系列文章-实战项目

在本篇文章中&#xff0c;我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识&#xff0c;包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用&#xff0c;可以根据用户输入的城市名获取该城市的天气信息&#xff0c;并将用户查询的城市列表保存到本地…

【设计模式】责任链的基本概念及使用Predicate灵活构造校验链

文章目录 1. 概述1.1.背景1.2.责任链模式的概念 2.责任链的基本写法2.1.链表实现2.2.数组实现 3.Predicate校验链2.1.使用Predicate改写代码2.1.更丰富的条件拓展 4.总结 1. 概述 1.1.背景 在最近的开发中遇到了这么一个需求&#xff0c;需要对业务流程中的各个参数做前置校验…

python版《羊了个羊》游戏开发第一天

Python小型项目实战教学课《羊了个羊》 一、项目开发大纲&#xff08;初级&#xff09; 版本1.0&#xff1a;基本开发 课次 内容 技术 第一天 基本游戏地图数据 面向过程 第二天 鼠标点击和移动 面向对象 第三天 消除 设计模式&#xff1a;单例模式 第四天 完整…

MyBatis和MyBatis-plus配置多数据源和操作多数据库

一&#xff0c;学习MyBatis和MyBatis-plus&#xff1a; mybatis:官网文档:mybatis – MyBatis 3 | 简介 mybatis-plus:官网文档&#xff1a;MyBatis-Plus 二&#xff0c;MyBatis来实现多数据源的查询&#xff1a; 配置文件的格式&#xff1a; spring:datasource: db1:driv…

【Hystrix技术指南】(4)故障切换的运作流程

[每日一句] 也许你度过了很糟糕的一天&#xff0c;但这并不代表你会因此度过糟糕的一生。 [背景介绍] 分布式系统的规模和复杂度不断增加&#xff0c;随着而来的是对分布式系统可用性的要求越来越高。在各种高可用设计模式中&#xff0c;【熔断、隔离、降级、限流】是经常被使…

代码随想录算法训练营day60

文章目录 Day60 柱状图中最大的矩形题目思路代码 Day60 柱状图中最大的矩形 84. 柱状图中最大的矩形 - 力扣&#xff08;LeetCode&#xff09; 题目 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图…

模拟实现消息队列项目(系列5) -- 服务器模块(虚拟主机)

目录 前言 1. 创建VirtualHost 1.1 定义虚拟主机的相关属性 1.2 VirtualHost 构造方法 1.3 交换机和队列的创建和删除 1.3.1 交换机操作 1.3.2 队列操作 1.4 绑定的创建和删除 1.5 发送消息到指定的队列/交换机 2. 实现路由规则Router 2.1 checkBindingKey() 2.2 checkRoutin…

【Spring Boot】Spring Boot项目的创建和文件配置

目录 一、为什么要学Spring Boot 1、Spring Boot的优点 二、创建Spring Boot项目 1、创建项目之前的准备工作 2、创建Spring Boot项目 3、项目目录的介绍 4、安装Spring Boot快速添加依赖的插件 5、在项目中写一个helloworld 三、Spring Boot的配置文件 1、配置文件的…

TCP/IP四层模型对比OSI七层网络模型的区别是啥?数据传输过程原来是这样的

一、TCP/IP四层模型对比OSI七层模型 它们两个定义的一些功能和协议都是差不多的。TCP/IP四层协议模型比我们的七层少了三层&#xff0c;把我们的数据链路层和物理层放在一层里面了&#xff0c;叫做数据链路层&#xff08;网络接口层&#xff09;&#xff0c;对应网络协议也没有…

本质安全设备标准(IEC60079-11)的理解(六)温度

本质安全设备标准&#xff08;IEC60079-11&#xff09;的理解&#xff08;六&#xff09;温度 本质安全设备的温度要求也是非常复杂的&#xff0c;首先在标准中涉及有3个温度的概念&#xff1a; 环境温度ambient temperature&#xff0c; 工作温度service temperature和最高表…

【Docker】数据库动态授权组件在Kubernetes集群下的测试过程记录

目录 背景 组件原理 测试设计 环境 测试脚本 脚本build为linux可执行文件 镜像构建 Dockerfile Docker build 镜像有效性验证 总结 资料获取方法 背景 我们都知道出于安全性考虑&#xff0c;生产环境的权限一般都是要做最小化控制&#xff0c;尤其是数据库的操作授…

【MFC】05.MFC第一大机制:程序启动机制-笔记

MFC程序开发所谓是非常简单&#xff0c;但是对于我们逆向人员来说&#xff0c;如果想要逆向MFC程序&#xff0c;那么我们就必须了解它背后的机制&#xff0c;这样我们才能够清晰地逆向出MFC程序&#xff0c;今天这篇文章就来带领大家了解MFC的第一大机制&#xff1a;程序启动机…

STM32 低功耗学习

STM32 电源系统结构介绍 电源系统&#xff1a;VDDA供电区域、VDD供电区域、1.8V供电区域、后备供电区域。 器件的工作电压&#xff08;VDD&#xff09;2.0~3.6V 为了提高转换精度&#xff0c;给模拟外设独立供电。电压调节器为1.8V供电区域供电&#xff0c;且1.8V供电区域是电…

Snapdrop手机电脑互传-无需下载App

软件介绍 Snapdrop&#xff1a;浏览器中的本地文件共享。灵感来自苹果的空投。 软件访问地址&#xff1a; Snapdrop官网地址 软件开源地址&#xff1a; github 软件截图

【自然语言处理】大模型高效微调:PEFT 使用案例

文章目录 一、PEFT介绍二、PEFT 使用2.1 PeftConfig2.2 PeftModel2.3 保存和加载模型 三、PEFT支持任务3.1 Models support matrix3.1.1 Causal Language Modeling3.1.2 Conditional Generation3.1.3 Sequence Classification3.1.4 Token Classification3.1.5 Text-to-Image Ge…

docker 安装hive

记录一下使用docker快速搭建部署hive环境 目录 写在前面 步骤 安装docker 安装docker安装docker-compose配置docker国内镜像源&#xff08;可选&#xff09; 安装git & 配置github部署Hive docker-hive开始部署 使用Hive命令行收尾工作 安装vi、lrzsz关闭相关命令 END…

NodeJS 个性化音乐推荐系统 毕业设-附源码00485

摘要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作规…

分布式问题

1. 分布式系统CAP原理 CAP原理&#xff1a;指在一个分布式系统中&#xff0c;Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;、Partitontolerance&#xff08;分区容忍性&#xff09;&#xff0c;三者不可得兼。 一致性&#xff08;C…