GD32移植STM32工程(因为懒,所以移植)

文章目录

  • 一、前言
  • 二、差异性
  • 三、软件移植部分
    • 1.前期准备
      • 1.1 安装GD32固件库
      • 1.2 选择所用芯片
    • 2.修改程序
      • 2.1 启动时间(内部时钟可不改)
      • 2.2 主频
        • 2.2.1 系统时钟配置
        • 2.2.2 108MHz宏定义
          • 第一处
          • 第二处
          • 第三处
          • 第四处
          • 第五处
        • 2.2.3 串口
        • 2.2.4 FLASH
  • 四、总结


一、前言

在一个慵懒的日子里,我因为不想花费太多时间和精力,直接将原来为STM32编写的工程进行了修改,使其适用于GD32工程。这个过程并不复杂,只需要对一些特定的代码进行替换和调整,以适应GD32的硬件架构和指令集。然而,由于我对STM32和GD32之间的差异了解不够深入,这个过程也让我犯了一些错误。最终,经过一番努力,我终于成功地将工程从STM32移植到了GD32。

经过这次移植的经历,我深刻体会到了GD32和STM32之间的差异,并积累了一定的经验。因此,我决定将这次移植的经验分享出来,希望能够帮助更多的人在面对类似移植问题时能够更加顺利地完成移植工作。

在这里插入图片描述

二、差异性

可以从下面表格看出主要的硬件差异是供电以及主频大小等。

MCUSTM32F103VCT6GD32F103VCT6
内核Cortex-M3内核Cortex-M3内核
程序存储容量256KB256KB
RAM总容量48KB48KB
GPIO端口数量8080
工作电压范围2V~3.6V2.6V~3.6V
内核的供电电压1.2V1.8V
CPU最大主频72MHz108MHz
程序存储器类型FLASHFLASH
工作温度范围-40℃~+85℃-40℃~+85℃
ADC(位数)12bit12bit
DAC(位数)12bit12bit

三、软件移植部分

这里我使用的GD芯片是GD32F103VCT6,移植的程序来源自STM32F103VCT6,采用的是STM32的标准库。

1.前期准备

1.1 安装GD32固件库

进入兆易创新GD32 MCU官网下载keil支持包,下载完成后双击进行安装。
在这里插入图片描述

1.2 选择所用芯片

这里我用的是keil5,所以我选择安装 GigaDevice.GD32F10x_DFP.2.1.0 pack Keil5 在线支持包,安装完成后点击keil的魔术棒会出现GD32F10x Series。

在这里插入图片描述

最后,选择我们需要的MCU型号,前期准备工作完成,接下来开始移植程序。

在这里插入图片描述

2.修改程序

2.1 启动时间(内部时钟可不改)

HSE_STARTUP_TIMEOUT是用于定义外部高速时钟(HSE)启动的超时时间。我用的是内部时钟,所以也可以不改。

代码如下(示例):

/*** @brief In the following line adjust the External High Speed oscillator (HSE) Startup Timeout value */
#define HSE_STARTUP_TIMEOUT   ((uint16_t)0xFFFF) /*!< Time out for HSE start up */ //STM32 0x0500

2.2 主频

2.2.1 系统时钟配置

通过上面的差异性比较,我们知道GD32的最高主频为108MHZ,那么在STM32工程中要有哪些修改呢?

请接着往下看

1.在SystemClock_Config系统时钟配置函数中选择我们需要的时钟,这里用的是内部时钟HSI,有同学可能对底下这个宏定义 #define RCC_PLLMul_27 ((uint32_t)0x08280000)感到疑惑,下面就解释下。

根据官方GD32F10x User Manual 2.6版本用户手册的资料显示(中文P84-P87,英文P87-P91),要配置108MHZ,PLL时钟倍频因子需要配置为PLL源时钟x27,由于我们在RCC_PLLConfig函数选择RCC_PLLSource_HSI_Div2,HSI刚好是8MHZ,一半的HSI是4MHZ,4x27=108MHZ

PLLMF[3:0]为第21位到18位,(PLL源时钟 x 27)为11010,第一个1其实是第27位,所以时钟配置寄存器 0(RCU_CFG0)最后的值为0x0000 1000 0010 1000 XXXX(补零)=0x08280000

在这里插入图片描述
代码如下(示例):

 #define RCC_PLLMul_27                   ((uint32_t)0x08280000)/******************************************************************************** 函数名:SystemClock_Config* 描述  :系统时钟配置* 输入  :void* 输出  :void* 调用  :初始化* 备注  :
*******************************************************************************/
void SystemClock_Config(void)
{/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/   /* RCC system reset(for debug purpose) */RCC_DeInit();/* Enable HSI */RCC_HSICmd(ENABLE);/* Wait till HSI is ready */while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET){}/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);/* HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1); /* PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);
#ifdef STM32F10X_CL/* Configure PLLs *********************************************************//* PLL2 configuration: PLL2CLK = (HSI / 2) * 4 = 16 MHz */RCC_PREDIV2Config(RCC_PREDIV2_Div2);RCC_PLL2Config(RCC_PLL2Mul_4);/* Enable PLL2 */RCC_PLL2Cmd(ENABLE);/* Wait till PLL2 is ready */while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET){}/* PLL configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */ RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
#else/* PLLCLK = 4MHz * 27 = 72 MHz */RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_27); // HSI is divided by 2 to have 4MHz then multiply by 27 to have 108MHz
#endif/* Enable PLL */ RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while(RCC_GetSYSCLKSource() != 0x08){}
}
2.2.2 108MHz宏定义

在system_stm32f10x.c文件中找到SYSCLK_FREQ_72MHz的位置,一共有5处,全部注释掉,并且换成SYSCLK_FREQ_108MHz。

代码如下(示例):

第一处
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */#define SYSCLK_FREQ_24MHz  24000000
#else
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */ 
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
/* #define SYSCLK_FREQ_72MHz  72000000 */#define SYSCLK_FREQ_108MHz  108000000
#endif
第二处
/*******************************************************************************
*  Clock Definitions
*******************************************************************************/
#ifdef SYSCLK_FREQ_HSEuint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;        /*!< System Clock Frequency (Core Clock) */#elif defined SYSCLK_FREQ_108MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_108MHz;        /*!< System Clock Frequency (Core Clock) */
#else /*!< HSI Selected as System Clock source */uint32_t SystemCoreClock         = HSI_VALUE;        /*!< System Clock Frequency (Core Clock) */
#endif
第三处
#ifdef SYSCLK_FREQ_HSEstatic void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_24MHzstatic void SetSysClockTo24(void);
#elif defined SYSCLK_FREQ_36MHzstatic void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHzstatic void SetSysClockTo48(void);
#elif defined SYSCLK_FREQ_56MHzstatic void SetSysClockTo56(void);  
#elif defined SYSCLK_FREQ_72MHzstatic void SetSysClockTo72(void);
#elif defined SYSCLK_FREQ_108MHzstatic void SetSysClockTo108(void);	
#endif
第四处
/*** @brief  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.* @param  None* @retval None*/
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSESetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHzSetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHzSetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHzSetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHzSetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHzSetSysClockTo72();
#elif defined SYSCLK_FREQ_108MHzSetSysClockTo108();
#endif 
}
第五处
#elif defined SYSCLK_FREQ_108MHz
/*** @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2 *         and PCLK1 prescalers. * @note   This function should be used only after reset.* @param  None* @retval None*/
static void SetSysClockTo108(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;     /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;      /* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;    /* PCLK1 = HCLK/2 */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */        RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);  /* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9); 
#else    /*  PLL configuration: PLLCLK = HSE/2 * 27 = 108 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL27);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}    /* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}
#endif
2.2.3 串口

一开始我改完时钟108MHZ,试了串口,然后发现乱码,后面查了资料,才知道在stm32f10x_rcc.c文件中RCC_GetClocksFreq函数要新增以下代码。

if(RCC->CFGR & 0x08000000)这行代码用于检查RCC->CFGR寄存器中特定位(第27位)的值。如果该位为1,就会执行pllmull += 15;,即将pllmull变量的值增加15,变成27倍频刚好对应上面的108MHZ。

代码如下(示例):

/*** @brief  Returns the frequencies of different on chip clocks.* @param  RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold*         the clocks frequencies.* @note   The result of this function could be not correct when using *         fractional value for HSE crystal.  * @retval None*/
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;#ifdef  STM32F10X_CLuint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)uint32_t prediv1factor = 0;
#endif    /* Get SYSCLK source -------------------------------------------------------*/tmp = RCC->CFGR & CFGR_SWS_Mask;switch (tmp){case 0x00:  /* HSI used as system clock */RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;break;case 0x04:  /* HSE used as system clock */RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;break;case 0x08:  /* PLL used as system clock *//* Get PLL clock source and multiplication factor ----------------------*/pllmull = RCC->CFGR & CFGR_PLLMull_Mask;pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;      
#ifndef STM32F10X_CL      pllmull = ( pllmull >> 18) + 2;      if(RCC->CFGR & 0x08000000)//取27位{pllmull += 15;}						if (pllsource == 0x00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;}else{#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;/* HSE oscillator clock selected as PREDIV1 clock entry */RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull; #else/* HSE selected as PLL clock entry */if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET){/* HSE oscillator clock divided by 2 */RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;}else{RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;}#endif}
#elsepllmull = pllmull >> 18;      if (pllmull != 0x0D){pllmull += 2;}else{ /* PLL multiplication factor = PLL input clock * 6.5 */pllmull = 13 / 2; }            if (pllsource == 0x00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;}else{/* PREDIV1 selected as PLL clock entry */        /* Get PREDIV1 clock source and division factor */prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC;prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;        if (prediv1source == 0){ /* HSE oscillator clock selected as PREDIV1 clock entry */RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull;          }else{/* PLL2 clock selected as PREDIV1 clock entry */          /* Get PREDIV2 division factor and PLL2 multiplication factor */prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1;pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2; RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         }}
#endif /* STM32F10X_CL */ break;default:RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;break;}/* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*//* Get HCLK prescaler */tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;tmp = tmp >> 4;presc = APBAHBPrescTable[tmp];/* HCLK clock frequency */RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;/* Get PCLK1 prescaler */tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;tmp = tmp >> 8;presc = APBAHBPrescTable[tmp];/* PCLK1 clock frequency */RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;/* Get PCLK2 prescaler */tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;tmp = tmp >> 11;presc = APBAHBPrescTable[tmp];/* PCLK2 clock frequency */RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;/* Get ADCCLK prescaler */tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;tmp = tmp >> 14;presc = ADCPrescTable[tmp];/* ADCCLK clock frequency */RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
}
2.2.4 FLASH

因为GD的Flash是自己的专利技术,而ST的Flash则是由第三方提供的,所以,当进行Flash取值操作时,GD32F10X芯片可以达到零等待周期的响应时间,而ST芯片则需要等待两个周期。另一方面,GD芯片的Flash擦除和编程时间可能会比ST芯片长一些。

所以针对这个不同需要增加两个空循环__NOP();指令进行等待。

代码如下(示例):

/*** @brief  Erases the FLASH option bytes.* @note   This functions erases all option bytes except the Read protection (RDP). * @note   This function can be used for all STM32F10x devices.* @param  None* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,*         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.*/
FLASH_Status FLASH_EraseOptionBytes(void)
{uint16_t rdptmp = RDP_Key;FLASH_Status status = FLASH_COMPLETE;/* Get the actual read protection Option Byte value */ if(FLASH_GetReadOutProtectionStatus() != RESET){rdptmp = 0x00;  }/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(EraseTimeout);if(status == FLASH_COMPLETE){/* Authorize the small information block programming */FLASH->OPTKEYR = FLASH_KEY1;FLASH->OPTKEYR = FLASH_KEY2;    __NOP();__NOP();    /* if the previous operation is completed, proceed to erase the option bytes */FLASH->CR |= CR_OPTER_Set;FLASH->CR |= CR_STRT_Set;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(EraseTimeout);    if(status == FLASH_COMPLETE){/* if the erase operation is completed, disable the OPTER Bit */FLASH->CR &= CR_OPTER_Reset;       /* Enable the Option Bytes Programming operation */FLASH->CR |= CR_OPTPG_Set;/* Restore the last read protection Option Byte value */OB->RDP = (uint16_t)rdptmp; /* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(ProgramTimeout);if(status != FLASH_TIMEOUT){/* if the program operation is completed, disable the OPTPG Bit */FLASH->CR &= CR_OPTPG_Reset;}}else{if (status != FLASH_TIMEOUT){/* Disable the OPTPG Bit */FLASH->CR &= CR_OPTPG_Reset;}}  }/* Return the erase status */return status;
}

除了FLASH_EraseOptionBytes函数外,还有下面三个函数也需要增加 __NOP();

FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);

GD芯片的Flash擦除和编程时间可能会比ST芯片长一些,所以把擦除和编程时间变长些。

/* Delay definition */   
#define EraseTimeout          ((uint32_t)0x000fffff)//0x000B0000   
#define ProgramTimeout        ((uint32_t)0x0000ffff)//0x00002000

四、总结

今天是STM32到GD32的工程移植经验分享,附件是移植好的工程。感谢你的观看,谢谢!

在这里插入图片描述

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

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

相关文章

KHBC靶场-->打不穿?笑死

最近这不是在上文件上传的课吗&#xff1f;刚好老师也布置了一堆靶场&#xff0c;刚好来挑一个显眼包 没错他就是KHBC靶场&#xff01;&#xff01;&#xff08;看他不顺眼很久了…

顶级旗舰ET9出道,蔚来还是那个「最不计成本」的中国车品牌

作者 |张祥威 编辑 |德新 2008年&#xff0c;李斌和新浪的曹国伟几人一起喝酒&#xff0c;发了第一条微博&#xff0c;「天冷带围巾&#xff0c;心冷发微博」&#xff0c;一晚上涨了2000多个粉丝&#xff0c;他偶尔还会针砭时事&#xff0c;很快积累了最早一波粉丝。 创立蔚来…

14章总结

一.lambda表达式 1.lambda表达式简介 lambda表达式不能独立执行&#xff0c;因此必须实现函数式接口&#xff0c;并且会返回一个函数式接口的对象。 语法&#xff1a; ()->结果表达式 参数->结果表达式 (参数1&#xff0c;参数2&#xff0c;...&#xff0c;参数n)->…

【leetcode100-019】【矩阵】螺旋矩阵

【题干】 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 【思路】 不难注意到&#xff0c;每进行一次转向&#xff0c;都有一行/列被输出&#xff08;并失效&#xff09;&#xff1b;既然已经失效&#xff0c;那我…

《面试专题-----经典高频面试题收集三》解锁 Java 面试的关键:深度解析并发编程基础篇高频经典面试题(第三篇)

目录 并发编程面试题1.什么是进程、线程、协程&#xff0c;他们之间的关系是怎样的2.协程对于多线程有什么优缺点吗 并发编程面试题 1.什么是进程、线程、协程&#xff0c;他们之间的关系是怎样的 进程: 本质上是⼀个独⽴执⾏的程序&#xff0c;进程是操作系统进⾏资源分配和…

鸿蒙应用开发 自定义下拉刷新动画

1 概述 属性动画&#xff0c;是最为基础的动画&#xff0c;其功能强大、使用场景多&#xff0c;应用范围较广。常用于如下场景中&#xff1a; 一、页面布局发生变化。例如添加、删除部分组件元素。二、页面元素的可见性和位置发生变化。例如显示或者隐藏部分元素&#xff0c;…

【python】python课设 天气预测数据分析及可视化(完整源码)

目录 1. 前言2. 项目结构3. 详细介绍3.1 main.py3.2 GetModel.py3.3 GetData.py3.4 ProcessData.py3.5天气网.html 4. 成果展示 1. 前言 本文介绍了天气预测数据分析及可视化的实现过程使用joblib导入模型和自定义模块GetModel获取模型&#xff0c;输出模型的MAE。使用pyechart…

自媒体实战篇:自媒体运营核心

欢迎各位关注下我的微信公众号:全干程序员demo 回复 “java面试” 获取[java精品面试题] 回复 “idea” 获取[idea2023最新版破解至2099年] 回复"自媒体" 获取个人自媒体笔记:玩转字节跳动平台(可以联系我催更,有时可能因为工作或者发布文章没空更新,因为笔记都是我自…

物理模拟重力 斜抛运动计算 抛物线计算

物理模拟重力 斜抛运动计算 抛物线计算 一、介绍二、原理三、实现如下PhysicsUtil.cs 工具类Missile.cs 四、资源分享 一、介绍 模拟Unity原始重力系统进行重写&#xff0c;可是实现发射到指定目标位置并能继续当前力进行自身的弹力与摩擦继续运动 二、原理 将Unity原始不受控…

【OAuth2】授权框架的四种授权方式详解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《OAuth 2》。&#x1f3af;&#x1f3af; &#x1…

【ZYNQ】ZYNQ7000 XADC 及其驱动示例

XADC 简介 ZYNQ SoC 的 XADC 模块包括两个 12 位的模数转换器&#xff0c;转换速率可以达到 1MSPS&#xff08;每秒一百万次采样&#xff09;。它带有片上温度和电压传感器&#xff0c;可以测量芯片工作时的温度和供电电压。 在 7 系列的 FPGA 中&#xff0c;XADC 提供了 JTA…

蓝桥小课堂-平方和【算法赛】

问题描述 蓝桥小课堂开课啦&#xff01; 平方和公式是一种用于计算连续整数的平方和的数学公式。它可以帮助我们快速求解从 1 到 n 的整数的平方和&#xff0c;其中 n 是一个正整数。 平方和公式的表达式如下&#xff1a; 这个公式可以简化计算过程&#xff0c;避免逐个计算…