当前位置: 首页 > news >正文

stm32和python串口数据收发

1-1 串口发送端(stm32)

1字符串发送

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{/* Check the parameters */assert_param(IS_USART_ALL_PERIPH(USARTx));assert_param(IS_USART_DATA(Data)); /* Transmit Data */USARTx->DR = (Data & (uint16_t)0x01FF);
}
/*****************  发送一个字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{/* 发送一个字节数据到USART */USART_SendData(pUSARTx,ch);/* 等待发送数据寄存器为空 */while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{unsigned int k=0;do {Usart_SendByte( pUSARTx, *(str + k) );k++;} while(*(str + k)!='\0');/* 等待发送完成 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET){}
}
/************状态:电机速度、位置和角位移传感器的速度、位置*****************/	 #define LPF(x, f, c) (c*x + (1-c)*f)  // 滤波motor_position = Read_Encoder_Angle(Encoder);sensor_position = Get_Adc_Average_Angle(Adc);motor_velocity = Read_Encoder_Speed(Encoder);sensor_velocity = Get_Adc_Average_Speed();pc_fil = LPF(motor_position, pc_fil,0.2f); vc_fil = LPF(motor_velocity, vc_fil,0.2f);ec_fil = LPF(sensor_position,ec_fil,0.2f);wc_fil = LPF(sensor_velocity,wc_fil,0.2f);/************** 串口发送数据方式一:使用字符串传输数据(整型和浮点型) **********************/				 sprintf(data_str, "%-8.4f, %-8.4f, %-8.4f, %-8.4f\n", pc_fil, ec_fil, vc_fil, wc_fil);Usart_SendString(USART1, data_str);

2 16进制传输(整型)

/************** 串口发送数据方式二:传输数据打包-16进制传输(整型) **********************/	
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{/* Check the parameters */assert_param(IS_USART_ALL_PERIPH(USARTx));assert_param(IS_USART_DATA(Data)); /* Transmit Data */USARTx->DR = (Data & (uint16_t)0x01FF);
}uint8_t data_array[10];data_array[0] =  0x12;  // 帧头1data_array[1] =  0x34;  // 帧头2data_array[2] = (int)Encoder & 0xFF;         // 编码器低8位data_array[3] = ((int)Encoder >> 8) & 0xFF;  // 编码器高8位data_array[4] = (int)Adc & 0xFF;             // 编码器低8位data_array[5] = ((int)Adc >> 8) & 0xFF;      // 编码器低8位data_array[6] =  0x56;  // 帧尾1data_array[7] =  0x78;  // 帧尾2for(uint8_t  i = 0 ; i < 8; i++){USART_SendData(USART1, *(data_array + i));while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  }

3 16进制传输(整型和浮点型)

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{/* Check the parameters */assert_param(IS_USART_ALL_PERIPH(USARTx));assert_param(IS_USART_DATA(Data)); /* Transmit Data */USARTx->DR = (Data & (uint16_t)0x01FF);
}
/************** 串口发送数据方式三: 串口传输数据打包-16进制传输(整型和浮点型) **********************/		//函数功能:将一个浮点数转换为字节数组   倒序  大小端的问题
//入口参数:浮点数   字节数组
void FloatToByte(float floatNum, unsigned char* byteArry) {char* pchar = (char*)&floatNum;for (int i = 0; i < sizeof(float); i++) {*byteArry = *pchar;pchar++;byteArry++;}
}FloatToByte(motor_velocity, byteArry); // 8个字节数据data_array[0] =  0x12;  // 帧头1data_array[1] =  0x34;  // 帧头2data_array[2] = (int)motor_position & 0xFF;          // 电机位置低字节data_array[3] = ((int)motor_position >> 8) & 0xFF;   // 电机位置高字节/*电机速度为浮点型数据,将其十进制数转换为单精度浮点数是4个字节(32位),转换网站:http://www.styb.cn/cms/ieee_754.php*/data_array[4] = byteArry[0];	// 单精度浮点数第4个字节							data_array[5] = byteArry[1];	// 单精度浮点数第3个字节			 	data_array[6] = byteArry[2];	// 单精度浮点数第2个字节							data_array[7] = byteArry[3];	// 单精度浮点数第1个字节				data_array[8] =  0x56;  // 帧尾1data_array[9] =  0x78;  // 帧尾2for(uint8_t  i = 0 ; i < sizeof(data_array); i++) // 一个字节一个字节发送数据{USART_SendData(USART1, *(data_array + i));while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  // 注意:此句是为防止数据还来不及发送,数据就被后面来的数据覆盖;等待发送完后继续发送下一个数据,没有过多的等待。}

4 仅发送浮点型小数

/**************串口发送数据方式四: 仅发送浮点型小数 **********************/
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{/* Check the parameters */assert_param(IS_USART_ALL_PERIPH(USARTx));assert_param(IS_USART_DATA(Data)); /* Transmit Data */USARTx->DR = (Data & (uint16_t)0x01FF);
}//函数功能:将一个浮点数转换为字节数组   倒序  大小端的问题
//入口参数:浮点数   字节数组
void FloatToByte(float floatNum, unsigned char* byteArry) {char* pchar = (char*)&floatNum;for (int i = 0; i < sizeof(float); i++) {*byteArry = *pchar;pchar++;byteArry++;}
}
FloatToByte(motor_velocity, byteArry); // 8个字节数据
for(uint8_t  i = 0 ; i < sizeof(float); i++) // 一个字节一个字节发送数据
{USART_SendData(USART1, *(byteArry + i));while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); // 注意:此句是为防止数据还来不及发送,数据就被后面来的数据覆盖;等待发送完后继续发送下一个数据,没有过多的等待。
}

1-2 串口接收端-python

接收数据:编码器(整型)、角位移传感器(整型)[对应1-1中的2]

# 从串口接收的数据为:编码器(整型)、角位移传感器(整型)
def read_serial_one_data_encoder_adc(ser):global receive_resultBUF_SIZE = 8buf = bytearray([0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x56, 0x78])c1 = ib = flag = 0while True:R = ser.read(1)# print("data", R)if R == b'':print("Read Fail")ser.close()breakc = int.from_bytes(R, byteorder='big') # 将接收的十六进制数转换为整数;注意,接收的十六进制会进行自动转换,如0x56是十六进制表示法,表示的是十进制数值86。而V是英文字母,它在ASCII码中的十进制表示是86。所以,0x56和V表示的是同一个字符。串口接收时会将0x56转化成V,它们实际上是同一个字符。if flag > 0:if ib < BUF_SIZE: # 位置标记ib要小于缓冲数组的最大值buf[ib] = c   # 将接收的数据保存在缓冲数组当中ib += 1       # 位置+1if ib == 8: # 如果当前位置为8,则说明数据缓冲区已满if buf[6] == 0x56 and buf[7] == 0x78: # 判断帧尾1和2是否满足规定值Encoder = (buf[3] << 8) + buf[2]  # 进行位操作。注意:buf[2]和buf[3]实际为十进制的数值,当进行位操作时,系统自动将其转换为十六进制进行位操作,最后结果仍为十进制数Adc= (buf[5] << 8) + buf[4]receive_result = [Encoder, Adc]  # 返回接收结果breakelse:print("CRC Fail")flag = 0if flag == 0:if c1 == 0x12 and c == 0x34: # 判断:是否接收到的帧头1和帧头2,且帧头1和2是否连续(帧头1在帧头2前面),若满足条件则开始接收flag = 1 # 接收数据标志位ib = 2   # 标记数据缓冲数据从第3位开始,即下标为2c1 = creturn receive_result  # 返回接收到的结果

接收数据:编码器(整型)、角位移传感器(浮点型)[对应1-1中的3]

# 函数功能:将一个字节数组转换为浮点数
# 入口参数:  字节数组
def Byte2Float(byteArry):floatNum = struct.unpack('f', byteArry)[0]return floatNum# 从串口接收的数据为:电机位置(整型)、电机速度(浮点型)
def read_serial_one_data_motor_position_velocity(ser):global receive_resultBUF_SIZE = 10buf = bytearray([0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x78]) # 定义一个字节数组,用于将数据打包,进行串口传输c1 = c2 = ib = flag = 0while True:R = ser.read(1) # 从串口接收一个字节if R == b'':print("Read Fail")ser.close()breakc = int.from_bytes(R, byteorder='big') # 将接收的十六进制数转换为整数;注意,接收的十六进制会进行自动转换,如0x56是十六进制表示法,表示的是十进制数值86。而V是英文字母,它在ASCII码中的十进制表示是86。所以,0x56和V表示的是同一个字符。串口接收时会将0x56转化成V,它们实际上是同一个字符。if flag > 0:if ib < BUF_SIZE: # 位置标记ib要小于缓冲数组的最大值buf[ib] = c   # 将接收的数据保存在缓冲数组当中ib += 1       # 位置+1if ib == 10:       # 如果当前位置为10,则说明数据缓冲区已满if buf[8] == 0x56 and buf[9] == 0x78:motor_position = (buf[3] << 8) + buf[2]motor_veclocity = Byte2Float(buf[4:8])receive_result = [motor_position, motor_veclocity]breakelse:print("CRC Fail")flag = 0if flag == 0:if c1 == 0x12 and c == 0x34:# 判断:是否接收到的帧头1和帧头2,且帧头1和2是否连续(帧头1在帧头2前面),若满足条件则开始接收flag = 1  # 接收数据标志位ib = 2    # 标记数据缓冲数据从第3位开始,即下标为2c1 = creturn receive_result  # 返回接收到的结果

2-1 串口发送端python

action = bytearray([0x12, 0x34, 0x00, 0x00, 0x00, 0x56, 0x78])
action_ = int(control_motor(result[0], result[1]))
print("action_", action_)
# 将action转化成字符串
action[0] = 0x2D   # 帧头
action[1] = 0x01   # 校验位,具体未实现,用0x01替代
if action_ < 0:action[2] = 0x45   # 符号位action[3] = action_  & 0xFF    # 数据位action[4] = (action_ >>8) & 0xFF  # 数据位action[5] = 0x0d   # 0x56是十六进制表示法,表示的是十进制数值86。而V是英文字母,它在ASCII码中的十进制表示是86。所以,0x56和V表示的是同一个字符。action[6] = 0x0a   # 0x78是十六进制表示法,表示的是十进制数值120。而x是英文字母,它在ASCII码中的十进制表示是120。所以,0x78和x表示的是同一个字符。for byte in action: # 一个一个字节发送 ,一次发送多个字节容易出错ser.write(byte.to_bytes(1, 'big'))

2-2 串口接收端stm32

void USART1_IRQHandler(void)                	//串口1中断服务程序{if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res = USART_ReceiveData(USART1);	//读取接收到的数据 0x2D,0x01,0x30,0x30,0x30,0x0D,0x0Aprintf("%02X", Res);if((USART_RX_STA&0x8000)==0)//接收未完成。当接收完成时,最高位会被置为1,表示接收结束。 {if(USART_RX_STA&0x4000)//接收到了0x0D,开始执行以下代码。USART_RX_STA&0x4000判断USART_RX_STA的第14位(bit 14)是否为1。{if(Res!=0x0A){USART_RX_STA=0;//接收错误,重新开始memset(USART_RX_BUF,0,USART_REC_LEN);// 将数据缓冲区清0}else{ //接收到了0x0A,开始执行以下代码USART_RX_STA|=0x8000;	//接收完成了。将 USART_RX_STA 的第15位设置为1。这样做的目的是在接收到完整的数据时,将接收完成标志置为1,以便后续的处理程序可以知道数据已经接收完成,进行后序操作。if(USART_RX_BUF[0] == 0x2D && USART_RX_BUF[1] == 0x01 ) // 判断帧头是否正确、判断奇偶校验位是否正确 || USART_RX_BUF[1] == 0x01(USART_RX_BUF[1]为校验位,此处未定义,使用0x01替代,简化){float value = 0;int16_t sign = 1;  // 符号标记,默认为‘+’if(USART_RX_BUF[2] == 0x45) // USART_RX_BUF[2]为符号位,当其等于0x45,即‘-’,表示其为负数{sign = -1;}value = (USART_RX_BUF[4] << 8) + USART_RX_BUF[3];// 将接收的十六进制数转换为十进制	action = sign * value; // 与符号标记做乘法,等到真实值USART_RX_STA = 0; 	memset(USART_RX_BUF,0,USART_REC_LEN); // 将数据缓冲区清0}else{USART_RX_STA = 0;	memset(USART_RX_BUF,0,USART_REC_LEN);// 将数据缓冲区清0}}								}else //还没收到0X0D{	if(Res==0x0D)USART_RX_STA|=0x4000; //当接收缓冲区溢出时,第14位会被置为1,表示接收缓冲区已满。|0x4000 = 0100 0000 0000 0000else{					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res; // 将接收到的值存放在数据缓冲区中,和0X3FFF(16383)进行与运算。这样做的目的是将索引值限制在0到16383之间,避免超出数组的范围。USART_RX_STA++; // 一个16位的无符号整数变量,用于接收数据的状态变量。// USART_RX_STA 的第15位通常用于表示接收完成标志。if(USART_RX_STA>(USART_REC_LEN-1)) // 接收数据的状态变量USART_RX_STA > 串口接收长度USART_REC_LEN时,则接收数据错误,重新开始接收{USART_RX_STA=0;//接收数据的状态变量归0memset(USART_RX_BUF,0,USART_REC_LEN); // 清空接收数据缓冲区USART_RX_BUF}					}		 }}} 
}

调试过程中的问题总结

1、串口传输数据需按字节传输,不可一次性发送多个字节,如下所示:

action = bytearray([0x12, 0x34, 0x31, 0x32, 0x00, 0x56, 0x78])
ser.write(action )

在实际调试过程中,因为数据还来不及发送,数据就被后面来的数据覆盖了,导致实际接收的结果为0x12, 0x34,或0x12, 0x34, 0x32, 0x78。总之数据不完整。
因此改为每次发送一个字节,如下所示:

action = bytearray([0x12, 0x34, 0x31, 0x32, 0x00, 0x56, 0x78])
for byte in action: ser.write(byte.to_bytes(1, 'big'))

2、串口接收数据丢失,如发送固定数据为6900,偶尔会跳变为244或1等其他数据
经排查,此类情况为波特率设置过低导致的,将波特率设为较大值可解决此类情况。

相关文章:

stm32和python串口数据收发

1-1 串口发送端&#xff08;stm32&#xff09; 1字符串发送 void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) {/* Check the parameters */assert_param(IS_USART_ALL_PERIPH(USARTx));assert_param(IS_USART_DATA(Data)); /* Transmit Data */USARTx->DR (D…...

无涯教程-jQuery - Dropable移动函数

Drop-able 功能可与JqueryUI中的交互一起使用。此功能可在任何DOM元素上启用可放置功能。 Drop able - 语法 $( "#droppable" ).droppable(); Drop able - 示例 以下是一个简单的示例&#xff0c;显示了drop-able的用法- <html><head><title>…...

【Python】Web学习笔记_flask(4)——钩子函数

钩子函数可以用来注册在请求处理的不同阶段执行出 Flask的请求钩子指的是在执行视图函数前后执行的一些函数&#xff0c; 之前是有4种&#xff0c;但是 before_first_request已经被删除了&#xff0c;使用时会报错 before_request&#xff1a;在每次请求前执行&#xff0c;…...

JavaScript 原型链解析,宏任务和微任务

目录 什么是原型链&#xff1f; 原型与构造函数 原型链的工作原理 实例&#xff1a;理解原型链 宏任务&#xff08;Macro Task&#xff09; 微任务&#xff08;Micro Task&#xff09; 什么是原型链&#xff1f; JavaScript 是一门基于原型的语言&#xff0c;而原型链是…...

05|Oracle学习(UNIQUE约束)

1. UNIQUE约束介绍 也叫&#xff1a;唯一键约束&#xff0c;用于限定数据表中字段值的唯一性。 1.1 UNIQUE和primary key区别&#xff1a; 主键/联合主键每张表中只有一个。UNIQUE约束可以在一张表中&#xff0c;多个字段中存在。例如&#xff1a;学生的电话、身份证号都是…...

glide加载content://com.android.contacts图片源码粗略梳理

获取链路是这样的&#xff1b; UriLoader类里定义了协议头&#xff1a; 里面有个内部类StreamFactory&#xff1a; 通过StreamLocalUriFetcher类的loadResource方法获取InputStream然后把流转换成为图片&#xff1b; 在这里作个草稿笔记给自己看...

【机器学习】Feature Engineering and Polynomial Regression

Feature Engineering and Polynomial Regression 1. 多项式特征2. 选择特征3. 缩放特征4. 复杂函数附录 首先&#xff0c;导入所需的库&#xff1a; import numpy as np import matplotlib.pyplot as plt from lab_utils_multi import zscore_normalize_features, run_gradien…...

Rust- 变量绑定

In Rust, you bind values to a variable name using the let keyword. This is often referred to as “variable binding” because it’s like binding a name to a value. Here’s a simple example: let x 5;In this example, x is bound to the value 5. By default, …...

向“数”而“深”,联想凌拓的“破局求变”底气何来?

前言&#xff1a;要赢得更多机遇&#xff0c;“破局求变”尤为重要。 【全球存储观察 &#xff5c; 热点关注】2019年2月25日&#xff0c;承袭联想集团与NetApp的“双基因”&#xff0c;联想凌拓正式成立。历经四年多的发展&#xff0c;联想凌拓已成为中国企业级数据管理领域的…...

pytorch实战-图像分类(二)(模型训练及验证)(基于迁移学习(理解+代码))

目录 1.迁移学习概念 2.数据预处理 3.训练模型&#xff08;基于迁移学习&#xff09; 3.1选择网络&#xff0c;这里用resnet 3.2如果用GPU训练&#xff0c;需要加入以下代码 3.3卷积层冻结模块 3.4加载resnet152模 3.5解释initialize_model函数 3.6迁移学习网络搭建 3.…...

b 树和 b+树的理解

项目场景&#xff1a; 图灵奖获得者&#xff08;Niklaus Wirth &#xff09;说过&#xff1a; 程序 数据结构 算法&#xff0c; 也就说我们无时无刻 都在和数据结构打交道。 只是作为 Java 开发&#xff0c;由于技术体系的成熟度较高&#xff0c;使得大部分人认为&#xff1…...

正则表达式 —— Awk

Awk awk&#xff1a;文本三剑客之一&#xff0c;是功能最强大的文本工具 awk也是按行来进行操作&#xff0c;对行操作完之后&#xff0c;可以根据指定命令来对行取列 awk的分隔符&#xff0c;默认分隔符是空格或tab键&#xff0c;多个空格会压缩成一个 awk的用法 awk的格式…...

国芯新作 | 四核Cortex-A53@1.4GHz,仅168元起?含税?哇!!!

创龙科技SOM-TLT507是一款基于全志科技T507-H处理器设计的4核ARM Cortex-A53全国产工业核心板&#xff0c;主频高达1.416GHz。核心板CPU、ROM、RAM、电源、晶振等所有元器件均采用国产工业级方案&#xff0c;国产化率100%。 核心板通过邮票孔连接方式引出MIPI CSI、HDMI OUT、…...

【MyBatis】 框架原理

目录 10.3【MyBatis】 框架原理 10.3.1 【MyBatis】 整体架构 10.3.2 【MyBatis】 运行原理 10.4 【MyBatis】 核心组件的生命周期 10.4.1 SqlSessionFactoryBuilder 10.4.2 SqlSessionFactory 10.4.3 SqlSession 10.4.4 Mapper Instances 与 Hibernate 框架相比&#…...

三、线性工作流

再生产的各个环节&#xff0c;正确使用gamma编码及gamma解码&#xff0c;使得最终得到的颜色数据与最初输入的物理数据一致。如果使用gamma空间的贴图&#xff0c;在传给着色器前需要从gamma空间转到线性空间。 如果不在线性空间下进行渲染&#xff0c;会产生的问题&#xff1a…...

2023华数杯数学建模A题思路 - 隔热材料的结构优化控制研究

# 1 赛题 A 题 隔热材料的结构优化控制研究 新型隔热材料 A 具有优良的隔热特性&#xff0c;在航天、军工、石化、建筑、交通等 高科技领域中有着广泛的应用。 目前&#xff0c;由单根隔热材料 A 纤维编织成的织物&#xff0c;其热导率可以直接测出&#xff1b;但是 单根隔热…...

Zabbix分布式监控Web监控

目录 1 概述2 配置 Web 场景2.1 配置步骤2.2 显示 3 Web 场景步骤3.1 创建新的 Web 场景。3.2 定义场景的步骤3.3 保存配置完成的Web 监控场景。 4 Zabbix-Get的使用 1 概述 您可以使用 Zabbix 对多个网站进行可用性方面监控&#xff1a; 要使用 Web 监控&#xff0c;您需要定…...

PHP从入门到精通—PHP开发入门-PHP概述、PHP开发环境搭建、PHP开发环境搭建、第一个PHP程序、PHP开发流程

每开始学习一门语言&#xff0c;都要了解这门语言和进行开发环境的搭建。同样&#xff0c;学生开始PHP学习之前&#xff0c;首先要了解这门语言的历史、语言优势等内容以及了解开发环境的搭建。 PHP概述 认识PHP PHP最初是由Rasmus Lerdorf于1994年为了维护个人网页而编写的一…...

【LeetCode-中等】722. 删除注释

题目链接 722. 删除注释 标签 字符串 步骤 Step1. 先将source合并为一个字符串进行处理&#xff0c;中间补上’\n’&#xff0c;方便后续确定注释开始、结束位置。 string combined; for (auto str : source) {combined str "\n"; }Step2. 定义数组 toDel&am…...

rust里如何判断字符串是否相等呢?

在 Rust 中&#xff0c;有几种方法可以判断字符串是否相等。下面是其中几种常见的方法&#xff1a; 使用 运算符&#xff1a;可以直接使用 运算符比较两个字符串是否相等。例如&#xff1a; fn main() {let str1 "hello";let str2 "world";if str1 …...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...