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

网站如何做网络营销与直播电商怎么样

网站如何做,网络营销与直播电商怎么样,短视频营销概念,做拍卖的网站有哪些目录 前言 SPI硬件电路 SPI部分特征 SPI框图 SPI数据收发过程 W25Q64 技术实现 接线图 代码实现 技术要点 引脚操作 SPI初始化 SPI起始信号 SPI终止信号 SPI字节交换 宏替换W25Q64操作指令 W25Q64写使能 忙等待 读取设备ID号和制造商ID 页写入 数…

目录

前言

SPI硬件电路

SPI部分特征 

SPI框图 

SPI数据收发过程 

W25Q64 

技术实现 

接线图 

代码实现 

技术要点 

引脚操作

SPI初始化

SPI起始信号

SPI终止信号

SPI字节交换

宏替换W25Q64操作指令 

W25Q64写使能 

忙等待

读取设备ID号和制造商ID

页写入

数据读取

实验结果

问题记录 


前言

SPI(Serial Peripheral Interface,串行外设接口)是一种同步串行通信接口规范,主要用于短距离通信,广泛应用于嵌入式系统中。它使一个主设备能够与一个或多个从设备进行通信。SPI使用四条主要信号线:MOSI(主机输出/从机输入)、MISO(主机输入/从机输出)、SCK(串行时钟)和SS/CS(从选/片选)来实现数据的双向传输。这种接口方式支持全双工通信,具有传输速率高、延迟低的优点,但相比其他一些接口协议,使用的信号线较多。SPI常用于连接传感器、存储器、ADC(模数转换器)等外围设备。

SPI硬件电路

  • 所有SPI设备的SCK,MISO,MOSI分别连在一起。
  • 主机另外引出多条CS控制线分别连接到各从机的CS引脚。
  • 输出引脚配置为推挽输出,输入引脚配置为浮空输入或上拉输入。

SPI部分特征 

  • 3线(SCK,MISO,MOSI)全双工同步传输
  • 带或不带第三根双向数据线的双线单工同步传输(只使用一根MISO或MOSI进行双向半双工数据传输)
  • 8或16位传输帧格式选择
  • 8个主模式波特率预分频系数(最大为fPCLK/2)
  • 可编程的时钟极性和相位
  • 可编程的数据顺序,MSB在前或LSB在前

SPI框图 

SPI数据收发过程 

硬件SPI通常只使用非连续数据传输方式,时钟速率不需要太快。

 (模式3)SCK被拉低后发送起始信号,要发送的数据被写入SPI_DR寄存器,TXE被清零,表示发送缓冲数据寄存器非空,然后数据从缓冲数据寄存器移入移位寄存器,TXE标志被置位,表示发送数据缓冲器空,因为使用非连续传输方式,暂时不用进行数据写入。然后数据从移位寄存器移出,一个时钟信号移出1位,同时从MISO移入数据接收缓冲寄存器一位,连续8个时钟信号后,一个字节的数据移出,一个字节的数据移入,完成一个字节数据的交换。读取SPI_SR寄存器的RXNE位判断接收数据寄存器内是否接收到数据。读出数据后方可进行下一个字节的写入与接收。

W25Q64 

W25Q64是华邦公司(Winbond)推出的一款基于SPI通信的大容量闪存产品,其存储容量为64Mb(即8MB)。该芯片支持2.7~3.6V的工作电压范围,并且具备至少10万次的擦写周期和长达20年的数据保存时间。W25Q64以其灵活性和出色的性能著称,非常适合用于存储声音、文本和数据等应用。它被组织为32768个可编程页面,每个页面包含256字节的数据。此外,W25Q64还支持多种擦除命令,包括4KB扇区擦除、32KB块擦除、64KB块擦除以及全片擦除,并且兼容标准SPI模式0和模式3,最高支持133MHz的时钟频率。通过SPI接口,W25Q64可以轻松地与各种微控制器进行集成,实现高效的数据读写操作。

W25Q64由8MB的存储容量,存储区域被划分成了128个块,每个块又被划分成了16个扇区,每个扇区又被划分成了 16个页。

W25Q64写入操作时

  •  在写入操作之前,必须先进行写使能。
  • 每个数据为只能有1改写成0,不能由0改写成1。
  • 写入数据之前必须先擦除,擦除后,所有的数据位都变为1。
  • 擦除必须以最小单元擦除(这里最小擦除单元时4kb扇区)。
  • 连续写入多个字节时最多写入一页的数据(256Byte),超过页尾的数据会回到页首覆盖写入。
  • 写入操作完成后,芯片进入忙状态,不响应新的写操作。

W25Q64读操作时:

  • 直接调取读操作时序,无需写使能,无需其他操作,没有页限制,读取操作完成后芯片不会进入忙状态,但是芯片忙状态时不能进行读操作。

技术实现 

原理图

 

接线图 

代码实现 

main.c

/**********************************************************
1.实验名称:硬件SPI读写W25Q64
2.实验环境:STM32F103C8T6最小系统板
3.实验内容:使用SPI外设实现读写W25Q64	
4.作者;abai
5.实验时间:2025-5-7
**********************************************************/
#include "stm32f10x.h"                  // Device header
#include "Delay.h"						//延时函数
#include "OLED.h"
#include "W25Q64.h"uint8_t MF;
uint16_t ID;
uint8_t SendArry[] = {0x05,0x06,0x07,0x08};
uint8_t ReceiveArry[4];int main(void)
{/*OLED初始化*/OLED_Init();W25Q64_Init();OLED_ShowString(1,1,"MF:");OLED_ShowString(2,1,"ID:");OLED_ShowString(3,1,"W:");OLED_ShowString(4,1,"R:");W25Q64_SectorErase(0x000000);												//写入数据之前必须页擦除W25Q64_PageProgram(0x000000,SendArry,4);W25Q64_ReadData(0x000000,ReceiveArry,4);W25Q64_ReadID(&MF,&ID);OLED_ShowHexNum(3,3,SendArry[0],2);OLED_ShowHexNum(3,5,SendArry[1],2);OLED_ShowHexNum(3,7,SendArry[2],2);OLED_ShowHexNum(3,9,SendArry[3],2);OLED_ShowHexNum(4,3,ReceiveArry[0],2);OLED_ShowHexNum(4,5,ReceiveArry[1],2);OLED_ShowHexNum(4,7,ReceiveArry[2],2);OLED_ShowHexNum(4,9,ReceiveArry[3],2);OLED_ShowHexNum(1,4,MF,2);OLED_ShowHexNum(2,4,ID,4);while(1){}
}

MySPI.h 

#ifndef MYSPI_H
#define MYSPI_H#include "stm32f10x.h"                  // Device headervoid MySPI_Init(void);
void MySPI_CS_W(uint8_t BitValue);
void MySPI_SCK_W(uint8_t BitValue);
void MySPI_MOSI_W(uint8_t BitValue);
uint8_t MySPI_MISO_R(void);
void MySPI_Start(void);
void MySPI_Stop(void);
uint8_t MySPI_SwapByte(uint8_t ByteValue);#endif

 MySPI.c

#include "MySPI.h"/***@brief  SPI初始化*@param  None*@retval None**/
void MySPI_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);//GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_4;GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_Out_PP;								//推挽输出GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_AF_PP;								//复用推挽输出GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_6;GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_IPU;								//上拉输入GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//SPISPI_InitTypeDef SPI_InitStruct;SPI_InitStruct.SPI_BaudRatePrescaler 	= SPI_BaudRatePrescaler_128;			//SPI时钟采用32分频SPI_InitStruct.SPI_CPHA 				= SPI_CPHA_1Edge;						//选择第几个上升沿捕获数据SPI_InitStruct.SPI_CPOL 				= SPI_CPOL_Low;							//时钟默认为低电平SPI_InitStruct.SPI_CRCPolynomial 		= 7;									//CRC校验,这里不使用给一个默认值7SPI_InitStruct.SPI_DataSize 			= SPI_DataSize_8b;						//数据字节长度为8SPI_InitStruct.SPI_Direction 			= SPI_Direction_2Lines_FullDuplex;		//数据传输采用双向全双工SPI_InitStruct.SPI_FirstBit 			= SPI_FirstBit_MSB;						//数据传输采用高位在前SPI_InitStruct.SPI_Mode 				= SPI_Mode_Master;						//SPI主模式SPI_InitStruct.SPI_NSS 					= SPI_NSS_Soft;							//使用GPIO模拟CS,这里设置为软件控制即可SPI_Init(SPI1,&SPI_InitStruct);//使能SPISPI_Cmd(SPI1,ENABLE);//默认CS为高电平MySPI_CS_W(1);
}/***@brief  SPI CS控制*@param  BitValue 要写入CS的位数据*@retval None**/
void MySPI_CS_W(uint8_t BitValue)
{GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue);
}/***@brief  SPI起始信号*@param  None*@retval None**/
void MySPI_Start(void)
{MySPI_CS_W(0);																//将片选信号拉低发送起始信号
}/***@brief  SPI终止信号*@param  None*@retval None**/
void MySPI_Stop(void)
{MySPI_CS_W(1);																//将片选信号拉高发送终止信号
}/***@brief  SPI交换字节*@param  None*@retval 交换的字节**/
uint8_t MySPI_SwapByte(uint8_t ByteValue)
{while(!SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE));SPI_I2S_SendData(SPI1,ByteValue);while(!SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE));return SPI_I2S_ReceiveData(SPI1);
}

W25Q64_Ins.h 

#ifndef W25Q64_INS_H
#define W25Q64_INS_H#define W25Q64_WRITEENABLE 				0x06
#define W25Q64_READSTATUSREGISTER1 		0x05
#define W25Q64_PAGEPROGRAM 				0x02
#define W25Q64_SECTORERASE4KB 			0x20
#define W25Q64_JEDECID 					0X9F
#define W25Q64_READDATA 				0x03
#define W25Q64_DUMMY_BYTE 				0xFF#endif

W25Q64.h 

#ifndef W25Q64_H
#define W25Q64_H#include "stm32f10x.h"                  // Device header
#include "MySPI.h"void W25Q64_Init(void);
void W25Q64_ReadID(uint8_t* MF, uint16_t*ID);
void W25Q64_WriteEnable(void);
void W25Q64_WaitBusy(void);
void W25Q64_PageProgram(uint32_t Address, uint8_t* DataArry, uint16_t Count);
void W25Q64_SectorErase(uint32_t Address);
void W25Q64_ReadData(uint32_t Address,uint8_t* DataArry, uint32_t Count);#endif

W25Q64.c 

#include "W25Q64.h"
#include "W25Q64_Ins.h"/***@brief  W25Q64初始化*@param  None*@retval None**/
void W25Q64_Init(void)
{MySPI_Init();
}/***@brief  W25Q64ID读取*@param  None*@retval None**/
void W25Q64_ReadID(uint8_t* MF, uint16_t*ID)
{MySPI_Start();//发送读取ID指令MySPI_SwapByte(W25Q64_JEDECID);//发送空指令交换数据*MF = MySPI_SwapByte(W25Q64_DUMMY_BYTE);													//随便发送一个数据用于与从机交换数据,一般使用0xFF或0x00*ID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);*ID <<= 8;*ID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);MySPI_Stop();
}/***@brief  W25Q64ID写使能*@param  None*@retval None**/
void W25Q64_WriteEnable(void)
{MySPI_Start();//发送写使能指令MySPI_SwapByte(W25Q64_WRITEENABLE);MySPI_Stop();
}/***@brief  W25Q64ID忙等待*@param  None*@retval None**/
void W25Q64_WaitBusy(void)
{MySPI_Start();//发送读状态寄存器指令MySPI_SwapByte(W25Q64_READSTATUSREGISTER1);//等待BUSY位清零,则从设备退出忙状态while((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0X01) == 0X01);MySPI_Stop();
}/***@brief  W25Q64ID页写入*@param  None*@retval None**/
void W25Q64_PageProgram(uint32_t Address, uint8_t* DataArry, uint16_t Count)
{uint16_t i;W25Q64_WriteEnable();														//写使能MySPI_Start();MySPI_SwapByte(W25Q64_PAGEPROGRAM);//发送24位地址MySPI_SwapByte(Address>>16);MySPI_SwapByte(Address>>8);MySPI_SwapByte(Address);//发送指定数量的数据for(i=0;i<Count;i++){MySPI_SwapByte(DataArry[i]);}MySPI_Stop();W25Q64_WaitBusy();															//事后等待忙状态
}/***@brief  W25Q64ID指定扇区擦除*@param  None*@retval None**/
void W25Q64_SectorErase(uint32_t Address)
{			W25Q64_WriteEnable();MySPI_Start();MySPI_SwapByte(W25Q64_SECTORERASE4KB);//发送24位地址MySPI_SwapByte(Address>>16);MySPI_SwapByte(Address>>8);MySPI_SwapByte(Address);MySPI_Stop();W25Q64_WaitBusy();
}/***@brief  W25Q64ID读取数据*@param  None*@retval None*@note   数据接收的数量也要指定,不然无法停止数据读取操作**/
void W25Q64_ReadData(uint32_t Address,uint8_t* DataArry, uint32_t Count)
{uint32_t i;MySPI_Start();MySPI_SwapByte(W25Q64_READDATA);//发送24位地址MySPI_SwapByte(Address>>16);MySPI_SwapByte(Address>>8);MySPI_SwapByte(Address);for(i=0;i<Count;i++){DataArry[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);}MySPI_Stop();
}

 OLED部分代码参照文章《STM32基础教程——OLED显示》

技术要点 

引脚操作

/***@brief  SPI CS控制*@param  BitValue 要写入CS的位数据*@retval None**/
void MySPI_CS_W(uint8_t BitValue)
{GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue);
}

对单个引脚的操作进行封装,用于模拟SPI引脚电平翻转用于控制CS信号。 

SPI初始化

/***@brief  SPI初始化*@param  None*@retval None**/
void MySPI_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);//GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_4;GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_Out_PP;								//推挽输出GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_AF_PP;								//复用推挽输出GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_6;GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_IPU;								//上拉输入GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//SPISPI_InitTypeDef SPI_InitStruct;SPI_InitStruct.SPI_BaudRatePrescaler 	= SPI_BaudRatePrescaler_128;			//SPI时钟采用128分频SPI_InitStruct.SPI_CPHA 				= SPI_CPHA_1Edge;						//选择第几个上升沿捕获数据SPI_InitStruct.SPI_CPOL 				= SPI_CPOL_Low;							//时钟默认为低电平SPI_InitStruct.SPI_CRCPolynomial 		= 7;									//CRC校验,这里不使用给一个默认值7SPI_InitStruct.SPI_DataSize 			= SPI_DataSize_8b;						//数据字节长度为8SPI_InitStruct.SPI_Direction 			= SPI_Direction_2Lines_FullDuplex;		//数据传输采用双向全双工SPI_InitStruct.SPI_FirstBit 			= SPI_FirstBit_MSB;						//数据传输采用高位在前SPI_InitStruct.SPI_Mode 				= SPI_Mode_Master;						//SPI主模式SPI_InitStruct.SPI_NSS 					= SPI_NSS_Soft;							//使用GPIO模拟CS,这里设置为软件控制即可SPI_Init(SPI1,&SPI_InitStruct);//使能SPISPI_Cmd(SPI1,ENABLE);//默认CS为高电平MySPI_CS_W(1);
}

SPI初始化,先初始化GPIO,PA4作为软件发送CS信号的引脚,应初始化为推挽输出。PA5和PA7作为外设SPI的SCK和MOSI引脚,应初始化为复用推挽输出,PA6引脚作为MISO引脚,用于接收数据输入,初始化为上拉输入。

SPI1初始化,时钟分频选择128分频,SPI1为APB2外设,系统时钟为72MHz,经分频后时钟频率为562.5kHz。设置第一个边沿数据移入,且默认时钟为低电平。将SPI设置为主模式下双向全双工模式,数据长度设置为8位,数据传输高位在前。其余杂项CRC校验设为默认值,NSS在本实验不使用,设置为软件控制。将片选信号初始化为高电平。

SPI起始信号

SPI的起始时序是CS(SS)从高电平切换为低电平 。

/***@brief  SPI起始信号*@param  None*@retval None**/
void MySPI_Start(void)
{MySPI_CS_W(0);																//将片选信号拉低发送起始信号
}

SPI终止信号
 

 SPI的终止时序是CS(SS)从低电平切换为高电平 。

/***@brief  SPI终止信号*@param  None*@retval None**/
void MySPI_Stop(void)
{MySPI_CS_W(1);																//将片选信号拉高发送终止信号
}

SPI字节交换

SPI为同步全双工通信,每一次通信都会进行数据交换。

/***@brief  SPI交换字节*@param  None*@retval 交换的字节**/
uint8_t MySPI_SwapByte(uint8_t ByteValue)
{while(!SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE));SPI_I2S_SendData(SPI1,ByteValue);while(!SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE));return SPI_I2S_ReceiveData(SPI1);
}

硬件SPI交换字节数据,先等待TXE标志位置位,表示发送数据缓冲寄存器为空,方可向发送数据缓冲寄存器写入数据,硬件SPI会在数据写入发送数据寄存器后自动完成数据发送,无需手动操作。然后只需等待数据接收寄存器的标志位RXNE被置位即可,当RXNE被置位后,说明数据接收寄存器已接收到从机发来的数据,此时将数据读出即可。

宏替换W25Q64操作指令 

#ifndef W25Q64_INS_H
#define W25Q64_INS_H#define W25Q64_WRITEENABLE 				0x06
#define W25Q64_READSTATUSREGISTER1 		0x05
#define W25Q64_PAGEPROGRAM 				0x02
#define W25Q64_SECTORERASE4KB 			0x20
#define W25Q64_JEDECID 					0X9F
#define W25Q64_READDATA 				0x03
#define W25Q64_DUMMY_BYTE 				0xFF#endif

将对W25Q64操作的命令使用宏代替, 提高代码的便捷性和可读性。

W25Q64写使能 

/***@brief  W25Q64ID写使能*@param  None*@retval None**/
void W25Q64_WriteEnable(void)
{MySPI_Start();//发送写使能指令MySPI_SwapByte(W25Q64_WRITEENABLE);MySPI_Stop();
}

将写使能操作封装,方便使用。主机与从机交换数据,发送写使能命令,对从机进行写使能操作。

忙等待

/***@brief  W25Q64ID忙等待*@param  None*@retval None**/
void W25Q64_WaitBusy(void)
{MySPI_Start();//发送读状态寄存器指令MySPI_SwapByte(W25Q64_READSTATUSREGISTER1);//等待BUSY位清零,则从设备退出忙状态while((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0X01) == 0X01);MySPI_Stop();
}

 发送读取状态寄存器1的命令,判断BUSY位的状态,使用while循环等待芯片退出忙状态将BUSY位清零。

读取设备ID号和制造商ID

/***@brief  W25Q64ID读取*@param  None*@retval None**/
void W25Q64_ReadID(uint8_t* MF, uint16_t*ID)
{MySPI_Start();//发送读取ID指令MySPI_SwapByte(W25Q64_JEDECID);//发送空指令交换数据*MF = MySPI_SwapByte(W25Q64_DUMMY_BYTE);													//随便发送一个数据用于与从机交换数据,一般使用0xFF或0x00*ID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);*ID <<= 8;*ID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);MySPI_Stop();
}

 主机发送读取JEDEC ID的命令,从机向主机发送数据,数据格式为第一个字节为制造商ID,第二个和第三个字节为设备ID。这里使用指针进行数据操作。

页写入

/***@brief  W25Q64ID页写入*@param  None*@retval None**/
void W25Q64_PageProgram(uint32_t Address, uint8_t* DataArry, uint16_t Count)
{uint16_t i;W25Q64_WriteEnable();														//写使能MySPI_Start();MySPI_SwapByte(W25Q64_PAGEPROGRAM);//发送24位地址MySPI_SwapByte(Address>>16);MySPI_SwapByte(Address>>8);MySPI_SwapByte(Address);//发送指定数量的数据for(i=0;i<Count;i++){MySPI_SwapByte(DataArry[i]);}MySPI_Stop();W25Q64_WaitBusy();															//事后等待忙状态
}

页写入操作,先进行写使能,然后发送起始信号,发送页写入命令。然后发送24位地址,高16位为页地址,低八位为字节地址。使用for循环写入指定数量的数据,数据的数量不应超过256字节。最后发送停止信号,然后进行芯片忙等待操作(忙等待如果加在函数开始,那读取操作也要加忙等待函数调用,这样会使操作更复杂。)。所有写操作函数与本函数类似,不再赘述。

数据读取

/***@brief  W25Q64ID读取数据*@param  None*@retval None*@note   数据接收的数量也要指定,不然无法停止数据读取操作**/
void W25Q64_ReadData(uint32_t Address,uint8_t* DataArry, uint32_t Count)
{uint32_t i;MySPI_Start();MySPI_SwapByte(W25Q64_READDATA);//发送24位地址MySPI_SwapByte(Address>>16);MySPI_SwapByte(Address>>8);MySPI_SwapByte(Address);for(i=0;i<Count;i++){DataArry[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);}MySPI_Stop();
}

数据读取操作无需写使能,无需进行其他操作。发送读数据命令,然后发送24位地址,同样高16位地址为页地址,低八位为字节地址。读取操作不受页限制。

实验结果

问题记录 

暂无

http://www.dtcms.com/wzjs/264731.html

相关文章:

  • wordpress边下边看免费seo优化
  • 免费app下载win10优化大师官网
  • 室内设计网页版seo网站推广企业
  • 域名持有者个人可以做公司网站百度产品大全入口
  • wampserver和wordpress网站推广和优化的原因网络营销
  • html5 网站测试数据分析师35岁以后怎么办
  • 公司网站重新备案第三方关键词优化排名
  • 新疆找人做网站多少钱手机搜索引擎排行榜
  • wordpress面包学seo内容优化方法
  • ae做模板下载网站网络服务公司经营范围
  • 甘肃省建设厅官方网站质监局硬件优化大师
  • java与php开发网站下载百度到桌面
  • 微信商城首页广州关键词优化外包
  • 低价网站开发网站客服系统
  • 安徽合肥网站制作公司成都关键词优化服务
  • 举报非法网站要求做笔录正规网络推广服务
  • 下拉框代码自做生成网站网络热词2021
  • 怎么查网站外链数网络营销所学课程
  • 合肥网站设计建交换友情链接的渠道有哪些
  • 有没有如何做网站的书seo免费诊断
  • 巩义旅游网站建设公司产品营销策划方案怎么做
  • 网站设计做微信发现界面北京专门做seo
  • 网站建设 ur建站免费做推广的网站
  • 怎么查在哪个网站做的备案广告公司广告牌制作
  • 一见钟情 网站北京网站优化站优化
  • 腾讯云网站建设教程视频怎么建立网站
  • 股权众筹网站开发长春网站提升排名
  • 官方网站建设 搜搜磐石网络百度一下首页百度一下
  • 网站后台banner更换找个免费的网站
  • 动态ip上做网站信息互联网推广