STM32 HAL ADC FIR 窗函数实现低通滤波

news2024/11/26 6:20:32

FIR 窗函数实现低通滤波

文章目录

  • FIR 窗函数实现低通滤波
    • 1.窗的分类与选择
    • 2.matlab设计
    • 3.代码编写
    • 4.结果欣赏与群延迟
    • 5.其他可能报错
      • 5.1.adc采集的数据没问题,vofa打印成-nan
      • 5.2.vofa打印的滤波数据为初始化的0
    • 6.代码备忘

1.窗的分类与选择

QQ_1721715560988

QQ_1721716527313

QQ_1721716546768

QQ_1721716565362

QQ_1721832214124

2.matlab设计

QQ_1721893451179

主页命令行输入filterDesiner

QQ_1721893414269

进去后选择FIR,阶数理论上越大越好这里80,窗的选择由第一部分,我们就选择汉宁窗

本次设计我们简单点,将一个200Hz的方波信号滤成正弦,那么截至频率就选择为200,采样率3200足矣。

Fs 采样频率,也就是说在之后你ADC的采样频率也要是这么多

Fc 截止频率,注意汉宁窗的截止频率在-6db点的位置

QQ_1721893690795

生成后留意上方选单,其中有个群延迟响应记一下,我们后面讲

image-20240725160101799

选择生成C 头文件

QQ_1721894495418

变量名自己随便设定,选用单精度浮点型,我们用的是f32函数,对应的就是单精度浮点

QQ_1721894592927

将生成的这段数据复制粘贴到代码中

3.代码编写

cubemx中配置ADC与dma单次采集,tim触发,dsp库导入clion,此处略过不讲,读者可以自行前往笔者过往博客翻看。

QQ_1721894825565

前半部分代码内容,宏定义了一个adc的采样点数,这里的采样点数需要是多于几个周期的,原因后文讲。这里宏定义懒得写那么多了,读者们可以多加,方便移植。

定义了标志位,adc存数据数组,输入fir数组,输出fir数组。

滤波器系数个数注意下比80多一个,fir状态变量暂存的数组长度注意。

块处理大小是后面一次fir处理的数据个数。

/* USER CODE BEGIN PD */
#define AdcNum 256
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint16_t adc_conv =0;//标志位
uint16_t adc_value[AdcNum] = {0};
//输入数据
float32_t inbuf[AdcNum] = {0};
//输出数据
float32_t outbuf[256]=	{0};
uint16_t numTaps=81;//fir滤波器系数个数
//FIR滤波器状态变量暂存:数组的大小=numTaps+blocksize-1
float32_t  pState[336]={0.0f};
//块处理大小
uint32_t blockSize=256;
/* USER CODE END PV */

QQ_1721895067597

之前matlab生成的头文件内容,将real32改成float类型变量,可以看到大量黄色warning,我们无需改成double型变量,改后fir32是不会工作的。

/* USER CODE BEGIN PFP */
float32_t pCoeffs[81] = {
        3.88870479e-19,0.0002536820539,0.0005061632837,0.0007350782398,0.0009042214951,
        0.0009640454082,0.0008594112005,0.0005441915127,-8.159095012e-19,-0.0007456119638,
        -0.001607135055,-0.002440539422,-0.003057639115,-0.003255824093,-0.002859890461,
        -0.001769107184,1.933912083e-18, 0.002285639057, 0.004776827525, 0.007039505057,
        0.008573494852, 0.008895023726, 0.007633602712,  0.00462751044,-3.315839305e-18,
        -0.00580064673,  -0.0120098507, -0.01760983095, -0.02144382522, -0.02236903831,
        -0.01942810044, -0.01201371197,4.433841939e-18,  0.01618272252,  0.03554584458,
        0.05661869422,    0.077596955,  0.09654571861,   0.1116304249,   0.1213437766,
        0.1246964261,   0.1213437766,   0.1116304249,  0.09654571861,    0.077596955,
        0.05661869422,  0.03554584458,  0.01618272252,4.433841939e-18, -0.01201371197,
        -0.01942810044, -0.02236903831, -0.02144382522, -0.01760983095,  -0.0120098507,
        -0.00580064673,-3.315839305e-18,  0.00462751044, 0.007633602712, 0.008895023726,
        0.008573494852, 0.007039505057, 0.004776827525, 0.002285639057,1.933912083e-18,
        -0.001769107184,-0.002859890461,-0.003255824093,-0.003057639115,-0.002440539422,
        -0.001607135055,-0.0007456119638,-8.159095012e-19,0.0005441915127,0.0008594112005,
        0.0009640454082,0.0009042214951,0.0007350782398,0.0005061632837,0.0002536820539,
        3.88870479e-19
};
/* USER CODE END PFP */

接下来是两段函数

/* USER CODE BEGIN 0 */
void adc_start()
{
    HAL_TIM_Base_Start(&htim8);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_value, AdcNum);
    while (!adc_conv);
    adc_conv = 0;
}

void fir_start()
{

    //adc采样值转换为电压值并存入输入数组
    for(int i=0;i<AdcNum;i++)
    {
        inbuf[i]=(float)(adc_value[i]*3.3/4096);
    }


//FIR实例化结构体
    arm_fir_instance_f32 * S;

// 为FIR实例分配内存
    S = (arm_fir_instance_f32 *)malloc(sizeof(arm_fir_instance_f32));
    if (S == NULL)
    {
        // 内存分配失败,处理错误
        return;
    }

    arm_fir_init_f32(S,numTaps,pCoeffs,pState,blockSize);
    arm_fir_f32(S,inbuf,outbuf,blockSize);

    free(S);      // 释放内存
    S = NULL; // 将指针设置为 NULL,以避免悬挂指针

    for (int j = 0; j < AdcNum; ++j) {
        printf("%d,%f,%f\n",j,outbuf[j],inbuf[j]);
    }
}
/* USER CODE END 0 */

QQ_1721895321516

QQ_1721895335471

adc_start函数没啥好讲的

fir_start中,我们先将adc采样的数据转换成电压值存到一个数组中

初始化arm_fir_instance_f32结构体并为它分配内存(重要!!!)

实测,如果不给它分配内存那fir不跑,看其他例程没分配照样好好运行,不知何解。

释放掉结构体内存,然后打印数据

4.结果欣赏与群延迟

打印到vofa

QQ_1721896038028

会发现前几个周期的波形fir是衰减的

问AI

QQ_1721896151056

看看安富莱

QQ_1721896110323

照应前文,读者可以翻上去看下群延迟的点是40,所以说我们的采样点数需要多一点,否则波形还没正常fir就结束了

QQ_1721896226784

确实差不多

5.其他可能报错

5.1.adc采集的数据没问题,vofa打印成-nan

-nan意为not a number,很可能是将matlab生成的系数转换为double型了

5.2.vofa打印的滤波数据为初始化的0

没有为结构体分配内存

6.代码备忘

/**
  ******************************************************************************
  * @file           : dsp.h
  * @author         : Silencecmsj
  * @brief          : None
  * @attention      : None
  * @date           : 2024/7/26
  ******************************************************************************
  *                             _ooOoo_
  *                            o8888888o
  *                            88" . "88
  *                            (| -_- |)
  *                            O\  =  /O
  *                         ____/`---'\____
  *                       .'  \\|     |//  `.
  *                      /  \\|||  :  |||//  \
  *                     /  _||||| -:- |||||-  \
  *                     |   | \\\  -  /// |   |
  *                     | \_|  ''\---/''  |   |
  *                     \  .-\__  `-`  ___/-. /
  *                   ___`. .'  /--.--\  `. . __
  *                ."" '<  `.___\_<|>_/___.'  >'"".
  *               | | :  `- \`.;`\ _ /`;.`/ - ` : | |
  *               \  \ `-.   \_ __\ /__ _/   .-` /  /
  *          ======`-.____`-.___\_____/___.-`____.-'======
  *            /**
  ******************************************************************************
  * @file           : fir.h
  * @author         : Silencecmsj
  * @brief          : None
  * @attention      : None
  * @date           : 2024/7/26
  ******************************************************************************
  *                             _ooOoo_
  *                            o8888888o
  *                            88" . "88
  *                            (| -_- |)
  *                            O\  =  /O
  *                         ____/`---'\____
  *                       .'  \\|     |//  `.
  *                      /  \\|||  :  |||//  \
  *                     /  _||||| -:- |||||-  \
  *                     |   | \\\  -  /// |   |
  *                     | \_|  ''\---/''  |   |
  *                     \  .-\__  `-`  ___/-. /
  *                   ___`. .'  /--.--\  `. . __
  *                ."" '<  `.___\_<|>_/___.'  >'"".
  *               | | :  `- \`.;`\ _ /`;.`/ - ` : | |
  *               \  \ `-.   \_ __\ /__ _/   .-` /  /
  *          ======`-.____`-.___\_____/___.-`____.-'======
  *                             `=---='
  *          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ******************************************************************************
  */

#ifndef FIR_TEST_FIR_H
#define FIR_TEST_FIR_H


#include "arm_math.h"
#include "stdlib.h"

/**
 * @brief FIR filter configuration structure
 *
 * @param numTaps   滤波器系数个数
 * @param pCoeffs   指向滤波器系数数组的指针
 * @param blockSize 每次处理大小
 * @param S         ARM FIR filter instance
 * @param inbuf     滤波输入数据,注意float型,为电压值,长度为blocksize
 * @param outbuf    滤波输出数据,长度为blocksize
 *
 * @note            请在主函数中提前设置好各种参数,仅支持一次性处理完毕
 */
typedef struct
{
    uint16_t numTaps;          // 滤波器系数个数
    float32_t *pCoeffs;        // 指向滤波器系数数组的指针
    uint16_t blockSize;        // 块处理大小
    arm_fir_instance_f32 *S;   // ARM FIR filter instance
    float32_t *inbuf;          // 输入数组指针
    float32_t *outbuf;         // 输出数组指针
} FIR_Config;


/**
 * @brief FFT configuration structure
 *
 * @param fftLength FFT 长度,应该为2的倍数
 * @param pInputBuf 指向输入数组的指针,注意长度应该是fftlength
 * @param pOutputBuf 指向输出缓冲区的指针,注意长度是fftlength+1
 * @param S ARM CFFT 实例
 */
typedef struct
{
    uint16_t fftLength;        // FFT 长度
    float32_t *pInputBuf;      // 指向输入缓冲区的指针
    float32_t *pOutputBuf;     // 指向输出缓冲区的指针
    arm_cfft_radix4_instance_f32 *S; // ARM CFFT 实例
}FFT_Config;


void adc_V_value(uint16_t adc_value[], float32_t adc_V[], uint16_t size,uint8_t adc_bit);//将ADC值转换为电压值
void fir(FIR_Config *config);//fir滤波函数
void fft(FFT_Config *config);//fft函数
#endif //FIR_TEST_FIR_H
/**
  ******************************************************************************
  * @file           : dsp.c
  * @author         : Silencecmsj
  * @brief          : None
  * @attention      : 使用前注意在主函数中提前将各种需要的参数设置好
  * @date           : 2024/7/26
  ******************************************************************************
  *                             _ooOoo_
  *                            o8888888o
  *                            88" . "88
  *                            (| -_- |)
  *                            O\  =  /O
  *                         ____/`---'\____
  *                       .'  \\|     |//  `.
  *                      /  \\|||  :  |||//  \
  *                     /  _||||| -:- |||||-  \
  *                     |   | \\\  -  /// |   |
  *                     | \_|  ''\---/''  |   |
  *                     \  .-\__  `-`  ___/-. /
  *                   ___`. .'  /--.--\  `. . __
  *                ."" '<  `.___\_<|>_/___.'  >'"".
  *               | | :  `- \`.;`\ _ /`;.`/ - ` : | |
  *               \  \ `-.   \_ __\ /__ _/   .-` /  /
  *          ======`-.____`-.___\_____/___.-`____.-'======
  *                             `=---='
  *          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ******************************************************************************
  */

#include "dsp.h"


/**
 * @brief 将ADC值转换为电压值
 * @param adc_value adc实际采集到的数组
 * @param adc_V adc转换后的电压值
 * @param size 要转换的数组长度
 * @param adc_bit adc位数
 *
 * @note 此处为节省单片机计算空间,直接给出对应位数的长度,因此暂时只支持8、10、12、14、16位的ADC
 */
void adc_V_value(uint16_t adc_value[], float32_t adc_V[], uint16_t size ,uint8_t adc_bit)//将ADC值转换为电压值
{
    if (adc_bit == 12)
    {
        for (int i = 0; i < size; i++)
        {
            adc_V[i] = (float32_t)(adc_value[i] * 3.3 / 4096);
        }
    }
    else if (adc_bit == 14)
    {
        for (int i = 0; i < size; i++)
        {
            adc_V[i] = (float32_t)(adc_value[i] * 3.3 / 16384);
        }
    }
    else if (adc_bit == 16)
    {
        for (int i = 0; i < size; i++)
        {
            adc_V[i] = (float32_t)(adc_value[i] * 3.3 / 65536);
        }
    }
    else if (adc_bit == 10)
    {
        for (int i = 0; i < size; i++)
        {
            adc_V[i] = (float32_t)(adc_value[i] * 3.3 / 1024);
        }
    }
    else if (adc_bit == 8)
    {
        for (int i = 0; i < size; i++)
        {
            adc_V[i] = (float32_t)(adc_value[i] * 3.3 / 256);
        }
    }

}


/**
 * @brief fir滤波函数
 * @param config fir结构体参数
 * @note  numTaps-1必须是4的倍数;
 *
 * @note  例子:主函数中,宏定义numTaps、blockSize,定义pCoeffs,定义结构体,调用fir函数
 */
void fir(FIR_Config *config)
{
    // Allocate memory for the state buffer
    float32_t *pState = malloc((config->numTaps + config->blockSize - 1) * sizeof(float32_t));
    if (pState == NULL)
    {
        // Handle error
        return;
    }

    // Allocate memory for the filter instance
    config->S = (arm_fir_instance_f32 *)malloc(sizeof(arm_fir_instance_f32));
    if (config->S == NULL)
    {
        free(pState);
        return;
    }

    // Initialize the filter
    arm_fir_init_f32((config->S), config->numTaps, config->pCoeffs, pState, config->blockSize);

    // Process the input buffer
    arm_fir_f32((config->S), config->inbuf, config->outbuf, config->blockSize);

    // Free allocated memory
    free(pState);
    free(config->S);
    config->S = NULL; // Avoid dangling pointer
}



/**
 * @brief FFT函数
 * @param config FFT结构体参数
 */
void fft(FFT_Config *config)
{
    // Allocate memory for the FFT instance
    config->S = (arm_cfft_radix4_instance_f32 *)malloc(sizeof(arm_cfft_radix4_instance_f32));
    if (config->S == NULL)
    {
        // Handle error
        return;
    }

    float32_t *fft_inputbuf = malloc(config->fftLength * 2 * sizeof(float32_t));
    if (fft_inputbuf == NULL)
    {

        return;
    }

    // Initialize the FFT
    arm_cfft_radix4_init_f32(config->S, config->fftLength, 0, 1);

    // Initialize the input buffer
    for (int i = 0; i < config->fftLength; i++)
    {
        fft_inputbuf[i * 2] = config->pInputBuf[i];//adc采集到的实际的电压值

        fft_inputbuf[i * 2 + 1] = 0;//涉及到fft原理实部也就是上一条有值,本项为虚部,置0。
    }

    // Perform the CFFT
    arm_cfft_radix4_f32(config->S, fft_inputbuf);

    // Calculate the magnitude spectrum
    arm_cmplx_mag_f32(fft_inputbuf, config->pOutputBuf, config->fftLength / 2 + 1);


    config->pOutputBuf[0] /= (float32_t )config->fftLength;
    for (int j = 1; j < config->fftLength+1; ++j)
    {
        config->pOutputBuf[j] = 2 * config->pOutputBuf[j] / (float32_t )config->fftLength;

    }

    // Free allocated memory
    free(config->S);
    config->S = NULL; // Avoid dangling pointe

    // Free the input buffer memory
    free(fft_inputbuf);
    config->pInputBuf = NULL; // Avoid dangling pointer

}

理论高度决定实践高度。

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

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

相关文章

例程学习(学习笔记)

project括号里面表示工程的名称&#xff0c;决定了最后生成的bin文件的名称&#xff0c;比如我们现在编译后的bin文件名称就是hello_world.bin文件&#xff0c;如果改成了project(xxx)&#xff0c;编译后的名称就是xxx.bin 这个文件用来设置路径&#xff0c;咱们得例程案例里面…

uniapp:上拉加载更多、下拉刷新、页面滚动到指定位置

提醒 本文实例是使用uniapp进行开发演示的。 一、需求场景 在开发商品&#xff08;SKU&#xff09;列表页面时&#xff0c;通常有三个需求&#xff1a; 页面下拉刷新&#xff0c;第一页展示最新数据&#xff1b;上拉加载更多数据&#xff1b;列表页面可以滚动到指定位置&#x…

5G在汽车零部件行业的应用

5G技术在汽车零部件行业的应用正在不断深入&#xff0c;为行业的智能化、自动化和高效化转型提供了强大的技术支持。 1、5G技术特点与优势 5G技术具有高速度、低延迟、大连接和切片技术等特点与优势。这些特性为汽车零部件行业提供了稳定、可靠、高效的通信连接&#xff0c;使…

jmeter的基本使用

Jmeter基本使用 一、变量 1.用户定义变量 2.用户参数 二、函数 1.计数器${__counter(,)} 2.时间函数 3.加密函数${__digest(,,,,)} 4. 整数相加${__intSum(,,)} 5.属性函数&#xff0c;${__P(,)}、${__property(,,)}、${__setProperty(,,)} 6.V函数 三、获取响应数据…

算法的学习笔记—和为 S 的连续正数序列(牛客JZ74)

&#x1f600;前言 在牛客网的《剑指 Offer》系列题中&#xff0c;有一道关于输出和为给定值 S 的连续正数序列的问题。这是一道典型的双指针问题&#xff0c;考察我们对连续数列求和的理解和双指针的应用。本文将详细解析这道题的思路&#xff0c;并展示如何实现代码。 &#…

D53【python 接口自动化学习】- python基础之模块与标准库

day53 自定义模块 学习日期&#xff1a;20241030 学习目标&#xff1a;模块与标准库 -- 67 自定义模块&#xff1a;如何编写一个完整功能&#xff1f; 学习笔记&#xff1a; 创建自定义模块 自定义模块注意事项 自定义模块 def func1():return this is a functionclass Cl…

上市公司企业数字金融认知数据集(2001-2023年)

一、测算方式&#xff1a;参考C刊《经济学家》王诗卉&#xff08;2021&#xff09;老师的做法&#xff0c;数字金融认知使用每万字年报描述中包含的对数字金融相关关键词的提及次数&#xff0c;关键词为&#xff1a;互联网、数字化、智能、大数据、电子银行、金融科技、科技金融…

4.2-7 运行MR应用:词频统计

文章目录 1. 准备数据文件2. 文件上传到HDFS指定目录2.1 创建HDFS目录2.2 上传文件到HDFS2.3 查看上传的文件 3. 运行词频统计程序的jar包3.1 查看Hadoop自带示例jar包3.2 运行示例jar包里的词频统计 4. 查看词频统计结果5. 在HDFS集群UI界面查看结果文件6. 在YARN集群UI界面查…

How to Train Neural Networks for Flare Removal

Abstract 当相机指向强光源时&#xff0c;生成的照片可能包含镜头眩光伪影。 耀斑以多种形式出现&#xff08;光晕、条纹、渗色、雾霾等&#xff09;&#xff0c;这种外观的多样性使得去除耀斑变得具有挑战性。 现有的分析解决方案对伪影的几何形状或亮度做出了强有力的假设&a…

Kafka如何控制消费的位置?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka如何控制消费的位置?】面试题&#xff1f;希望对大家有帮助&#xff1b; Kafka如何控制消费的位置? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Kafka 中&#xff0c;控制消费位置主要通过以下几个机制来实…

shell脚本实例(4)while实现1+...+100,linux新增用户

while实现1到100求和 #!/bin/bash/ s0 i1 #-le小于等于 while [ $i -le 100 ] dos$[ $s$i ]i$[ $i1 ] done echo $s echo $i 执行结果如下 修改用户名密码脚本 #!/bin/bash/ #提示用户输入用户名 read -p "请输入用户名&#xff1a;"username useradd $username #提…

Qt 实战(10)模型视图 | 10.5、代理

文章目录 一、代理1、简介2、自定义代理 前言&#xff1a; 在Qt的模型/视图&#xff08;Model/View&#xff09;框架中&#xff0c;代理&#xff08;Delegate&#xff09;是一个非常重要的概念。它充当了模型和视图之间的桥梁&#xff0c;负责数据的显示和编辑。代理可以自定义…

lenovo联想小新 潮7000-14AST(81GE)笔记本原厂Win10系统镜像安装包下载

适用机型&#xff1a;【81GE】 链接&#xff1a;https://pan.baidu.com/s/1ciGya7OjTN73rHFJs52WpQ?pwdkgk4 提取码&#xff1a;kgk4 联想原装出厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、联想电脑管家、联想浏览器…

C语言部分输入输出(printf函数与scanf函数,getchar与putchar详解,使用Linux ubuntu)

1.输入输出 1.1.按格式输入输出 printf 可以在man手册中查看 int printf(const char *format, ...); printf:函数名(参数)int:函数的返回值 功能&#xff1a;按格式在终端输出 参数&#xff1a;多参 返回值&#xff1a;输出字符个数 格式&#xff1a; %d int %c char…

Jmeter自动化实战

一、前言 由于系统业务流程很复杂,在不同的阶段需要不同的数据,且数据无法重复使用,每次造新的数据特别繁琐,故想着能不能使用jmeter一键造数据 二、创建录制模板 可参考:jmeter录制接口 首先创建一个录制模板 因为会有各种请求头,cookies,签名,认证信息等原因,导致手动复制…

【mysql】4-2. MySQL存储结构

MySQL存储结构 1 什么是表空间⽂件&#xff1f; 解答问题 表空间⽂件是⽤来存储表中数据的⽂件&#xff0c;表空间⽂件的⼤⼩由存储的数据多少决定&#xff0c;不同的表空间⽂件存储数据的种类也有所不同&#xff0c;在MySQL中表空间分为五类&#xff0c;包括&#xff1a;系统…

Ansible基本使用

目录 介绍 安装 inventory-主机清单 分组 子组 modules-模块 command shell script file copy systemd yum get_url yum_repository user mount cron 介绍 ansible是基于python开发的自动化运维工具。架构相对比较简单&#xff0c;仅需通过ssh连接客户机执行…

HivisionIDPhoto Docker部署以及Springboot接口对接(AI证件照制作)

项目简介 项目以及官方文档地址 HivisionIDPhoto 旨在开发一种实用、系统性的证件照智能制作算法。 它利用一套完善的AI模型工作流程&#xff0c;实现对多种用户拍照场景的识别、抠图与证件照生成。 HivisionIDPhoto 可以做到&#xff1a; 轻量级抠图&#xff08;纯离线&a…

DB-GPT系列(一):DB-GPT能帮你做什么?

DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL and Agents)&#xff0c;围绕大模型提供灵活、可拓展的AI原生数据应用管理与开发能力&#xff0c;可以帮助企业快速构建、部署智能AI数据应用&#xff0c;通过智能数据分析、洞察…

整理了一些大模型的课程,非常详细,大模型零基础入门到精通,收藏我这一篇就够了

目前有多个科普类的大模型课程&#xff0c;这些课程涵盖了从基础理论到实际应用的各个方面。以下是一些主要的科普类大模型课程&#xff1a;复旦大学“大模型开发与赋能”专题讲习班&#xff1a;由复旦大学计算机学院邱锡鹏教授带来的《大模型科普讲解》课程&#xff0c;通过深…