官方SDK中提供了ADC操作的相关主要接口,极大方便了对ADC的配置

ADC数据结构

ADC的主要数据结构有两个ADC_InitTypeDef 和  ADC_CommonInitTypeDef

ADC_CommonInitTypeDef 主要提供ADC初始化配置包括模式,时钟分频,采样周期等

ADC_CommonInitTypeDef 结构成员 描述
uint32_t ADC_Mode; ADC采的操作模式配置 独立的或者多重模式
uint32_t ADC_Prescaler ADC 分频设置,ADC的时钟是由PCLCK分频而来,可以设置为2,4,6,8,,最大频率为36Mhz
uint32_t ADC_DMAAccessMode DMA模式设置,只有在多重模式下才需要设置
uint32_t ADC_TwoSamplingDelay 2个采样阶段之间的延迟,多模交错模式需要设置

ADC_InitTypeDef主要是ADC的一些初始化配置

ADC_InitTypeDef结构成员 描述
uint32_t ADC_Resolution ADC分辨率设置,可以选择12,10,8,和6位
FunctionalState ADC_ScanConvMode 是否启动扫描模式
FunctionalState ADC_ContinuousConvMode 是否启用连续转换模式
uint32_t ADC_ExternalTrigConvEdge 外部触发极性配置
uint32_t ADC_ExternalTrigConv 外部触发事件选择
uint32_t ADC_DataAlign 数据字节对齐方式
uint8_t  ADC_NbrOfConversion AD转换通道数目

单通道中断采集

本示范用例位单通到采集用例,因为是单通道采集可以采样规则通道转换数据,其采取数据的方式可以采样中断方式进行采集,可以不采样DMA方式,当每次采集完毕之后,ADC会发送一个ADC_IT_JEOC中断,表明数据采集完毕,在中断服务程序读取ADC_DR中的寄存器数据。

该实验用例采样的硬件设计如下:

其ADC采样传感器为一个滑动电阻, ADC1接PC3, 查看上节可以PC3可以接ADC1的13 通道

软件实现部分

#define ADCx_CHANNEL_GPIO_CLK    RCC_AHB1Periph_GPIOC
#define ADC1_GPIO_PIN            GPIO_Pin_3
#define ADC_GPIO_PORT            GPIOC/************ADC******************/
#define ADCx                     ADC1
#define PARA_ADC_CHANNEL_1       ADC_Channel_13
#define ADCx_CLK                 RCC_APB2Periph_ADC1/*PC3 GPIO初始化*/
void ADC_GPIO_Config(void)
{GPIO_InitTypeDef      GPIO_InitStructure;RCC_AHB1PeriphClockCmd(ADCx_CHANNEL_GPIO_CLK, ENABLE);/******************ADC1*************/GPIO_InitStructure.GPIO_Pin = ADC1_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//GPIO设置为Analog ModeGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//即不上拉又不下拉GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);}/**ADC 中断初始化***/
void ADC_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* 配置优先级分组 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 配置中断源 */NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}/*ADC 初始化代码*/
void ADC_Mode_Configure(void)
{ADC_InitTypeDef       ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);/* ADC1 Common Init **********************************************************/ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//设置为独立模式ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//设置为4分频ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;//DMA 设置为disableADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;//延迟周期ADC_CommonInit(&ADC_CommonInitStructure);/* ADC1 Init ****************************************************************/ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//采样分辨率为12位ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 单通道ADC,不需要扫描模式ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续模式使能ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;////ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;//外部触发不需要设置ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐ADC_InitStructure.ADC_NbrOfConversion =1;ADC_Init(ADCx, &ADC_InitStructure);/* ADC1 regular channel13 configuration **************************************/ADC_RegularChannelConfig(ADCx, PARA_ADC_CHANNEL_1, 1, ADC_SampleTime_3Cycles);//设置通道转换规则,第一个采集位DMA channel 13// ADC 转换结束产生中断,在中断服务程序中读取转换值//ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);//使能中断ADC_Cmd(ADCx, ENABLE);//使能ADC//开始 adc 转换,软件触发ADC_SoftwareStartConv(ADCx); //触发ADC开始转换}/*adc中断函数,读取数据*/
void ADC_IRQHandler(void)
{if (ADC_GetITStatus(ADCx,ADC_IT_EOC)==SET) {// 读取 ADC 的转换值ADCxConvertedValue = ADC_GetConversionValue(ADCx);ADC_ClearITPendingBit(ADCx,ADC_IT_EOC);}
}/*处理函数封装*/
void ADC_Configure(void)
{ADC_GPIO_Config();ADC_NVIC_Config();ADC_Mode_Configure();
}

多通道注入规则采集

本节例子主要讲述最近项目遇到的问题,由于DCMI和ADC都是用的DMA1采集数据,DMA1本质上在同一个DMA内不能同时采集两个以上,所以DCMI和ADC都使用DMA时两者会有影响,尤其是采集到的图像会出现条纹,该问题定位了很久,一直怀疑是sensor的问题,后来把ADC采集去掉之后,图像恢复正常,看来这是STM32的一个芯片缺陷,无奈只能改用注入规则采集数据,使用定时器触发外部触发注入规则转换,进行定时采集。

硬件设计:

在该项目中使用到了两个滑动电阻需要采集数据,分别接PC3和PC4 IO。查看手册可以使用ADC1的13和14通道。

代码部分

使用定时器TIM2的CC1来触发注入转换规则,每隔100ms采集一次数据,由于针对注入通道的转换规则相关用例比较少,查看了手册很久,才把数据调通,代码主要部分如下:

/**************GPIO*************/
#define ADCx_CHANNEL_GPIO_CLK    RCC_AHB1Periph_GPIOC
#define ADC1_GPIO_PIN            GPIO_Pin_3
#define ADC_GPIO_PORT            GPIOC
#define ADC2_GPIO_PIN            GPIO_Pin_4/************ADC******************/
#define ADCx                     ADC1
#define PARA_ADC_CHANNEL_1       ADC_Channel_13
#define PARA_ADC_CHANNEL_2       ADC_Channel_14
#define ADCx_CLK                 RCC_APB2Periph_ADC1/*定时器初始化代码*/
static void ADC_TIM_Mode_Config(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0};TIM_OCInitTypeDef       TIM_OCInitStructure   = {0};uint32_t TIM_Period = 1000;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_TimeBaseStructure.TIM_Period    = TIM_Period - 1;TIM_TimeBaseStructure.TIM_Prescaler = 8400 - 1;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = TIM_Period/2;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OC1Init(TIM2, &TIM_OCInitStructure);TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);//TIM_ClearFlag(TIM2, TIM_FLAG_Update);//TIM_ITConfig(TIM2, TIM_IT_Update,ENABLE);TIM_Cmd(TIM2, ENABLE);
}/*TIM中断初始化*/
void ADC_TIM_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* 配置优先级分组 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 配置中断源 */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}/*GPIO初始化代码*/
void ADC_GPIO_Config(void)
{GPIO_InitTypeDef      GPIO_InitStructure;RCC_AHB1PeriphClockCmd(ADCx_CHANNEL_GPIO_CLK, ENABLE);/******************ADC1*************/GPIO_InitStructure.GPIO_Pin = ADC1_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);/******************ADC2*************/GPIO_InitStructure.GPIO_Pin = ADC2_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);
}/**ADC中断初始化**/
void ADC_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* 配置优先级分组 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 配置中断源 */NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}/*ADC初始化配置*/
void ADC_Mode_Configure(void)
{ADC_InitTypeDef       ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);/* ADC1 Common Init **********************************************************/ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;ADC_CommonInit(&ADC_CommonInitStructure);/* ADC1 Init ****************************************************************/ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;ADC_InitStructure.ADC_ScanConvMode = ENABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigInjecConvEdge_Rising;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigInjecConv_T2_CC1;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfConversion = 2;ADC_Init(ADCx, &ADC_InitStructure);/* ADC1 regular channel13 configuration **************************************/ADC_InjectedSequencerLengthConfig(ADCx, 2);ADC_InjectedChannelConfig(ADCx, PARA_ADC_CHANNEL_1, 1, ADC_SampleTime_56Cycles);ADC_InjectedChannelConfig(ADCx, PARA_ADC_CHANNEL_2, 2, ADC_SampleTime_56Cycles);ADC_ExternalTrigInjectedConvConfig(ADCx, ADC_ExternalTrigInjecConv_T2_CC1);// ADC 转换结束产生中断,在中断服务程序中读取转换值ADC_ITConfig(ADCx, ADC_IT_JEOC, ENABLE);ADC_Cmd(ADCx, ENABLE);  }/**TIM2定时器定时开启ADC采集**/
void TIM2_IRQHandler(void)
{if (TIM_GetFlagStatus(TIM2, TIM_IT_Update)){   if (0 == ADCFlag){ADC_SoftwareStartInjectedConv(ADCx);ADCFlag = 1;}TIM_ClearFlag(TIM2, TIM_IT_Update);}
}/***ADC采集完中断处理程序***/
void ADC_IRQHandler(void)
{if (ADC_GetITStatus(ADCx,ADC_IT_JEOC)==SET){ADCxConvertedValue_1[1]   = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_2);ADCxConvertedValue_1[0]   = ADC_GetInjectedConversionValue(ADCx, ADC_InjectedChannel_1);ADCFlag = 0;ADC_ClearITPendingBit(ADCx,ADC_IT_JEOC);}
}/***处理封装***/
void ADC_Configure(void)
{ADC_TIM_NVIC_Config();ADC_TIM_Mode_Config();  ADC_GPIO_Config();ADC_NVIC_Config();ADC_Mode_Configure();
}

上述代码在项目中,亲测有效,可以正常采集到数据

多重道规则DMA采集

上述采集通过多重到规则DMA采集实现方法:

/**************GPIO*************/
#define ADCx_CHANNEL_GPIO_CLK    RCC_AHB1Periph_GPIOC
#define ADC1_GPIO_PIN            GPIO_Pin_3
#define ADC_GPIO_PORT            GPIOC
#define ADC2_GPIO_PIN            GPIO_Pin_4// ADC DR register
#define ADC_DR_ADDR    ((u32)&ADC1->DR)/**********DCMA****************/
#define ADC_DMA_CLK      RCC_AHB1Periph_DMA2
#define ADC_DMA_CHANNEL  DMA_Channel_0
#define ADC_DMA_STREAM   DMA2_Stream0/************ADC******************/
#define ADCx                     ADC1
#define PARA_ADC_CHANNEL_1       ADC_Channel_13
#define PARA_ADC_CHANNEL_2       ADC_Channel_14
#define ADCx_CLK                 RCC_APB2Periph_ADC1
#define DMA_CHANNELx             DMA_Channel_2
#define DMA_STREAMx              DMA2_Stream0
#define ADCx_DR_ADDRESS          ((uint32_t)0x4001224C)#define DATE_SIZE      2__IO uint16_t ADCxConvertedValue[DATE_SIZE] = {0};
/**GPIO配置***/
void ADC_GPIO_Config(void)
{GPIO_InitTypeDef      GPIO_InitStructure;RCC_AHB1PeriphClockCmd(ADCx_CHANNEL_GPIO_CLK, ENABLE);/******************ADC1*************/GPIO_InitStructure.GPIO_Pin = ADC1_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);/******************ADC2*************/GPIO_InitStructure.GPIO_Pin = ADC2_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStructure);
}/***ADC DMA配置*****/
void ADC_DMA_Config(void)
{DMA_InitTypeDef DMA_InitStructure;// RCC_AHB1PeriphClockCmd(ADC_DMA_CLK, ENABLE); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;DMA_InitStructure.DMA_Memory0BaseAddr = (u32)ADCxConvertedValue;  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;DMA_InitStructure.DMA_BufferSize = DATE_SIZE;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  DMA_InitStructure.DMA_Channel = ADC_DMA_CHANNEL; DMA_Init(ADC_DMA_STREAM, &DMA_InitStructure);DMA_Cmd(ADC_DMA_STREAM, ENABLE);
}/**ADC配置**/
void ADC_Mode_Configure(void)
{ADC_InitTypeDef       ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);/* ADC1 Common Init **********************************************************/ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;ADC_CommonInit(&ADC_CommonInitStructure);/* ADC1 Init ****************************************************************/ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;ADC_InitStructure.ADC_ScanConvMode = ENABLE;ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfConversion = DATE_SIZE;ADC_Init(ADCx, &ADC_InitStructure);/* ADC1 regular channel13 configuration **************************************/ADC_RegularChannelConfig(ADCx, PARA_ADC_CHANNEL_1, 1, ADC_SampleTime_3Cycles);ADC_RegularChannelConfig(ADCx, PARA_ADC_CHANNEL_2, 2, ADC_SampleTime_3Cycles);// ADC 转换结束产生中断,在中断服务程序中读取转换值//ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE);ADC_DMACmd(ADCx, ENABLE);ADC_Cmd(ADCx, ENABLE);//开始 adc 转换,软件触发ADC_SoftwareStartConv(ADCx);}

STM32那点事(5)_ADC(下)相关推荐

  1. STM32那点事(5)_ADC(中)

    在上节得ADC转换规则中可以看到有两个规则:规则通道和注入通道,两个规则应用场景不太一样: 规则通道是比较常用的转换规则,支持连续循环自动采集,不需要人工进行干预,可以由硬件自动触发进行采集,在同一个 ...

  2. STM32那点事(5)_ADC(上)

    ADC介绍 ADC顾名思义为模数转换,与之相对的是DAC为数模转换,AD/DA为电子元器件中的重要模块,主要负责模拟信号和数字信号之间的转换,因为我们计算机中使用到的主要是数字信息010101等,而我 ...

  3. STM32那点事(3)_中断(上)

    中断是STM32核心模块之一,几乎所有的模块都需要和中断打交道.了解STM32运作机制非常重要.在<STM32那点事(1)_STM32F40_41xx启动文件详解>中讲解启动流程中提到,中 ...

  4. STM32那点事(4)_DMA(下)

    DMA按照其数据流传输可以分为存储器到外设.外设到存储器或者存储器到存储器的传输. 外设到存储器模式 这种模式可以通过DMA_SxCR寄存器中的EN置1,每次产生外设请求,数据流都会启动数据源到FIF ...

  5. STM32那点事(3)_中断(下)

    上节主要讲述了STM32 的中断基础知识以及一般配置过程.外部中断与其他模块中断相对要复杂一点.外部中断一般都是由GPIO触发,是在整个系统中需要经常用到. 介绍 STM32F4 有多达23个中断,每 ...

  6. STM32那点事(2)_时钟树(下)

    上两篇主要讲述了系统时钟,APB1, APB2, AHB配置的整个过程,是系统启动的关键,剩余部门将单独介绍 独立看门狗(IWDGCLK) 独立看门够采用内部单独时钟LSIRC,用于与其他系统时钟隔离 ...

  7. STM32系统定时器SysTick(只能向下递减)延时闪烁灯

    参考:stm32 系统定时器 SysTick 作者:点灯小哥 发布时间: 2021-03-10 13:46:00 网址:https://blog.csdn.net/weixin_46016743/ar ...

  8. STM32那点事(6)_定时器(上)

    STM32定时器是CPU中的基本功能模块之一,最基本的功能是提供定时,STM32定时器共用16个定时器,主要分为两个基本定时器,10个通用定时器,2个高级定时器,以及两个看门狗定时器.看门狗定时器后面 ...

  9. STM32那点事(4)_DMA(上)

    前言 DMA(直接存储器访问)主要用于外设与存储器之间以及存储器与存储器之间提高数据传输. 主要作用: 1:无需借助CPU操作,就可以通过DMA在两个外设或者存储器之间传递数据,速度较快. 2:解放C ...

最新文章

  1. HBase保存的各个字段意义解释
  2. 基于PaddlePaddle的机器翻译教程 | 深度学习基础任务系列
  3. Gartner:人工智能将改变个人设备领域的游戏规则
  4. 【简报】超棒的拖放式文件上传javascript类库:FileDrop
  5. Android滤镜效果实现及原理分析
  6. python3 文件 复制、重命名、移动、删除
  7. python3精要(6)-string类的format()方法
  8. java mysql自动备份_java定时备份数据之二_MySQL
  9. 配置纯净版Debian
  10. TDMoverIP是什么?tdmoverip产品特性介绍
  11. sublime text 3中安装ctags支持函数跳转,安装convertToUtf8支持中文步骤[工具篇]
  12. 7. JavaScript HTML DOM - 改变 CSS
  13. WordPress插件教程-WPS Limit Login限制登录次数
  14. java中finish什么意思,finish是什么意思(释义详解一览)
  15. iVMS-4200 Vs区别_异地恋 VS 网恋,哪个更难坚持到最后?| Newth互动158
  16. Opencascade 开发 1章
  17. iphone 各个设备的分辨率和对应的像素尺寸
  18. 使用Mindstudio进行Pytorch模型量化压缩
  19. 百度贴吧和微博爬虫好用的开源库
  20. 红叶李之Linux文件系统

热门文章

  1. Jeecg-Boot 快速开发平台,新手入门教程
  2. 开发指南专题二:JEECG微云快速开发平台JEECG框架初探
  3. 微服务架构案例(04):中间件集成,公共服务封装
  4. Java描述设计模式(10):组合模式
  5. 读书笔记—《发现你的行为模式(钻石版)》-开篇
  6. 【华为云 ModelArts-Lab AI实战营】第三期:图像分类 (III) 模型参数网络调优
  7. hadoop--windows环境配置hadoop-3.2.2
  8. hadoop--HDFS概述
  9. Linux基础命令---ab测试apache性能
  10. 深入PHP面向对象、模式与实践读书笔记:面向对象设计和过程式编程