【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)

news2024/12/26 12:38:00

【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)

MMWave API(位置处于BSS)可以被DSS和MSS调用
通过Mailbox进行数据通信
毫米波雷达接口

#include < ti/control/mmwave/mmwave.h>
#include <ti/drivers/mailbox/mailbox.h>

MMWave工作原理

首先搞清楚 mmwave时雷达射频整体 每秒发送很多frame(帧)
frame下面有chirp 比如96个chirp
所以当发送开始时 会连续发送96个chirps 然后接收数据 再处理
如图为chirp的时序图
在这里插入图片描述
雷达工作原理是上电-发送chirps-帧结束-处理-上电循环
一个Frame,首先是信号发送,比如96个chirp就顺次发出去,然后接收回来,混频滤波,ADC采样,这些都是射频模块的东西。射频完成之后,FFT,CFAR,DOA这些就是信号处理的东西。然后输出给那个结构体,就是当前帧获得的点云了。
在这里插入图片描述
在射频发送阶段 一个frame发送若干个chirp 也就是上图左上角
第一个绿色点为frame start 第二个绿色点为frame end
其中发送若干chirps(小三角形)
chirps的个数称为numLoops(代码中 rlFrameCfg_t结构体)
在mmwave studio上位机中 则称为 no of chirp loops

frame end 到 周期结束的时间为计算时间 称为inter frame period
在这里插入图片描述
frame start到循环结束的时间称为framePeriodicity(代码中 rlFrameCfg_t结构体)
在mmwave studio上位机中 则称为 Periodicity

如下图frame配置部分
在这里插入图片描述
在inter frame Periodicity时间内(比如这里整个周期是55ms)
就是用于计算和处理的时间 一定比55ms要小
如果chirps很多的话 那么计算时间就会减小

如果是处理点云数据 则只需要每一帧计算一次点云即可
计算出当前帧的xyz坐标和速度 以及保存时间戳

雷达上电

 /* Wait for BSS powerup */
if (SOC_waitBSSPowerUp(socHandle, &errCode) < 0)
{
    /* Debug Message: */
    System_printf ("Debug: SOC_waitBSSPowerUp failed with Error [%d]\n", errCode);
    return 0;
}

Mailbox_init(MAILBOX_TYPE_MSS);

除了初始化SOC外 还需要调用SOC_waitBSSPowerUpMailbox_init

配置流程

1. 初始化模块:MMWave_init

配置结构体 MMWave_InitCfg
domain指定运行位置

MMWave_InitCfg      initCfg;
initCfg.domain                  = MMWave_Domain_MSS;
initCfg.socHandle               = MMWave_Global_Params.handle.socHandle;
initCfg.eventFxn                = MMWave_eventFxnCallback;  //事件回调
initCfg.linkCRCCfg.useCRCDriver = 0U;           //1开启CRC 0关闭CRC
initCfg.linkCRCCfg.crcChannel   = CRC_Channel_CH1;      //CRC通道1
initCfg.cfgMode                 = MMWave_ConfigurationMode_FULL;  //全部模式 也可以设置成最小全部模式
initCfg.executionMode           = MMWave_ExecutionMode_ISOLATION;  //MSS和DSS不通讯 如果需要 则换个模式

//以下全是回调
initCfg.cooperativeModeCfg.cfgFxn   = MMWave_cfgFxnCallback;
initCfg.cooperativeModeCfg.closeFxn = MMWave_closeFxnCallback;
initCfg.cooperativeModeCfg.openFxn  = MMWave_openFxnCallback;
initCfg.cooperativeModeCfg.startFxn = MMWave_startFxnCallback;
initCfg.cooperativeModeCfg.stopFxn  = MMWave_stopFxnCallback;

/* Initialize and setup the MMWave Control module */
MMWave_Global_Params.handle.MMWave_handle = MMWave_init (&initCfg, &errCode);
if (MMWave_Global_Params.handle.MMWave_handle == NULL)
{
    /* Error: Unable to initialize the MMWave control module */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: MMWave Control Initialization failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    return;
}

在MSS+DSS协作模式下工作时,毫米波同时在MSS和DSS上执行。每个域都注册一个回调函数,如果对等域执行等效操作,则由毫米波模块调用该函数。
在这里插入图片描述
这样在配置时 会自动进行传参 使两个部分同步

2. 同步模块:MMWave_sync

/* Synchronization: This will synchronize the execution of the control module
     * between the domains. This is a prerequiste and always needs to be invoked. */
    //同步
    if (MMWave_sync (MMWave_Global_Params.handle.MMWave_handle, &errCode) < 0)
    {
        /* Error: Unable to synchronize the MMWave control module */
        MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
        System_printf ("Error: MMWave Control Synchronization failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
        return;
    }

直接调用MMWave_sync

3. 执行毫米波模块:MMWave_execute

在执行上面两步以后需要调用MMWave_execute
这个函数需要在上下文一直调用 所以建立一个死循环线程

这里priority 越大 优先级越高 越先响应

/*****************************************************************************
    * Launch the MMWave control execution task
    * - This should have a higher priroity than any other task which uses the
    *   MMWave control API
    *****************************************************************************/
    //这里是开了一个线程循环调用
    Task_Params_init(&taskParams);
    taskParams.priority  = 5;
    taskParams.stackSize = 3*1024;
    MMWave_Global_Params.task.MMWaveCtrl = Task_create(Ctrl_MMWave, &taskParams, NULL);
void Ctrl_MMWave(UArg arg0, UArg arg1)
{
    int32_t errCode;
    MMWave_ErrorLevel   errorLevel;
    int16_t             mmWaveErrorCode;
    int16_t             subsysErrorCode;

    while (1)
    {
        /* Execute the MMWave control module: */
        if (MMWave_execute (MMWave_Global_Params.handle.MMWave_handle, &errCode) < 0)
        {
            MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
            System_printf ("Error: MMWave control execution failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
        }
    }
}

4. 打开模块:MMWave_open

MMWave_OpenCfg      openCfg;

openCfg.freqLimitLow  = 600U;   //低频限制
openCfg.freqLimitHigh = 640U;   //高频限制

openCfg.chCfg.rxChannelEn = 0x000F;  //开启四个RX
openCfg.chCfg.txChannelEn = 0x0007;  //开启四个TX
openCfg.chCfg.cascading   = 0x0000;  //不开启级联
openCfg.chCfg.cascadingPinoutCfg = 0;  //直接给0

openCfg.lowPowerMode.lpAdcMode = 0x0000; //Regular ADC mode

openCfg.adcOutCfg.fmt.b2AdcBits = 2; //16bit
openCfg.adcOutCfg.fmt.b8FullScaleReducFctr = 0; //16bit只能为0
openCfg.adcOutCfg.fmt.b2AdcOutFmt = 2;  //Complex with Image band

openCfg.defaultAsyncEventHandler    = MMWave_DefaultAsyncEventHandler_MSS;

openCfg.disableFrameStartAsyncEvent = false;
openCfg.disableFrameStopAsyncEvent  = false;

openCfg.useCustomCalibration        = false;  // 无自定义校准 false表示默认启用所有校准
openCfg.customCalibrationEnableMask = 0x0;

openCfg.calibMonTimeUnit            = 1;   //一帧一次校准

/*
MMWave_CalibrationData      calibrationData;
memset ((void*)&calibrationCfg, 0 , sizeof(MMWave_CalibrationCfg));

calibrationData.ptrCalibData->calibChunk
calibrationData.ptrPhaseShiftCalibData->PhShiftcalibChunk
*/

/* Open the mmWave module: */
if (MMWave_open (MMWave_Global_Params.handle.MMWave_handle, &openCfg, NULL, &errCode) < 0)
{
    /* Error: decode and Report the error */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Open failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
}

这里是配置频段 RX、TX使能个数、采样位数等
对应mmwave studio:
在这里插入图片描述
在这里插入图片描述

5. 模块的配置:MMWave_config

这里是配置frame

MMWave_CtrlCfg      ctrlCfg;

ctrlCfg.dfeDataOutputMode = MMWave_DFEDataOutputMode_FRAME;

ctrlCfg.u.frameCfg.profileHandle[0]=MMWave_Global_Params.handle.profileHandle[0];
ctrlCfg.u.frameCfg.profileHandle[1]=NULL;
ctrlCfg.u.frameCfg.profileHandle[2]=NULL;
ctrlCfg.u.frameCfg.profileHandle[3]=NULL;

ctrlCfg.u.frameCfg.frameCfg.chirpStartIdx = 0;
ctrlCfg.u.frameCfg.frameCfg.chirpEndIdx = 2;
ctrlCfg.u.frameCfg.frameCfg.numLoops = 96;
ctrlCfg.u.frameCfg.frameCfg.numFrames = 0;
ctrlCfg.u.frameCfg.frameCfg.numAdcSamples = 96;
ctrlCfg.u.frameCfg.frameCfg.framePeriodicity = 11000000;  //55ms
ctrlCfg.u.frameCfg.frameCfg.triggerSelect = 0x0001; //软件API触发

ctrlCfg.u.frameCfg.frameCfg.numDummyChirpsAtEnd = 0;
ctrlCfg.u.frameCfg.frameCfg.frameTriggerDelay = 0;

/*
//frame模式不用配
ctrlCfg.u.continuousModeCfg.cfg.startFreqConst
ctrlCfg.u.continuousModeCfg.cfg.txOutPowerBackoffCode
ctrlCfg.u.continuousModeCfg.cfg.txPhaseShifter
ctrlCfg.u.continuousModeCfg.cfg.digOutSampleRate
ctrlCfg.u.continuousModeCfg.cfg.hpfCornerFreq1
ctrlCfg.u.continuousModeCfg.cfg.hpfCornerFreq2
ctrlCfg.u.continuousModeCfg.cfg.rxGain
ctrlCfg.u.continuousModeCfg.cfg.vcoSelect
ctrlCfg.u.continuousModeCfg.dataTransSize
*/
//ctrlCfg.u.advancedFrameCfg.profileHandle = //NULL;  //frame模式不用配

/* Configure the mmWave module: */
if (MMWave_config (MMWave_Global_Params.handle.MMWave_handle, &ctrlCfg, &errCode) < 0)
{
    /* Error: Report the error */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Config failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
}

对应:
在这里插入图片描述

配置profile和chirp

如果需要配置profile和chirp 则需要调用MMWave_addProfileMMWave_addChirp

注意 chirp是在profile之下的 而profile是在mmwave之下的(就像mmwave的句柄在soc之下)

所以配置frame时:

ctrlCfg.u.frameCfg.profileHandle[0]=MMWave_Global_Params.handle.profileHandle[0];

这里的profile句柄就是MMWave_addProfile返回的 而chirp的句柄在MMWave_addChirp的返回中
并且MMWave_addChirp的第一个参数就是MMWave_addProfile的返回值(profile的句柄)
MMWave_addProfile的第一个参数则为MMWave_init的返回值(mmwave的句柄)
那么配置的先后关系就可以列出来了(其实不用在意 只要配了就行 另外 句柄要用全局变量 但是按顺序配置可以方便从上往下读代码)

rlProfileCfg_t  profileCfg;
rlChirpCfg_t    chirpCfg;
memset ((void*)&profileCfg, 0 , sizeof(rlProfileCfg_t));
memset ((void*)&chirpCfg, 0 , sizeof(rlChirpCfg_t));

profileCfg.profileId = 0;
profileCfg.pfVcoSelect = 0x02;  //内置 VCO2 选择60-64GHz
profileCfg.pfCalLutUpdate = 0x00;  //校准
profileCfg.startFreqConst = 0x58E3A1CD;  //60GHz
profileCfg.idleTimeConst = 0x2710;  //100us
profileCfg.adcStartTimeConst = 0x258;  //6us
profileCfg.rampEndTime = 0x1770;  //60us
profileCfg.txOutPowerBackoffCode = 0;  //全为0
profileCfg.txPhaseShifter = 0;  //全为0
profileCfg.freqSlopeConst = 0x05E7;  //54.713 MHz/us
profileCfg.txStartTime = 0;  //0us
profileCfg.numAdcSamples = 96;  //96
profileCfg.digOutSampleRate = 0x0B86;  //2950ksps
profileCfg.hpfCornerFreq1 = 0;  //175K
profileCfg.hpfCornerFreq2 = 0;  //350K
profileCfg.txCalibEnCfg = 0xFFFF;  //不适用于IWR6843 ES 1.0
profileCfg.rxGain = 0x68; //40dB/34dB

MMWave_Global_Params.handle.profileHandle[0] = MMWave_addProfile(MMWave_Global_Params.handle.MMWave_handle,&profileCfg,&errCode);
if(MMWave_Global_Params.handle.profileHandle[0] == NULL)
{
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave profileCfg failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
}

chirpCfg.chirpStartIdx=0;
chirpCfg.chirpEndIdx=0;
chirpCfg.profileId=0;
chirpCfg.startFreqVar=0;
chirpCfg.freqSlopeVar=0;
chirpCfg.idleTimeVar=0;
chirpCfg.adcStartTimeVar=0;
chirpCfg.txEnable=(1<<0);

//TDM模式 用for循环配置三次 每次的chirpStartIdx chirpEndIdx均不同 分别为00 11 22 另外 打开的TX也不同 分别为TX0 TX1 TX2
//这三个chirp配置都属于同一个profileHandle下
for(i=0;i<3;i++)
{
    chirpCfg.chirpStartIdx=i;
    chirpCfg.chirpEndIdx=i;
    chirpCfg.txEnable=(1<<i);
    MMWave_Global_Params.handle.chirpHandle[i] = MMWave_addChirp(MMWave_Global_Params.handle.profileHandle[0],&chirpCfg,&errCode);
    if(MMWave_Global_Params.handle.chirpHandle[i] == NULL)
    {
        MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
        System_printf ("Error: mmWave chirpCfg %d failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    }
}

//然后下面再是MMWave_config 函数和配置

然后下面再是MMWave_config 函数和配置

对应的就是这一大块
在这里插入图片描述

6. 启动毫米波:MMWave_start

这里就是开启测量了 同时定义了校准和运行模式

MMWave_CalibrationCfg       calibrationCfg;
memset ((void *)&calibrationCfg, 0, sizeof(MMWave_CalibrationCfg));

calibrationCfg.dfeDataOutputMode = MMWave_DFEDataOutputMode_FRAME;

calibrationCfg.u.chirpCalibrationCfg.enableCalibration = true;
calibrationCfg.u.chirpCalibrationCfg.enablePeriodicity = true;
calibrationCfg.u.chirpCalibrationCfg.periodicTimeInFrames = 10;  //每10帧一次校准

//calibrationCfg.u.contCalibrationCfg.enableOneShotCalibration  //frame模式不用配

/* Start the mmWave module: The configuration has been applied successfully. */
if (MMWave_start(MMWave_Global_Params.handle.MMWave_handle, &calibrationCfg, &errCode) < 0)
{
    /* Error/Warning: Unable to start the mmWave module */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Start failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    /* datapath has already been moved to start state; so either we initiate a cleanup of start sequence or
       assert here and re-start from the beginning. For now, choosing the latter path */
}

错误代码

毫米波雷达错误代码可以用MMWave_decodeError函数来获取
传入的第一个参数为errCode 而后面三个其实都是返回值
比如:

int32_t         errCode;
MMWave_ErrorLevel   errorLevel;
int16_t             mmWaveErrorCode;
int16_t             subsysErrorCode;
if (MMWave_start(MMWave_Global_Params.handle.MMWave_handle, &calibrationCfg, &errCode) < 0)
{
    /* Error/Warning: Unable to start the mmWave module */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Start failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    /* datapath has already been moved to start state; so either we initiate a cleanup of start sequence or
       assert here and re-start from the beginning. For now, choosing the latter path */
}

最后皆可以通过mmWaveErrorCode来获取调用函数的问题

其他模块的错误代码基本地址不一样 但是也大同小异 查其他模块的手册就可以了

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

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

相关文章

Redis基本了解

Redis 基于内存进⾏存储&#xff0c;⽀持 key-value 的存储形式&#xff0c;底层是⽤ C 语⾔编写的。 基于 key-value 形式的数据字典&#xff0c;结构⾮常简单&#xff0c;没有数据表的概念&#xff0c;直接⽤键值对的形式完成数据的管理&#xff0c;Redis ⽀持 5 种数据类型…

运维Shell脚本小试牛刀(六): Shell中的函数|本地变量

运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 运维Shell脚本小试牛刀(三)::$(cd $(dirname $0)&#xff1b; pwd)命令详解 运维Shell脚本小试牛刀(四): 多层嵌套if...elif...elif....else fi_蜗牛杨哥的博客-CSDN博客 Cenos7安装小火车程序动画 运维Shell脚本小试…

14.Redis 主从复制

Redis 主从复制 redis 主从复制配置 redis 主从复制启动 redis 主从复制断开 redis 主从复制主从复制构特点主从复制的拓扑结构一主一从⼀主多从树状主从 主从复制原理数据同步psync 运行流程全量复制流程部分复制流程实时复制 关于从节点何时晋升成主节点总结 redis 主从复制 …

iKeyPrime完美解4G信号,可以登录iCloud,有消息通知,支持最新iOS16.6。

iKeyPrime是一款绕过激活锁界面的解锁工具&#xff0c;可以激活所有iPhone苹果手机&#xff0c;二网/三网恢复信号&#xff0c;并且支持插卡接打电话、收发短信、4G流量上网&#xff0c;支持iCloud登录&#xff0c;有消息通知&#xff0c;支持iPhone5S~X的所有型号&#xff0c;…

车规微控制器的ECC机制及EMU外设

车规微控制器的ECC机制及EMU外设 文章目录 车规微控制器的ECC机制及EMU外设引言ECC的基本原理ECC RAM的访问方式ECC RAM的初始化SRAM ECC错误注入及EMU外设Flash ECC校验参考文献 引言 ECC是微控制器系统中&#xff0c;用于保障信息安全的常用机制&#xff0c;主要是避免存储设…

gRPC远程进程调用

gRPC远程进程调用 rpc简介golang实现rpc方法一net/rpc库golang实现rpc方法二jsonrpc库grpc和protobuf在一起第一个grpc应用grpc服务的定义和服务的种类grpc stream实例1-服务端单向流grpc stream实例2-客户端单向流grpc stream实例3-双向流grpc整合gin

转型的每一步都至关重要!大运新能源远勤山谈品牌发展之道

“我们转型新能源乘用车&#xff0c;一开始选择研发生产悦虎和远志M1两款中低价位车型是为了“练练手”。我们用这两款车型探路&#xff0c;去熟悉和了解新能源市场&#xff0c;通过一步一步踏踏实实把产品做好&#xff0c;逐渐获得消费者认可&#xff0c;同时也为今后研发其他…

一周AIGC丨中国境内 151 个算法完成备案,腾讯、百度等 11 家 AI 大模型产品陆续上线...

近日&#xff0c;网信办官网公开发布第二批境内深度合成服务算法备案信息。至此&#xff0c;国内已有 151 个算法通过深度合成服务算法名单的备案。腾讯、百度等 11 家 AI 大模型产品完成备案陆续上线&#xff0c;标志着大模型行业在我国正式进入产品化落地阶段&#xff0c;大模…

链动2+1模式,让你的美妆消费变成收入来源

美妆&#xff0c;是一个与女性息息相关的话题&#xff0c;也是一个巨大的市场。据统计&#xff0c;2022年&#xff0c;中国美妆市场规模达到了1.3万亿元&#xff0c;占全球美妆市场的20%。美妆消费者的需求日益多样化和个性化&#xff0c;对产品的品质、效果、安全性等方面有着…

Nougat 深度剖析

Nougat 深度剖析 项目地址&#xff1a;https://github.com/facebookresearch/nougat 论文地址&#xff1a;Nougat: Neural Optical Understanding for Academic Documents 0 背景 近日&#xff0c;MetaAI又放了大招&#xff0c;他们提出了一种全新的端到端的OCR模型&#x…

spring boot项目上传头像

应用还是验证码使用的原理&#xff1b;但是代码逻辑却有所不同。 逻辑前端传给后端&#xff0c;然后写入本机磁盘去&#xff0c;文件名用uuid避免重复。写完就可以顺带把文件名保存到数据库里。上传就这样子。 怎么取用的&#xff1b;还是通过配置映射的方式&#xff1b;通过sr…

电商企业固定资产怎么管理

电商固定资产管理需要建立标准的固定资产管理制度&#xff0c;从规则上进行约束。同时&#xff0c;引入固定资产管理系统&#xff0c;从流程上起到直接提升效果的方式。电商标准的固定资产管理制度因公司而异&#xff0c;但通常包括以下内容&#xff1a;  固定资产的定义和分…

B2B企业常用的邮件营销推广策略

互联网在经历了十多年的高速增长后&#xff0c;近年来互联网流量逐渐饱和&#xff0c;企业获客成本越发高涨以及拓客增长渐渐缓慢&#xff0c;尤其对于专业门槛高、行业较为垂直的B2B企业而言&#xff0c;网络营销一直是企业获客中非常重要的一环。如何获得更多的客户、降低获客…

【Python爬虫笔记】爬虫代理IP与访问控制

一、前言 在进行网络爬虫的开发过程中&#xff0c;有许多限制因素阻碍着爬虫程序的正常运行&#xff0c;其中最主要的一点就是反爬虫机制。为了防止爬虫程序在短时间内大量地请求同一个网站&#xff0c;网站管理者会使用一些方式进行限制。这时候&#xff0c;代理IP就是解决方…

VUE for循环 默认选中第一条数据

for循环渲染列表默认选中第一条数据 点击其他选项切换数据 <div><div class"Subtitle" style"padding: 5px 40px;">项目清单</div><div class"project-manifest"><div v-for"(item, index) in project" :…

三年前端还不会配置Nginx?刷完这篇就够了

什么是Nginx Nginx是一个开源的高性能HTTP和反向代理服务器。它可以用于处理静态资源、负载均衡、反向代理和缓存等任务。Nginx被广泛用于构建高可用性、高性能的Web应用程序和网站。它具有低内存消耗、高并发能力和良好的稳定性&#xff0c;因此在互联网领域非常受欢迎。 为…

SpringBoot的HandlerInterceptor拦截器使用方法

一、创建拦截器 通过实现HandlerInterceptor接口创建自己要使用的拦截器 import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.…

Python Fiddler抓包工具实战案例:获取公众号(pc客户端)数据

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 开发环境: python 3.8 运行代码 pycharm 2021.2 辅助敲代码 requests 第三方模块 Fiddler 汉化版 抓包的工具 配置Fiddler环境 先打开Fiddler&#x…

AFNetworking 实现下载请求的原理过程

实现下载的流程 一 生成一个 NSMutableURLRequest二 创建 NSURLSessionTask创建 URLSessionTask过程解析代理方法调用过程这样设计的原因 一 生成一个 NSMutableURLRequest NSMutableURLRequest *request [[AFHTTPRequestSerializer serializer] requestWithMethod:"GET&…

【三相太阳能光伏系统控制】在线性和非线性负载条件下模拟额定功率为33kW的三相并网光伏系统,提高电能质量研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…