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

东莞网站建设哪家公司好拼多多关键词排名查询软件

东莞网站建设哪家公司好,拼多多关键词排名查询软件,红色主题展馆设计,商城网站系统建设方案文章目录 一、前言二、差异性三、软件移植部分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 四、总结 一…

文章目录

  • 一、前言
  • 二、差异性
  • 三、软件移植部分
    • 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.ds6.com.cn/news/30392.html

相关文章:

  • 顺德做外贸网站宁德市有几个区几个县
  • 网络推广免费网站我的百度账号登录
  • 微网站怎么做的好名字360优化大师下载安装
  • 网站板块怎么做b站推广链接
  • 新公司网站设计百度关键词快速优化
  • 建设银行安全网站深圳推广网络
  • 免费做app的网站百度营销后台
  • 免费php mysql网站软件推广平台有哪些?哪个比较好
  • 有专门做食品的网站吗推荐seo关键词优化
  • 视频解析接口网站怎么做百度学术官网首页
  • 如何做网站逻辑结构图企业管理培训
  • 泰州网站建设方案海外免费网站推广
  • 提供网站设计方案公司哪个网站做推广效果好
  • 打车网站开发网站怎么做到秒收录
  • 手机网站建设的背景2022真实新闻作文400字
  • 网站建设与制作教程北华大学百度seo怎么收费
  • 浏览器谷歌手机版下载谷歌seo课程
  • 网站建设服务器软件站长之家alexa排名
  • 网站虚拟旅游怎么做的360指数查询工具
  • 织梦网站图片怎么做滚动图片有什么推广软件
  • 用织梦做的企业网站商丘网站优化公司
  • 免费网站建设网站有那些seo公司厦门
  • 做公司网站都需要付什么费用软文自动发布软件
  • 大连建设网网址湖南专业关键词优化
  • 哪个网站做娱乐品牌营销是什么
  • 务川做网站wguserapp拉新任务平台
  • 扬州网站建设 天维网店运营的工作内容
  • 深圳 做网站 互联seo小白入门
  • 安徽网站排名优化公司凡科网怎么建网站
  • 企业招聘网站哪个最好网站入口百度